Home | History | Annotate | Download | only in src
      1 // Copyright 2012 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 "src/allocation.h"
      9 #include "src/assert-scope.h"
     10 #include "src/bailout-reason.h"
     11 #include "src/base/bits.h"
     12 #include "src/builtins.h"
     13 #include "src/checks.h"
     14 #include "src/elements-kind.h"
     15 #include "src/field-index.h"
     16 #include "src/flags.h"
     17 #include "src/list.h"
     18 #include "src/property-details.h"
     19 #include "src/smart-pointers.h"
     20 #include "src/unicode-inl.h"
     21 #include "src/zone.h"
     22 
     23 #if V8_TARGET_ARCH_ARM
     24 #include "src/arm/constants-arm.h"  // NOLINT
     25 #elif V8_TARGET_ARCH_ARM64
     26 #include "src/arm64/constants-arm64.h"  // NOLINT
     27 #elif V8_TARGET_ARCH_MIPS
     28 #include "src/mips/constants-mips.h"  // NOLINT
     29 #elif V8_TARGET_ARCH_MIPS64
     30 #include "src/mips64/constants-mips64.h"  // NOLINT
     31 #endif
     32 
     33 
     34 //
     35 // Most object types in the V8 JavaScript are described in this file.
     36 //
     37 // Inheritance hierarchy:
     38 // - Object
     39 //   - Smi          (immediate small integer)
     40 //   - HeapObject   (superclass for everything allocated in the heap)
     41 //     - JSReceiver  (suitable for property access)
     42 //       - JSObject
     43 //         - JSArray
     44 //         - JSArrayBuffer
     45 //         - JSArrayBufferView
     46 //           - JSTypedArray
     47 //           - JSDataView
     48 //         - JSCollection
     49 //           - JSSet
     50 //           - JSMap
     51 //         - JSSetIterator
     52 //         - JSMapIterator
     53 //         - JSWeakCollection
     54 //           - JSWeakMap
     55 //           - JSWeakSet
     56 //         - JSRegExp
     57 //         - JSFunction
     58 //         - JSGeneratorObject
     59 //         - JSModule
     60 //         - GlobalObject
     61 //           - JSGlobalObject
     62 //           - JSBuiltinsObject
     63 //         - JSGlobalProxy
     64 //         - JSValue
     65 //           - JSDate
     66 //         - JSMessageObject
     67 //       - JSProxy
     68 //         - JSFunctionProxy
     69 //     - FixedArrayBase
     70 //       - ByteArray
     71 //       - FixedArray
     72 //         - DescriptorArray
     73 //         - HashTable
     74 //           - Dictionary
     75 //           - StringTable
     76 //           - CompilationCacheTable
     77 //           - CodeCacheHashTable
     78 //           - MapCache
     79 //         - OrderedHashTable
     80 //           - OrderedHashSet
     81 //           - OrderedHashMap
     82 //         - Context
     83 //         - TypeFeedbackVector
     84 //         - JSFunctionResultCache
     85 //         - ScopeInfo
     86 //         - TransitionArray
     87 //       - FixedDoubleArray
     88 //       - ExternalArray
     89 //         - ExternalUint8ClampedArray
     90 //         - ExternalInt8Array
     91 //         - ExternalUint8Array
     92 //         - ExternalInt16Array
     93 //         - ExternalUint16Array
     94 //         - ExternalInt32Array
     95 //         - ExternalUint32Array
     96 //         - ExternalFloat32Array
     97 //     - Name
     98 //       - String
     99 //         - SeqString
    100 //           - SeqOneByteString
    101 //           - SeqTwoByteString
    102 //         - SlicedString
    103 //         - ConsString
    104 //         - ExternalString
    105 //           - ExternalOneByteString
    106 //           - ExternalTwoByteString
    107 //         - InternalizedString
    108 //           - SeqInternalizedString
    109 //             - SeqOneByteInternalizedString
    110 //             - SeqTwoByteInternalizedString
    111 //           - ConsInternalizedString
    112 //           - ExternalInternalizedString
    113 //             - ExternalOneByteInternalizedString
    114 //             - ExternalTwoByteInternalizedString
    115 //       - Symbol
    116 //     - HeapNumber
    117 //     - Cell
    118 //       - PropertyCell
    119 //     - Code
    120 //     - Map
    121 //     - Oddball
    122 //     - Foreign
    123 //     - SharedFunctionInfo
    124 //     - Struct
    125 //       - Box
    126 //       - DeclaredAccessorDescriptor
    127 //       - AccessorInfo
    128 //         - DeclaredAccessorInfo
    129 //         - ExecutableAccessorInfo
    130 //       - AccessorPair
    131 //       - AccessCheckInfo
    132 //       - InterceptorInfo
    133 //       - CallHandlerInfo
    134 //       - TemplateInfo
    135 //         - FunctionTemplateInfo
    136 //         - ObjectTemplateInfo
    137 //       - Script
    138 //       - SignatureInfo
    139 //       - TypeSwitchInfo
    140 //       - DebugInfo
    141 //       - BreakPointInfo
    142 //       - CodeCache
    143 //
    144 // Formats of Object*:
    145 //  Smi:        [31 bit signed int] 0
    146 //  HeapObject: [32 bit direct pointer] (4 byte aligned) | 01
    147 
    148 namespace v8 {
    149 namespace internal {
    150 
    151 class OStream;
    152 
    153 enum KeyedAccessStoreMode {
    154   STANDARD_STORE,
    155   STORE_TRANSITION_SMI_TO_OBJECT,
    156   STORE_TRANSITION_SMI_TO_DOUBLE,
    157   STORE_TRANSITION_DOUBLE_TO_OBJECT,
    158   STORE_TRANSITION_HOLEY_SMI_TO_OBJECT,
    159   STORE_TRANSITION_HOLEY_SMI_TO_DOUBLE,
    160   STORE_TRANSITION_HOLEY_DOUBLE_TO_OBJECT,
    161   STORE_AND_GROW_NO_TRANSITION,
    162   STORE_AND_GROW_TRANSITION_SMI_TO_OBJECT,
    163   STORE_AND_GROW_TRANSITION_SMI_TO_DOUBLE,
    164   STORE_AND_GROW_TRANSITION_DOUBLE_TO_OBJECT,
    165   STORE_AND_GROW_TRANSITION_HOLEY_SMI_TO_OBJECT,
    166   STORE_AND_GROW_TRANSITION_HOLEY_SMI_TO_DOUBLE,
    167   STORE_AND_GROW_TRANSITION_HOLEY_DOUBLE_TO_OBJECT,
    168   STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS,
    169   STORE_NO_TRANSITION_HANDLE_COW
    170 };
    171 
    172 
    173 enum ContextualMode {
    174   NOT_CONTEXTUAL,
    175   CONTEXTUAL
    176 };
    177 
    178 
    179 enum MutableMode {
    180   MUTABLE,
    181   IMMUTABLE
    182 };
    183 
    184 
    185 static const int kGrowICDelta = STORE_AND_GROW_NO_TRANSITION -
    186     STANDARD_STORE;
    187 STATIC_ASSERT(STANDARD_STORE == 0);
    188 STATIC_ASSERT(kGrowICDelta ==
    189               STORE_AND_GROW_TRANSITION_SMI_TO_OBJECT -
    190               STORE_TRANSITION_SMI_TO_OBJECT);
    191 STATIC_ASSERT(kGrowICDelta ==
    192               STORE_AND_GROW_TRANSITION_SMI_TO_DOUBLE -
    193               STORE_TRANSITION_SMI_TO_DOUBLE);
    194 STATIC_ASSERT(kGrowICDelta ==
    195               STORE_AND_GROW_TRANSITION_DOUBLE_TO_OBJECT -
    196               STORE_TRANSITION_DOUBLE_TO_OBJECT);
    197 
    198 
    199 static inline KeyedAccessStoreMode GetGrowStoreMode(
    200     KeyedAccessStoreMode store_mode) {
    201   if (store_mode < STORE_AND_GROW_NO_TRANSITION) {
    202     store_mode = static_cast<KeyedAccessStoreMode>(
    203         static_cast<int>(store_mode) + kGrowICDelta);
    204   }
    205   return store_mode;
    206 }
    207 
    208 
    209 static inline bool IsTransitionStoreMode(KeyedAccessStoreMode store_mode) {
    210   return store_mode > STANDARD_STORE &&
    211       store_mode <= STORE_AND_GROW_TRANSITION_HOLEY_DOUBLE_TO_OBJECT &&
    212       store_mode != STORE_AND_GROW_NO_TRANSITION;
    213 }
    214 
    215 
    216 static inline KeyedAccessStoreMode GetNonTransitioningStoreMode(
    217     KeyedAccessStoreMode store_mode) {
    218   if (store_mode >= STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) {
    219     return store_mode;
    220   }
    221   if (store_mode >= STORE_AND_GROW_NO_TRANSITION) {
    222     return STORE_AND_GROW_NO_TRANSITION;
    223   }
    224   return STANDARD_STORE;
    225 }
    226 
    227 
    228 static inline bool IsGrowStoreMode(KeyedAccessStoreMode store_mode) {
    229   return store_mode >= STORE_AND_GROW_NO_TRANSITION &&
    230       store_mode <= STORE_AND_GROW_TRANSITION_HOLEY_DOUBLE_TO_OBJECT;
    231 }
    232 
    233 
    234 // Setter that skips the write barrier if mode is SKIP_WRITE_BARRIER.
    235 enum WriteBarrierMode { SKIP_WRITE_BARRIER, UPDATE_WRITE_BARRIER };
    236 
    237 
    238 // Indicates whether a value can be loaded as a constant.
    239 enum StoreMode {
    240   ALLOW_AS_CONSTANT,
    241   FORCE_FIELD
    242 };
    243 
    244 
    245 // PropertyNormalizationMode is used to specify whether to keep
    246 // inobject properties when normalizing properties of a JSObject.
    247 enum PropertyNormalizationMode {
    248   CLEAR_INOBJECT_PROPERTIES,
    249   KEEP_INOBJECT_PROPERTIES
    250 };
    251 
    252 
    253 // Indicates how aggressively the prototype should be optimized. FAST_PROTOTYPE
    254 // will give the fastest result by tailoring the map to the prototype, but that
    255 // will cause polymorphism with other objects. REGULAR_PROTOTYPE is to be used
    256 // (at least for now) when dynamically modifying the prototype chain of an
    257 // object using __proto__ or Object.setPrototypeOf.
    258 enum PrototypeOptimizationMode { REGULAR_PROTOTYPE, FAST_PROTOTYPE };
    259 
    260 
    261 // Indicates whether transitions can be added to a source map or not.
    262 enum TransitionFlag {
    263   INSERT_TRANSITION,
    264   OMIT_TRANSITION
    265 };
    266 
    267 
    268 enum DebugExtraICState {
    269   DEBUG_BREAK,
    270   DEBUG_PREPARE_STEP_IN
    271 };
    272 
    273 
    274 // Indicates whether the transition is simple: the target map of the transition
    275 // either extends the current map with a new property, or it modifies the
    276 // property that was added last to the current map.
    277 enum SimpleTransitionFlag {
    278   SIMPLE_TRANSITION,
    279   FULL_TRANSITION
    280 };
    281 
    282 
    283 // Indicates whether we are only interested in the descriptors of a particular
    284 // map, or in all descriptors in the descriptor array.
    285 enum DescriptorFlag {
    286   ALL_DESCRIPTORS,
    287   OWN_DESCRIPTORS
    288 };
    289 
    290 // The GC maintains a bit of information, the MarkingParity, which toggles
    291 // from odd to even and back every time marking is completed. Incremental
    292 // marking can visit an object twice during a marking phase, so algorithms that
    293 // that piggy-back on marking can use the parity to ensure that they only
    294 // perform an operation on an object once per marking phase: they record the
    295 // MarkingParity when they visit an object, and only re-visit the object when it
    296 // is marked again and the MarkingParity changes.
    297 enum MarkingParity {
    298   NO_MARKING_PARITY,
    299   ODD_MARKING_PARITY,
    300   EVEN_MARKING_PARITY
    301 };
    302 
    303 // ICs store extra state in a Code object. The default extra state is
    304 // kNoExtraICState.
    305 typedef int ExtraICState;
    306 static const ExtraICState kNoExtraICState = 0;
    307 
    308 // Instance size sentinel for objects of variable size.
    309 const int kVariableSizeSentinel = 0;
    310 
    311 // We may store the unsigned bit field as signed Smi value and do not
    312 // use the sign bit.
    313 const int kStubMajorKeyBits = 7;
    314 const int kStubMinorKeyBits = kSmiValueSize - kStubMajorKeyBits - 1;
    315 
    316 // All Maps have a field instance_type containing a InstanceType.
    317 // It describes the type of the instances.
    318 //
    319 // As an example, a JavaScript object is a heap object and its map
    320 // instance_type is JS_OBJECT_TYPE.
    321 //
    322 // The names of the string instance types are intended to systematically
    323 // mirror their encoding in the instance_type field of the map.  The default
    324 // encoding is considered TWO_BYTE.  It is not mentioned in the name.  ONE_BYTE
    325 // encoding is mentioned explicitly in the name.  Likewise, the default
    326 // representation is considered sequential.  It is not mentioned in the
    327 // name.  The other representations (e.g. CONS, EXTERNAL) are explicitly
    328 // mentioned.  Finally, the string is either a STRING_TYPE (if it is a normal
    329 // string) or a INTERNALIZED_STRING_TYPE (if it is a internalized string).
    330 //
    331 // NOTE: The following things are some that depend on the string types having
    332 // instance_types that are less than those of all other types:
    333 // HeapObject::Size, HeapObject::IterateBody, the typeof operator, and
    334 // Object::IsString.
    335 //
    336 // NOTE: Everything following JS_VALUE_TYPE is considered a
    337 // JSObject for GC purposes. The first four entries here have typeof
    338 // 'object', whereas JS_FUNCTION_TYPE has typeof 'function'.
    339 #define INSTANCE_TYPE_LIST(V)                                   \
    340   V(STRING_TYPE)                                                \
    341   V(ONE_BYTE_STRING_TYPE)                                       \
    342   V(CONS_STRING_TYPE)                                           \
    343   V(CONS_ONE_BYTE_STRING_TYPE)                                  \
    344   V(SLICED_STRING_TYPE)                                         \
    345   V(SLICED_ONE_BYTE_STRING_TYPE)                                \
    346   V(EXTERNAL_STRING_TYPE)                                       \
    347   V(EXTERNAL_ONE_BYTE_STRING_TYPE)                              \
    348   V(EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE)                    \
    349   V(SHORT_EXTERNAL_STRING_TYPE)                                 \
    350   V(SHORT_EXTERNAL_ONE_BYTE_STRING_TYPE)                        \
    351   V(SHORT_EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE)              \
    352                                                                 \
    353   V(INTERNALIZED_STRING_TYPE)                                   \
    354   V(ONE_BYTE_INTERNALIZED_STRING_TYPE)                          \
    355   V(EXTERNAL_INTERNALIZED_STRING_TYPE)                          \
    356   V(EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE)                 \
    357   V(EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE)       \
    358   V(SHORT_EXTERNAL_INTERNALIZED_STRING_TYPE)                    \
    359   V(SHORT_EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE)           \
    360   V(SHORT_EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE) \
    361                                                                 \
    362   V(SYMBOL_TYPE)                                                \
    363                                                                 \
    364   V(MAP_TYPE)                                                   \
    365   V(CODE_TYPE)                                                  \
    366   V(ODDBALL_TYPE)                                               \
    367   V(CELL_TYPE)                                                  \
    368   V(PROPERTY_CELL_TYPE)                                         \
    369                                                                 \
    370   V(HEAP_NUMBER_TYPE)                                           \
    371   V(MUTABLE_HEAP_NUMBER_TYPE)                                   \
    372   V(FOREIGN_TYPE)                                               \
    373   V(BYTE_ARRAY_TYPE)                                            \
    374   V(FREE_SPACE_TYPE)                                            \
    375   /* Note: the order of these external array */                 \
    376   /* types is relied upon in */                                 \
    377   /* Object::IsExternalArray(). */                              \
    378   V(EXTERNAL_INT8_ARRAY_TYPE)                                   \
    379   V(EXTERNAL_UINT8_ARRAY_TYPE)                                  \
    380   V(EXTERNAL_INT16_ARRAY_TYPE)                                  \
    381   V(EXTERNAL_UINT16_ARRAY_TYPE)                                 \
    382   V(EXTERNAL_INT32_ARRAY_TYPE)                                  \
    383   V(EXTERNAL_UINT32_ARRAY_TYPE)                                 \
    384   V(EXTERNAL_FLOAT32_ARRAY_TYPE)                                \
    385   V(EXTERNAL_FLOAT64_ARRAY_TYPE)                                \
    386   V(EXTERNAL_UINT8_CLAMPED_ARRAY_TYPE)                          \
    387                                                                 \
    388   V(FIXED_INT8_ARRAY_TYPE)                                      \
    389   V(FIXED_UINT8_ARRAY_TYPE)                                     \
    390   V(FIXED_INT16_ARRAY_TYPE)                                     \
    391   V(FIXED_UINT16_ARRAY_TYPE)                                    \
    392   V(FIXED_INT32_ARRAY_TYPE)                                     \
    393   V(FIXED_UINT32_ARRAY_TYPE)                                    \
    394   V(FIXED_FLOAT32_ARRAY_TYPE)                                   \
    395   V(FIXED_FLOAT64_ARRAY_TYPE)                                   \
    396   V(FIXED_UINT8_CLAMPED_ARRAY_TYPE)                             \
    397                                                                 \
    398   V(FILLER_TYPE)                                                \
    399                                                                 \
    400   V(DECLARED_ACCESSOR_DESCRIPTOR_TYPE)                          \
    401   V(DECLARED_ACCESSOR_INFO_TYPE)                                \
    402   V(EXECUTABLE_ACCESSOR_INFO_TYPE)                              \
    403   V(ACCESSOR_PAIR_TYPE)                                         \
    404   V(ACCESS_CHECK_INFO_TYPE)                                     \
    405   V(INTERCEPTOR_INFO_TYPE)                                      \
    406   V(CALL_HANDLER_INFO_TYPE)                                     \
    407   V(FUNCTION_TEMPLATE_INFO_TYPE)                                \
    408   V(OBJECT_TEMPLATE_INFO_TYPE)                                  \
    409   V(SIGNATURE_INFO_TYPE)                                        \
    410   V(TYPE_SWITCH_INFO_TYPE)                                      \
    411   V(ALLOCATION_MEMENTO_TYPE)                                    \
    412   V(ALLOCATION_SITE_TYPE)                                       \
    413   V(SCRIPT_TYPE)                                                \
    414   V(CODE_CACHE_TYPE)                                            \
    415   V(POLYMORPHIC_CODE_CACHE_TYPE)                                \
    416   V(TYPE_FEEDBACK_INFO_TYPE)                                    \
    417   V(ALIASED_ARGUMENTS_ENTRY_TYPE)                               \
    418   V(BOX_TYPE)                                                   \
    419                                                                 \
    420   V(FIXED_ARRAY_TYPE)                                           \
    421   V(FIXED_DOUBLE_ARRAY_TYPE)                                    \
    422   V(CONSTANT_POOL_ARRAY_TYPE)                                   \
    423   V(SHARED_FUNCTION_INFO_TYPE)                                  \
    424                                                                 \
    425   V(JS_MESSAGE_OBJECT_TYPE)                                     \
    426                                                                 \
    427   V(JS_VALUE_TYPE)                                              \
    428   V(JS_DATE_TYPE)                                               \
    429   V(JS_OBJECT_TYPE)                                             \
    430   V(JS_CONTEXT_EXTENSION_OBJECT_TYPE)                           \
    431   V(JS_GENERATOR_OBJECT_TYPE)                                   \
    432   V(JS_MODULE_TYPE)                                             \
    433   V(JS_GLOBAL_OBJECT_TYPE)                                      \
    434   V(JS_BUILTINS_OBJECT_TYPE)                                    \
    435   V(JS_GLOBAL_PROXY_TYPE)                                       \
    436   V(JS_ARRAY_TYPE)                                              \
    437   V(JS_ARRAY_BUFFER_TYPE)                                       \
    438   V(JS_TYPED_ARRAY_TYPE)                                        \
    439   V(JS_DATA_VIEW_TYPE)                                          \
    440   V(JS_PROXY_TYPE)                                              \
    441   V(JS_SET_TYPE)                                                \
    442   V(JS_MAP_TYPE)                                                \
    443   V(JS_SET_ITERATOR_TYPE)                                       \
    444   V(JS_MAP_ITERATOR_TYPE)                                       \
    445   V(JS_WEAK_MAP_TYPE)                                           \
    446   V(JS_WEAK_SET_TYPE)                                           \
    447   V(JS_REGEXP_TYPE)                                             \
    448                                                                 \
    449   V(JS_FUNCTION_TYPE)                                           \
    450   V(JS_FUNCTION_PROXY_TYPE)                                     \
    451   V(DEBUG_INFO_TYPE)                                            \
    452   V(BREAK_POINT_INFO_TYPE)
    453 
    454 
    455 // Since string types are not consecutive, this macro is used to
    456 // iterate over them.
    457 #define STRING_TYPE_LIST(V)                                                   \
    458   V(STRING_TYPE, kVariableSizeSentinel, string, String)                       \
    459   V(ONE_BYTE_STRING_TYPE, kVariableSizeSentinel, one_byte_string,             \
    460     OneByteString)                                                            \
    461   V(CONS_STRING_TYPE, ConsString::kSize, cons_string, ConsString)             \
    462   V(CONS_ONE_BYTE_STRING_TYPE, ConsString::kSize, cons_one_byte_string,       \
    463     ConsOneByteString)                                                        \
    464   V(SLICED_STRING_TYPE, SlicedString::kSize, sliced_string, SlicedString)     \
    465   V(SLICED_ONE_BYTE_STRING_TYPE, SlicedString::kSize, sliced_one_byte_string, \
    466     SlicedOneByteString)                                                      \
    467   V(EXTERNAL_STRING_TYPE, ExternalTwoByteString::kSize, external_string,      \
    468     ExternalString)                                                           \
    469   V(EXTERNAL_ONE_BYTE_STRING_TYPE, ExternalOneByteString::kSize,              \
    470     external_one_byte_string, ExternalOneByteString)                          \
    471   V(EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE, ExternalTwoByteString::kSize,    \
    472     external_string_with_one_byte_data, ExternalStringWithOneByteData)        \
    473   V(SHORT_EXTERNAL_STRING_TYPE, ExternalTwoByteString::kShortSize,            \
    474     short_external_string, ShortExternalString)                               \
    475   V(SHORT_EXTERNAL_ONE_BYTE_STRING_TYPE, ExternalOneByteString::kShortSize,   \
    476     short_external_one_byte_string, ShortExternalOneByteString)               \
    477   V(SHORT_EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE,                            \
    478     ExternalTwoByteString::kShortSize,                                        \
    479     short_external_string_with_one_byte_data,                                 \
    480     ShortExternalStringWithOneByteData)                                       \
    481                                                                               \
    482   V(INTERNALIZED_STRING_TYPE, kVariableSizeSentinel, internalized_string,     \
    483     InternalizedString)                                                       \
    484   V(ONE_BYTE_INTERNALIZED_STRING_TYPE, kVariableSizeSentinel,                 \
    485     one_byte_internalized_string, OneByteInternalizedString)                  \
    486   V(EXTERNAL_INTERNALIZED_STRING_TYPE, ExternalTwoByteString::kSize,          \
    487     external_internalized_string, ExternalInternalizedString)                 \
    488   V(EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE, ExternalOneByteString::kSize, \
    489     external_one_byte_internalized_string, ExternalOneByteInternalizedString) \
    490   V(EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE,                     \
    491     ExternalTwoByteString::kSize,                                             \
    492     external_internalized_string_with_one_byte_data,                          \
    493     ExternalInternalizedStringWithOneByteData)                                \
    494   V(SHORT_EXTERNAL_INTERNALIZED_STRING_TYPE,                                  \
    495     ExternalTwoByteString::kShortSize, short_external_internalized_string,    \
    496     ShortExternalInternalizedString)                                          \
    497   V(SHORT_EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE,                         \
    498     ExternalOneByteString::kShortSize,                                        \
    499     short_external_one_byte_internalized_string,                              \
    500     ShortExternalOneByteInternalizedString)                                   \
    501   V(SHORT_EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE,               \
    502     ExternalTwoByteString::kShortSize,                                        \
    503     short_external_internalized_string_with_one_byte_data,                    \
    504     ShortExternalInternalizedStringWithOneByteData)
    505 
    506 // A struct is a simple object a set of object-valued fields.  Including an
    507 // object type in this causes the compiler to generate most of the boilerplate
    508 // code for the class including allocation and garbage collection routines,
    509 // casts and predicates.  All you need to define is the class, methods and
    510 // object verification routines.  Easy, no?
    511 //
    512 // Note that for subtle reasons related to the ordering or numerical values of
    513 // type tags, elements in this list have to be added to the INSTANCE_TYPE_LIST
    514 // manually.
    515 #define STRUCT_LIST(V)                                                         \
    516   V(BOX, Box, box)                                                             \
    517   V(DECLARED_ACCESSOR_DESCRIPTOR,                                              \
    518     DeclaredAccessorDescriptor,                                                \
    519     declared_accessor_descriptor)                                              \
    520   V(DECLARED_ACCESSOR_INFO, DeclaredAccessorInfo, declared_accessor_info)      \
    521   V(EXECUTABLE_ACCESSOR_INFO, ExecutableAccessorInfo, executable_accessor_info)\
    522   V(ACCESSOR_PAIR, AccessorPair, accessor_pair)                                \
    523   V(ACCESS_CHECK_INFO, AccessCheckInfo, access_check_info)                     \
    524   V(INTERCEPTOR_INFO, InterceptorInfo, interceptor_info)                       \
    525   V(CALL_HANDLER_INFO, CallHandlerInfo, call_handler_info)                     \
    526   V(FUNCTION_TEMPLATE_INFO, FunctionTemplateInfo, function_template_info)      \
    527   V(OBJECT_TEMPLATE_INFO, ObjectTemplateInfo, object_template_info)            \
    528   V(SIGNATURE_INFO, SignatureInfo, signature_info)                             \
    529   V(TYPE_SWITCH_INFO, TypeSwitchInfo, type_switch_info)                        \
    530   V(SCRIPT, Script, script)                                                    \
    531   V(ALLOCATION_SITE, AllocationSite, allocation_site)                          \
    532   V(ALLOCATION_MEMENTO, AllocationMemento, allocation_memento)                 \
    533   V(CODE_CACHE, CodeCache, code_cache)                                         \
    534   V(POLYMORPHIC_CODE_CACHE, PolymorphicCodeCache, polymorphic_code_cache)      \
    535   V(TYPE_FEEDBACK_INFO, TypeFeedbackInfo, type_feedback_info)                  \
    536   V(ALIASED_ARGUMENTS_ENTRY, AliasedArgumentsEntry, aliased_arguments_entry)   \
    537   V(DEBUG_INFO, DebugInfo, debug_info)                                         \
    538   V(BREAK_POINT_INFO, BreakPointInfo, break_point_info)
    539 
    540 // We use the full 8 bits of the instance_type field to encode heap object
    541 // instance types.  The high-order bit (bit 7) is set if the object is not a
    542 // string, and cleared if it is a string.
    543 const uint32_t kIsNotStringMask = 0x80;
    544 const uint32_t kStringTag = 0x0;
    545 const uint32_t kNotStringTag = 0x80;
    546 
    547 // Bit 6 indicates that the object is an internalized string (if set) or not.
    548 // Bit 7 has to be clear as well.
    549 const uint32_t kIsNotInternalizedMask = 0x40;
    550 const uint32_t kNotInternalizedTag = 0x40;
    551 const uint32_t kInternalizedTag = 0x0;
    552 
    553 // If bit 7 is clear then bit 2 indicates whether the string consists of
    554 // two-byte characters or one-byte characters.
    555 const uint32_t kStringEncodingMask = 0x4;
    556 const uint32_t kTwoByteStringTag = 0x0;
    557 const uint32_t kOneByteStringTag = 0x4;
    558 
    559 // If bit 7 is clear, the low-order 2 bits indicate the representation
    560 // of the string.
    561 const uint32_t kStringRepresentationMask = 0x03;
    562 enum StringRepresentationTag {
    563   kSeqStringTag = 0x0,
    564   kConsStringTag = 0x1,
    565   kExternalStringTag = 0x2,
    566   kSlicedStringTag = 0x3
    567 };
    568 const uint32_t kIsIndirectStringMask = 0x1;
    569 const uint32_t kIsIndirectStringTag = 0x1;
    570 STATIC_ASSERT((kSeqStringTag & kIsIndirectStringMask) == 0);  // NOLINT
    571 STATIC_ASSERT((kExternalStringTag & kIsIndirectStringMask) == 0);  // NOLINT
    572 STATIC_ASSERT((kConsStringTag &
    573                kIsIndirectStringMask) == kIsIndirectStringTag);  // NOLINT
    574 STATIC_ASSERT((kSlicedStringTag &
    575                kIsIndirectStringMask) == kIsIndirectStringTag);  // NOLINT
    576 
    577 // Use this mask to distinguish between cons and slice only after making
    578 // sure that the string is one of the two (an indirect string).
    579 const uint32_t kSlicedNotConsMask = kSlicedStringTag & ~kConsStringTag;
    580 STATIC_ASSERT(IS_POWER_OF_TWO(kSlicedNotConsMask));
    581 
    582 // If bit 7 is clear, then bit 3 indicates whether this two-byte
    583 // string actually contains one byte data.
    584 const uint32_t kOneByteDataHintMask = 0x08;
    585 const uint32_t kOneByteDataHintTag = 0x08;
    586 
    587 // If bit 7 is clear and string representation indicates an external string,
    588 // then bit 4 indicates whether the data pointer is cached.
    589 const uint32_t kShortExternalStringMask = 0x10;
    590 const uint32_t kShortExternalStringTag = 0x10;
    591 
    592 
    593 // A ConsString with an empty string as the right side is a candidate
    594 // for being shortcut by the garbage collector. We don't allocate any
    595 // non-flat internalized strings, so we do not shortcut them thereby
    596 // avoiding turning internalized strings into strings. The bit-masks
    597 // below contain the internalized bit as additional safety.
    598 // See heap.cc, mark-compact.cc and objects-visiting.cc.
    599 const uint32_t kShortcutTypeMask =
    600     kIsNotStringMask |
    601     kIsNotInternalizedMask |
    602     kStringRepresentationMask;
    603 const uint32_t kShortcutTypeTag = kConsStringTag | kNotInternalizedTag;
    604 
    605 static inline bool IsShortcutCandidate(int type) {
    606   return ((type & kShortcutTypeMask) == kShortcutTypeTag);
    607 }
    608 
    609 
    610 enum InstanceType {
    611   // String types.
    612   INTERNALIZED_STRING_TYPE =
    613       kTwoByteStringTag | kSeqStringTag | kInternalizedTag,
    614   ONE_BYTE_INTERNALIZED_STRING_TYPE =
    615       kOneByteStringTag | kSeqStringTag | kInternalizedTag,
    616   EXTERNAL_INTERNALIZED_STRING_TYPE =
    617       kTwoByteStringTag | kExternalStringTag | kInternalizedTag,
    618   EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE =
    619       kOneByteStringTag | kExternalStringTag | kInternalizedTag,
    620   EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE =
    621       EXTERNAL_INTERNALIZED_STRING_TYPE | kOneByteDataHintTag |
    622       kInternalizedTag,
    623   SHORT_EXTERNAL_INTERNALIZED_STRING_TYPE = EXTERNAL_INTERNALIZED_STRING_TYPE |
    624                                             kShortExternalStringTag |
    625                                             kInternalizedTag,
    626   SHORT_EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE =
    627       EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE | kShortExternalStringTag |
    628       kInternalizedTag,
    629   SHORT_EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE =
    630       EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE |
    631       kShortExternalStringTag | kInternalizedTag,
    632   STRING_TYPE = INTERNALIZED_STRING_TYPE | kNotInternalizedTag,
    633   ONE_BYTE_STRING_TYPE =
    634       ONE_BYTE_INTERNALIZED_STRING_TYPE | kNotInternalizedTag,
    635   CONS_STRING_TYPE = kTwoByteStringTag | kConsStringTag | kNotInternalizedTag,
    636   CONS_ONE_BYTE_STRING_TYPE =
    637       kOneByteStringTag | kConsStringTag | kNotInternalizedTag,
    638   SLICED_STRING_TYPE =
    639       kTwoByteStringTag | kSlicedStringTag | kNotInternalizedTag,
    640   SLICED_ONE_BYTE_STRING_TYPE =
    641       kOneByteStringTag | kSlicedStringTag | kNotInternalizedTag,
    642   EXTERNAL_STRING_TYPE =
    643       EXTERNAL_INTERNALIZED_STRING_TYPE | kNotInternalizedTag,
    644   EXTERNAL_ONE_BYTE_STRING_TYPE =
    645       EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE | kNotInternalizedTag,
    646   EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE =
    647       EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE |
    648       kNotInternalizedTag,
    649   SHORT_EXTERNAL_STRING_TYPE =
    650       SHORT_EXTERNAL_INTERNALIZED_STRING_TYPE | kNotInternalizedTag,
    651   SHORT_EXTERNAL_ONE_BYTE_STRING_TYPE =
    652       SHORT_EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE | kNotInternalizedTag,
    653   SHORT_EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE =
    654       SHORT_EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE |
    655       kNotInternalizedTag,
    656 
    657   // Non-string names
    658   SYMBOL_TYPE = kNotStringTag,  // FIRST_NONSTRING_TYPE, LAST_NAME_TYPE
    659 
    660   // Objects allocated in their own spaces (never in new space).
    661   MAP_TYPE,
    662   CODE_TYPE,
    663   ODDBALL_TYPE,
    664   CELL_TYPE,
    665   PROPERTY_CELL_TYPE,
    666 
    667   // "Data", objects that cannot contain non-map-word pointers to heap
    668   // objects.
    669   HEAP_NUMBER_TYPE,
    670   MUTABLE_HEAP_NUMBER_TYPE,
    671   FOREIGN_TYPE,
    672   BYTE_ARRAY_TYPE,
    673   FREE_SPACE_TYPE,
    674   EXTERNAL_INT8_ARRAY_TYPE,  // FIRST_EXTERNAL_ARRAY_TYPE
    675   EXTERNAL_UINT8_ARRAY_TYPE,
    676   EXTERNAL_INT16_ARRAY_TYPE,
    677   EXTERNAL_UINT16_ARRAY_TYPE,
    678   EXTERNAL_INT32_ARRAY_TYPE,
    679   EXTERNAL_UINT32_ARRAY_TYPE,
    680   EXTERNAL_FLOAT32_ARRAY_TYPE,
    681   EXTERNAL_FLOAT64_ARRAY_TYPE,
    682   EXTERNAL_UINT8_CLAMPED_ARRAY_TYPE,  // LAST_EXTERNAL_ARRAY_TYPE
    683   FIXED_INT8_ARRAY_TYPE,              // FIRST_FIXED_TYPED_ARRAY_TYPE
    684   FIXED_UINT8_ARRAY_TYPE,
    685   FIXED_INT16_ARRAY_TYPE,
    686   FIXED_UINT16_ARRAY_TYPE,
    687   FIXED_INT32_ARRAY_TYPE,
    688   FIXED_UINT32_ARRAY_TYPE,
    689   FIXED_FLOAT32_ARRAY_TYPE,
    690   FIXED_FLOAT64_ARRAY_TYPE,
    691   FIXED_UINT8_CLAMPED_ARRAY_TYPE,  // LAST_FIXED_TYPED_ARRAY_TYPE
    692   FIXED_DOUBLE_ARRAY_TYPE,
    693   FILLER_TYPE,  // LAST_DATA_TYPE
    694 
    695   // Structs.
    696   DECLARED_ACCESSOR_DESCRIPTOR_TYPE,
    697   DECLARED_ACCESSOR_INFO_TYPE,
    698   EXECUTABLE_ACCESSOR_INFO_TYPE,
    699   ACCESSOR_PAIR_TYPE,
    700   ACCESS_CHECK_INFO_TYPE,
    701   INTERCEPTOR_INFO_TYPE,
    702   CALL_HANDLER_INFO_TYPE,
    703   FUNCTION_TEMPLATE_INFO_TYPE,
    704   OBJECT_TEMPLATE_INFO_TYPE,
    705   SIGNATURE_INFO_TYPE,
    706   TYPE_SWITCH_INFO_TYPE,
    707   ALLOCATION_SITE_TYPE,
    708   ALLOCATION_MEMENTO_TYPE,
    709   SCRIPT_TYPE,
    710   CODE_CACHE_TYPE,
    711   POLYMORPHIC_CODE_CACHE_TYPE,
    712   TYPE_FEEDBACK_INFO_TYPE,
    713   ALIASED_ARGUMENTS_ENTRY_TYPE,
    714   BOX_TYPE,
    715   DEBUG_INFO_TYPE,
    716   BREAK_POINT_INFO_TYPE,
    717   FIXED_ARRAY_TYPE,
    718   CONSTANT_POOL_ARRAY_TYPE,
    719   SHARED_FUNCTION_INFO_TYPE,
    720 
    721   // All the following types are subtypes of JSReceiver, which corresponds to
    722   // objects in the JS sense. The first and the last type in this range are
    723   // the two forms of function. This organization enables using the same
    724   // compares for checking the JS_RECEIVER/SPEC_OBJECT range and the
    725   // NONCALLABLE_JS_OBJECT range.
    726   JS_FUNCTION_PROXY_TYPE,  // FIRST_JS_RECEIVER_TYPE, FIRST_JS_PROXY_TYPE
    727   JS_PROXY_TYPE,           // LAST_JS_PROXY_TYPE
    728   JS_VALUE_TYPE,           // FIRST_JS_OBJECT_TYPE
    729   JS_MESSAGE_OBJECT_TYPE,
    730   JS_DATE_TYPE,
    731   JS_OBJECT_TYPE,
    732   JS_CONTEXT_EXTENSION_OBJECT_TYPE,
    733   JS_GENERATOR_OBJECT_TYPE,
    734   JS_MODULE_TYPE,
    735   JS_GLOBAL_OBJECT_TYPE,
    736   JS_BUILTINS_OBJECT_TYPE,
    737   JS_GLOBAL_PROXY_TYPE,
    738   JS_ARRAY_TYPE,
    739   JS_ARRAY_BUFFER_TYPE,
    740   JS_TYPED_ARRAY_TYPE,
    741   JS_DATA_VIEW_TYPE,
    742   JS_SET_TYPE,
    743   JS_MAP_TYPE,
    744   JS_SET_ITERATOR_TYPE,
    745   JS_MAP_ITERATOR_TYPE,
    746   JS_WEAK_MAP_TYPE,
    747   JS_WEAK_SET_TYPE,
    748   JS_REGEXP_TYPE,
    749   JS_FUNCTION_TYPE,  // LAST_JS_OBJECT_TYPE, LAST_JS_RECEIVER_TYPE
    750 
    751   // Pseudo-types
    752   FIRST_TYPE = 0x0,
    753   LAST_TYPE = JS_FUNCTION_TYPE,
    754   FIRST_NAME_TYPE = FIRST_TYPE,
    755   LAST_NAME_TYPE = SYMBOL_TYPE,
    756   FIRST_UNIQUE_NAME_TYPE = INTERNALIZED_STRING_TYPE,
    757   LAST_UNIQUE_NAME_TYPE = SYMBOL_TYPE,
    758   FIRST_NONSTRING_TYPE = SYMBOL_TYPE,
    759   // Boundaries for testing for an external array.
    760   FIRST_EXTERNAL_ARRAY_TYPE = EXTERNAL_INT8_ARRAY_TYPE,
    761   LAST_EXTERNAL_ARRAY_TYPE = EXTERNAL_UINT8_CLAMPED_ARRAY_TYPE,
    762   // Boundaries for testing for a fixed typed array.
    763   FIRST_FIXED_TYPED_ARRAY_TYPE = FIXED_INT8_ARRAY_TYPE,
    764   LAST_FIXED_TYPED_ARRAY_TYPE = FIXED_UINT8_CLAMPED_ARRAY_TYPE,
    765   // Boundary for promotion to old data space/old pointer space.
    766   LAST_DATA_TYPE = FILLER_TYPE,
    767   // Boundary for objects represented as JSReceiver (i.e. JSObject or JSProxy).
    768   // Note that there is no range for JSObject or JSProxy, since their subtypes
    769   // are not continuous in this enum! The enum ranges instead reflect the
    770   // external class names, where proxies are treated as either ordinary objects,
    771   // or functions.
    772   FIRST_JS_RECEIVER_TYPE = JS_FUNCTION_PROXY_TYPE,
    773   LAST_JS_RECEIVER_TYPE = LAST_TYPE,
    774   // Boundaries for testing the types represented as JSObject
    775   FIRST_JS_OBJECT_TYPE = JS_VALUE_TYPE,
    776   LAST_JS_OBJECT_TYPE = LAST_TYPE,
    777   // Boundaries for testing the types represented as JSProxy
    778   FIRST_JS_PROXY_TYPE = JS_FUNCTION_PROXY_TYPE,
    779   LAST_JS_PROXY_TYPE = JS_PROXY_TYPE,
    780   // Boundaries for testing whether the type is a JavaScript object.
    781   FIRST_SPEC_OBJECT_TYPE = FIRST_JS_RECEIVER_TYPE,
    782   LAST_SPEC_OBJECT_TYPE = LAST_JS_RECEIVER_TYPE,
    783   // Boundaries for testing the types for which typeof is "object".
    784   FIRST_NONCALLABLE_SPEC_OBJECT_TYPE = JS_PROXY_TYPE,
    785   LAST_NONCALLABLE_SPEC_OBJECT_TYPE = JS_REGEXP_TYPE,
    786   // Note that the types for which typeof is "function" are not continuous.
    787   // Define this so that we can put assertions on discrete checks.
    788   NUM_OF_CALLABLE_SPEC_OBJECT_TYPES = 2
    789 };
    790 
    791 const int kExternalArrayTypeCount =
    792     LAST_EXTERNAL_ARRAY_TYPE - FIRST_EXTERNAL_ARRAY_TYPE + 1;
    793 
    794 STATIC_ASSERT(JS_OBJECT_TYPE == Internals::kJSObjectType);
    795 STATIC_ASSERT(FIRST_NONSTRING_TYPE == Internals::kFirstNonstringType);
    796 STATIC_ASSERT(ODDBALL_TYPE == Internals::kOddballType);
    797 STATIC_ASSERT(FOREIGN_TYPE == Internals::kForeignType);
    798 
    799 
    800 #define FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(V) \
    801   V(FAST_ELEMENTS_SUB_TYPE)                   \
    802   V(DICTIONARY_ELEMENTS_SUB_TYPE)             \
    803   V(FAST_PROPERTIES_SUB_TYPE)                 \
    804   V(DICTIONARY_PROPERTIES_SUB_TYPE)           \
    805   V(MAP_CODE_CACHE_SUB_TYPE)                  \
    806   V(SCOPE_INFO_SUB_TYPE)                      \
    807   V(STRING_TABLE_SUB_TYPE)                    \
    808   V(DESCRIPTOR_ARRAY_SUB_TYPE)                \
    809   V(TRANSITION_ARRAY_SUB_TYPE)
    810 
    811 enum FixedArraySubInstanceType {
    812 #define DEFINE_FIXED_ARRAY_SUB_INSTANCE_TYPE(name) name,
    813   FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(DEFINE_FIXED_ARRAY_SUB_INSTANCE_TYPE)
    814 #undef DEFINE_FIXED_ARRAY_SUB_INSTANCE_TYPE
    815   LAST_FIXED_ARRAY_SUB_TYPE = TRANSITION_ARRAY_SUB_TYPE
    816 };
    817 
    818 
    819 enum CompareResult {
    820   LESS      = -1,
    821   EQUAL     =  0,
    822   GREATER   =  1,
    823 
    824   NOT_EQUAL = GREATER
    825 };
    826 
    827 
    828 #define DECL_BOOLEAN_ACCESSORS(name)   \
    829   inline bool name() const;            \
    830   inline void set_##name(bool value);  \
    831 
    832 
    833 #define DECL_ACCESSORS(name, type)                                      \
    834   inline type* name() const;                                            \
    835   inline void set_##name(type* value,                                   \
    836                          WriteBarrierMode mode = UPDATE_WRITE_BARRIER); \
    837 
    838 
    839 #define DECLARE_CAST(type)                              \
    840   INLINE(static type* cast(Object* object));            \
    841   INLINE(static const type* cast(const Object* object));
    842 
    843 
    844 class AccessorPair;
    845 class AllocationSite;
    846 class AllocationSiteCreationContext;
    847 class AllocationSiteUsageContext;
    848 class DictionaryElementsAccessor;
    849 class ElementsAccessor;
    850 class FixedArrayBase;
    851 class GlobalObject;
    852 class ObjectVisitor;
    853 class LookupIterator;
    854 class StringStream;
    855 class TypeFeedbackVector;
    856 // We cannot just say "class HeapType;" if it is created from a template... =8-?
    857 template<class> class TypeImpl;
    858 struct HeapTypeConfig;
    859 typedef TypeImpl<HeapTypeConfig> HeapType;
    860 
    861 
    862 // A template-ized version of the IsXXX functions.
    863 template <class C> inline bool Is(Object* obj);
    864 
    865 #ifdef VERIFY_HEAP
    866 #define DECLARE_VERIFIER(Name) void Name##Verify();
    867 #else
    868 #define DECLARE_VERIFIER(Name)
    869 #endif
    870 
    871 #ifdef OBJECT_PRINT
    872 #define DECLARE_PRINTER(Name) void Name##Print(OStream& os);  // NOLINT
    873 #else
    874 #define DECLARE_PRINTER(Name)
    875 #endif
    876 
    877 
    878 #define OBJECT_TYPE_LIST(V) \
    879   V(Smi)                    \
    880   V(HeapObject)             \
    881   V(Number)
    882 
    883 #define HEAP_OBJECT_TYPE_LIST(V)   \
    884   V(HeapNumber)                    \
    885   V(MutableHeapNumber)             \
    886   V(Name)                          \
    887   V(UniqueName)                    \
    888   V(String)                        \
    889   V(SeqString)                     \
    890   V(ExternalString)                \
    891   V(ConsString)                    \
    892   V(SlicedString)                  \
    893   V(ExternalTwoByteString)         \
    894   V(ExternalOneByteString)         \
    895   V(SeqTwoByteString)              \
    896   V(SeqOneByteString)              \
    897   V(InternalizedString)            \
    898   V(Symbol)                        \
    899                                    \
    900   V(ExternalArray)                 \
    901   V(ExternalInt8Array)             \
    902   V(ExternalUint8Array)            \
    903   V(ExternalInt16Array)            \
    904   V(ExternalUint16Array)           \
    905   V(ExternalInt32Array)            \
    906   V(ExternalUint32Array)           \
    907   V(ExternalFloat32Array)          \
    908   V(ExternalFloat64Array)          \
    909   V(ExternalUint8ClampedArray)     \
    910   V(FixedTypedArrayBase)           \
    911   V(FixedUint8Array)               \
    912   V(FixedInt8Array)                \
    913   V(FixedUint16Array)              \
    914   V(FixedInt16Array)               \
    915   V(FixedUint32Array)              \
    916   V(FixedInt32Array)               \
    917   V(FixedFloat32Array)             \
    918   V(FixedFloat64Array)             \
    919   V(FixedUint8ClampedArray)        \
    920   V(ByteArray)                     \
    921   V(FreeSpace)                     \
    922   V(JSReceiver)                    \
    923   V(JSObject)                      \
    924   V(JSContextExtensionObject)      \
    925   V(JSGeneratorObject)             \
    926   V(JSModule)                      \
    927   V(Map)                           \
    928   V(DescriptorArray)               \
    929   V(TransitionArray)               \
    930   V(TypeFeedbackVector)            \
    931   V(DeoptimizationInputData)       \
    932   V(DeoptimizationOutputData)      \
    933   V(DependentCode)                 \
    934   V(FixedArray)                    \
    935   V(FixedDoubleArray)              \
    936   V(ConstantPoolArray)             \
    937   V(Context)                       \
    938   V(NativeContext)                 \
    939   V(ScopeInfo)                     \
    940   V(JSFunction)                    \
    941   V(Code)                          \
    942   V(Oddball)                       \
    943   V(SharedFunctionInfo)            \
    944   V(JSValue)                       \
    945   V(JSDate)                        \
    946   V(JSMessageObject)               \
    947   V(StringWrapper)                 \
    948   V(Foreign)                       \
    949   V(Boolean)                       \
    950   V(JSArray)                       \
    951   V(JSArrayBuffer)                 \
    952   V(JSArrayBufferView)             \
    953   V(JSTypedArray)                  \
    954   V(JSDataView)                    \
    955   V(JSProxy)                       \
    956   V(JSFunctionProxy)               \
    957   V(JSSet)                         \
    958   V(JSMap)                         \
    959   V(JSSetIterator)                 \
    960   V(JSMapIterator)                 \
    961   V(JSWeakCollection)              \
    962   V(JSWeakMap)                     \
    963   V(JSWeakSet)                     \
    964   V(JSRegExp)                      \
    965   V(HashTable)                     \
    966   V(Dictionary)                    \
    967   V(StringTable)                   \
    968   V(JSFunctionResultCache)         \
    969   V(NormalizedMapCache)            \
    970   V(CompilationCacheTable)         \
    971   V(CodeCacheHashTable)            \
    972   V(PolymorphicCodeCacheHashTable) \
    973   V(MapCache)                      \
    974   V(Primitive)                     \
    975   V(GlobalObject)                  \
    976   V(JSGlobalObject)                \
    977   V(JSBuiltinsObject)              \
    978   V(JSGlobalProxy)                 \
    979   V(UndetectableObject)            \
    980   V(AccessCheckNeeded)             \
    981   V(Cell)                          \
    982   V(PropertyCell)                  \
    983   V(ObjectHashTable)               \
    984   V(WeakHashTable)                 \
    985   V(OrderedHashTable)
    986 
    987 // Object is the abstract superclass for all classes in the
    988 // object hierarchy.
    989 // Object does not use any virtual functions to avoid the
    990 // allocation of the C++ vtable.
    991 // Since both Smi and HeapObject are subclasses of Object no
    992 // data members can be present in Object.
    993 class Object {
    994  public:
    995   // Type testing.
    996   bool IsObject() const { return true; }
    997 
    998 #define IS_TYPE_FUNCTION_DECL(type_)  INLINE(bool Is##type_() const);
    999   OBJECT_TYPE_LIST(IS_TYPE_FUNCTION_DECL)
   1000   HEAP_OBJECT_TYPE_LIST(IS_TYPE_FUNCTION_DECL)
   1001 #undef IS_TYPE_FUNCTION_DECL
   1002 
   1003   // A non-keyed store is of the form a.x = foo or a["x"] = foo whereas
   1004   // a keyed store is of the form a[expression] = foo.
   1005   enum StoreFromKeyed {
   1006     MAY_BE_STORE_FROM_KEYED,
   1007     CERTAINLY_NOT_STORE_FROM_KEYED
   1008   };
   1009 
   1010   INLINE(bool IsFixedArrayBase() const);
   1011   INLINE(bool IsExternal() const);
   1012   INLINE(bool IsAccessorInfo() const);
   1013 
   1014   INLINE(bool IsStruct() const);
   1015 #define DECLARE_STRUCT_PREDICATE(NAME, Name, name) \
   1016   INLINE(bool Is##Name() const);
   1017   STRUCT_LIST(DECLARE_STRUCT_PREDICATE)
   1018 #undef DECLARE_STRUCT_PREDICATE
   1019 
   1020   INLINE(bool IsSpecObject()) const;
   1021   INLINE(bool IsSpecFunction()) const;
   1022   INLINE(bool IsTemplateInfo()) const;
   1023   INLINE(bool IsNameDictionary() const);
   1024   INLINE(bool IsSeededNumberDictionary() const);
   1025   INLINE(bool IsUnseededNumberDictionary() const);
   1026   INLINE(bool IsOrderedHashSet() const);
   1027   INLINE(bool IsOrderedHashMap() const);
   1028   bool IsCallable() const;
   1029 
   1030   // Oddball testing.
   1031   INLINE(bool IsUndefined() const);
   1032   INLINE(bool IsNull() const);
   1033   INLINE(bool IsTheHole() const);
   1034   INLINE(bool IsException() const);
   1035   INLINE(bool IsUninitialized() const);
   1036   INLINE(bool IsTrue() const);
   1037   INLINE(bool IsFalse() const);
   1038   INLINE(bool IsArgumentsMarker() const);
   1039 
   1040   // Filler objects (fillers and free space objects).
   1041   INLINE(bool IsFiller() const);
   1042 
   1043   // Extract the number.
   1044   inline double Number();
   1045   INLINE(bool IsNaN() const);
   1046   INLINE(bool IsMinusZero() const);
   1047   bool ToInt32(int32_t* value);
   1048   bool ToUint32(uint32_t* value);
   1049 
   1050   inline Representation OptimalRepresentation() {
   1051     if (!FLAG_track_fields) return Representation::Tagged();
   1052     if (IsSmi()) {
   1053       return Representation::Smi();
   1054     } else if (FLAG_track_double_fields && IsHeapNumber()) {
   1055       return Representation::Double();
   1056     } else if (FLAG_track_computed_fields && IsUninitialized()) {
   1057       return Representation::None();
   1058     } else if (FLAG_track_heap_object_fields) {
   1059       DCHECK(IsHeapObject());
   1060       return Representation::HeapObject();
   1061     } else {
   1062       return Representation::Tagged();
   1063     }
   1064   }
   1065 
   1066   inline bool FitsRepresentation(Representation representation) {
   1067     if (FLAG_track_fields && representation.IsNone()) {
   1068       return false;
   1069     } else if (FLAG_track_fields && representation.IsSmi()) {
   1070       return IsSmi();
   1071     } else if (FLAG_track_double_fields && representation.IsDouble()) {
   1072       return IsMutableHeapNumber() || IsNumber();
   1073     } else if (FLAG_track_heap_object_fields && representation.IsHeapObject()) {
   1074       return IsHeapObject();
   1075     }
   1076     return true;
   1077   }
   1078 
   1079   Handle<HeapType> OptimalType(Isolate* isolate, Representation representation);
   1080 
   1081   inline static Handle<Object> NewStorageFor(Isolate* isolate,
   1082                                              Handle<Object> object,
   1083                                              Representation representation);
   1084 
   1085   inline static Handle<Object> WrapForRead(Isolate* isolate,
   1086                                            Handle<Object> object,
   1087                                            Representation representation);
   1088 
   1089   // Returns true if the object is of the correct type to be used as a
   1090   // implementation of a JSObject's elements.
   1091   inline bool HasValidElements();
   1092 
   1093   inline bool HasSpecificClassOf(String* name);
   1094 
   1095   bool BooleanValue();                                      // ECMA-262 9.2.
   1096 
   1097   // Convert to a JSObject if needed.
   1098   // native_context is used when creating wrapper object.
   1099   static inline MaybeHandle<JSReceiver> ToObject(Isolate* isolate,
   1100                                                  Handle<Object> object);
   1101   static MaybeHandle<JSReceiver> ToObject(Isolate* isolate,
   1102                                           Handle<Object> object,
   1103                                           Handle<Context> context);
   1104 
   1105   // Converts this to a Smi if possible.
   1106   static MUST_USE_RESULT inline MaybeHandle<Smi> ToSmi(Isolate* isolate,
   1107                                                        Handle<Object> object);
   1108 
   1109   MUST_USE_RESULT static MaybeHandle<Object> GetProperty(LookupIterator* it);
   1110 
   1111   // Implementation of [[Put]], ECMA-262 5th edition, section 8.12.5.
   1112   MUST_USE_RESULT static MaybeHandle<Object> SetProperty(
   1113       Handle<Object> object, Handle<Name> key, Handle<Object> value,
   1114       StrictMode strict_mode,
   1115       StoreFromKeyed store_mode = MAY_BE_STORE_FROM_KEYED);
   1116 
   1117   MUST_USE_RESULT static MaybeHandle<Object> SetProperty(
   1118       LookupIterator* it, Handle<Object> value, StrictMode strict_mode,
   1119       StoreFromKeyed store_mode);
   1120   MUST_USE_RESULT static MaybeHandle<Object> WriteToReadOnlyProperty(
   1121       LookupIterator* it, Handle<Object> value, StrictMode strict_mode);
   1122   static Handle<Object> SetDataProperty(LookupIterator* it,
   1123                                         Handle<Object> value);
   1124   MUST_USE_RESULT static MaybeHandle<Object> AddDataProperty(
   1125       LookupIterator* it, Handle<Object> value, PropertyAttributes attributes,
   1126       StrictMode strict_mode, StoreFromKeyed store_mode);
   1127   MUST_USE_RESULT static inline MaybeHandle<Object> GetPropertyOrElement(
   1128       Handle<Object> object,
   1129       Handle<Name> key);
   1130   MUST_USE_RESULT static inline MaybeHandle<Object> GetProperty(
   1131       Isolate* isolate,
   1132       Handle<Object> object,
   1133       const char* key);
   1134   MUST_USE_RESULT static inline MaybeHandle<Object> GetProperty(
   1135       Handle<Object> object,
   1136       Handle<Name> key);
   1137 
   1138   MUST_USE_RESULT static MaybeHandle<Object> GetPropertyWithAccessor(
   1139       Handle<Object> receiver,
   1140       Handle<Name> name,
   1141       Handle<JSObject> holder,
   1142       Handle<Object> structure);
   1143   MUST_USE_RESULT static MaybeHandle<Object> SetPropertyWithAccessor(
   1144       Handle<Object> receiver, Handle<Name> name, Handle<Object> value,
   1145       Handle<JSObject> holder, Handle<Object> structure,
   1146       StrictMode strict_mode);
   1147 
   1148   MUST_USE_RESULT static MaybeHandle<Object> GetPropertyWithDefinedGetter(
   1149       Handle<Object> receiver,
   1150       Handle<JSReceiver> getter);
   1151   MUST_USE_RESULT static MaybeHandle<Object> SetPropertyWithDefinedSetter(
   1152       Handle<Object> receiver,
   1153       Handle<JSReceiver> setter,
   1154       Handle<Object> value);
   1155 
   1156   MUST_USE_RESULT static inline MaybeHandle<Object> GetElement(
   1157       Isolate* isolate,
   1158       Handle<Object> object,
   1159       uint32_t index);
   1160 
   1161   MUST_USE_RESULT static MaybeHandle<Object> GetElementWithReceiver(
   1162       Isolate* isolate,
   1163       Handle<Object> object,
   1164       Handle<Object> receiver,
   1165       uint32_t index);
   1166 
   1167   // Returns the permanent hash code associated with this object. May return
   1168   // undefined if not yet created.
   1169   Object* GetHash();
   1170 
   1171   // Returns the permanent hash code associated with this object depending on
   1172   // the actual object type. May create and store a hash code if needed and none
   1173   // exists.
   1174   static Handle<Smi> GetOrCreateHash(Isolate* isolate, Handle<Object> object);
   1175 
   1176   // Checks whether this object has the same value as the given one.  This
   1177   // function is implemented according to ES5, section 9.12 and can be used
   1178   // to implement the Harmony "egal" function.
   1179   bool SameValue(Object* other);
   1180 
   1181   // Checks whether this object has the same value as the given one.
   1182   // +0 and -0 are treated equal. Everything else is the same as SameValue.
   1183   // This function is implemented according to ES6, section 7.2.4 and is used
   1184   // by ES6 Map and Set.
   1185   bool SameValueZero(Object* other);
   1186 
   1187   // Tries to convert an object to an array index.  Returns true and sets
   1188   // the output parameter if it succeeds.
   1189   inline bool ToArrayIndex(uint32_t* index);
   1190 
   1191   // Returns true if this is a JSValue containing a string and the index is
   1192   // < the length of the string.  Used to implement [] on strings.
   1193   inline bool IsStringObjectWithCharacterAt(uint32_t index);
   1194 
   1195   DECLARE_VERIFIER(Object)
   1196 #ifdef VERIFY_HEAP
   1197   // Verify a pointer is a valid object pointer.
   1198   static void VerifyPointer(Object* p);
   1199 #endif
   1200 
   1201   inline void VerifyApiCallResultType();
   1202 
   1203   // Prints this object without details.
   1204   void ShortPrint(FILE* out = stdout);
   1205 
   1206   // Prints this object without details to a message accumulator.
   1207   void ShortPrint(StringStream* accumulator);
   1208 
   1209   DECLARE_CAST(Object)
   1210 
   1211   // Layout description.
   1212   static const int kHeaderSize = 0;  // Object does not take up any space.
   1213 
   1214 #ifdef OBJECT_PRINT
   1215   // For our gdb macros, we should perhaps change these in the future.
   1216   void Print();
   1217 
   1218   // Prints this object with details.
   1219   void Print(OStream& os);  // NOLINT
   1220 #endif
   1221 
   1222  private:
   1223   friend class LookupIterator;
   1224   friend class PrototypeIterator;
   1225 
   1226   // Return the map of the root of object's prototype chain.
   1227   Map* GetRootMap(Isolate* isolate);
   1228 
   1229   DISALLOW_IMPLICIT_CONSTRUCTORS(Object);
   1230 };
   1231 
   1232 
   1233 struct Brief {
   1234   explicit Brief(const Object* const v) : value(v) {}
   1235   const Object* value;
   1236 };
   1237 
   1238 
   1239 OStream& operator<<(OStream& os, const Brief& v);
   1240 
   1241 
   1242 // Smi represents integer Numbers that can be stored in 31 bits.
   1243 // Smis are immediate which means they are NOT allocated in the heap.
   1244 // The this pointer has the following format: [31 bit signed int] 0
   1245 // For long smis it has the following format:
   1246 //     [32 bit signed int] [31 bits zero padding] 0
   1247 // Smi stands for small integer.
   1248 class Smi: public Object {
   1249  public:
   1250   // Returns the integer value.
   1251   inline int value() const;
   1252 
   1253   // Convert a value to a Smi object.
   1254   static inline Smi* FromInt(int value);
   1255 
   1256   static inline Smi* FromIntptr(intptr_t value);
   1257 
   1258   // Returns whether value can be represented in a Smi.
   1259   static inline bool IsValid(intptr_t value);
   1260 
   1261   DECLARE_CAST(Smi)
   1262 
   1263   // Dispatched behavior.
   1264   void SmiPrint(OStream& os) const;  // NOLINT
   1265   DECLARE_VERIFIER(Smi)
   1266 
   1267   static const int kMinValue =
   1268       (static_cast<unsigned int>(-1)) << (kSmiValueSize - 1);
   1269   static const int kMaxValue = -(kMinValue + 1);
   1270 
   1271  private:
   1272   DISALLOW_IMPLICIT_CONSTRUCTORS(Smi);
   1273 };
   1274 
   1275 
   1276 // Heap objects typically have a map pointer in their first word.  However,
   1277 // during GC other data (e.g. mark bits, forwarding addresses) is sometimes
   1278 // encoded in the first word.  The class MapWord is an abstraction of the
   1279 // value in a heap object's first word.
   1280 class MapWord BASE_EMBEDDED {
   1281  public:
   1282   // Normal state: the map word contains a map pointer.
   1283 
   1284   // Create a map word from a map pointer.
   1285   static inline MapWord FromMap(const Map* map);
   1286 
   1287   // View this map word as a map pointer.
   1288   inline Map* ToMap();
   1289 
   1290 
   1291   // Scavenge collection: the map word of live objects in the from space
   1292   // contains a forwarding address (a heap object pointer in the to space).
   1293 
   1294   // True if this map word is a forwarding address for a scavenge
   1295   // collection.  Only valid during a scavenge collection (specifically,
   1296   // when all map words are heap object pointers, i.e. not during a full GC).
   1297   inline bool IsForwardingAddress();
   1298 
   1299   // Create a map word from a forwarding address.
   1300   static inline MapWord FromForwardingAddress(HeapObject* object);
   1301 
   1302   // View this map word as a forwarding address.
   1303   inline HeapObject* ToForwardingAddress();
   1304 
   1305   static inline MapWord FromRawValue(uintptr_t value) {
   1306     return MapWord(value);
   1307   }
   1308 
   1309   inline uintptr_t ToRawValue() {
   1310     return value_;
   1311   }
   1312 
   1313  private:
   1314   // HeapObject calls the private constructor and directly reads the value.
   1315   friend class HeapObject;
   1316 
   1317   explicit MapWord(uintptr_t value) : value_(value) {}
   1318 
   1319   uintptr_t value_;
   1320 };
   1321 
   1322 
   1323 // HeapObject is the superclass for all classes describing heap allocated
   1324 // objects.
   1325 class HeapObject: public Object {
   1326  public:
   1327   // [map]: Contains a map which contains the object's reflective
   1328   // information.
   1329   inline Map* map() const;
   1330   inline void set_map(Map* value);
   1331   // The no-write-barrier version.  This is OK if the object is white and in
   1332   // new space, or if the value is an immortal immutable object, like the maps
   1333   // of primitive (non-JS) objects like strings, heap numbers etc.
   1334   inline void set_map_no_write_barrier(Map* value);
   1335 
   1336   // Get the map using acquire load.
   1337   inline Map* synchronized_map();
   1338   inline MapWord synchronized_map_word() const;
   1339 
   1340   // Set the map using release store
   1341   inline void synchronized_set_map(Map* value);
   1342   inline void synchronized_set_map_no_write_barrier(Map* value);
   1343   inline void synchronized_set_map_word(MapWord map_word);
   1344 
   1345   // During garbage collection, the map word of a heap object does not
   1346   // necessarily contain a map pointer.
   1347   inline MapWord map_word() const;
   1348   inline void set_map_word(MapWord map_word);
   1349 
   1350   // The Heap the object was allocated in. Used also to access Isolate.
   1351   inline Heap* GetHeap() const;
   1352 
   1353   // Convenience method to get current isolate.
   1354   inline Isolate* GetIsolate() const;
   1355 
   1356   // Converts an address to a HeapObject pointer.
   1357   static inline HeapObject* FromAddress(Address address);
   1358 
   1359   // Returns the address of this HeapObject.
   1360   inline Address address();
   1361 
   1362   // Iterates over pointers contained in the object (including the Map)
   1363   void Iterate(ObjectVisitor* v);
   1364 
   1365   // Iterates over all pointers contained in the object except the
   1366   // first map pointer.  The object type is given in the first
   1367   // parameter. This function does not access the map pointer in the
   1368   // object, and so is safe to call while the map pointer is modified.
   1369   void IterateBody(InstanceType type, int object_size, ObjectVisitor* v);
   1370 
   1371   // Returns the heap object's size in bytes
   1372   inline int Size();
   1373 
   1374   // Returns true if this heap object may contain raw values, i.e., values that
   1375   // look like pointers to heap objects.
   1376   inline bool MayContainRawValues();
   1377 
   1378   // Given a heap object's map pointer, returns the heap size in bytes
   1379   // Useful when the map pointer field is used for other purposes.
   1380   // GC internal.
   1381   inline int SizeFromMap(Map* map);
   1382 
   1383   // Returns the field at offset in obj, as a read/write Object* reference.
   1384   // Does no checking, and is safe to use during GC, while maps are invalid.
   1385   // Does not invoke write barrier, so should only be assigned to
   1386   // during marking GC.
   1387   static inline Object** RawField(HeapObject* obj, int offset);
   1388 
   1389   // Adds the |code| object related to |name| to the code cache of this map. If
   1390   // this map is a dictionary map that is shared, the map copied and installed
   1391   // onto the object.
   1392   static void UpdateMapCodeCache(Handle<HeapObject> object,
   1393                                  Handle<Name> name,
   1394                                  Handle<Code> code);
   1395 
   1396   DECLARE_CAST(HeapObject)
   1397 
   1398   // Return the write barrier mode for this. Callers of this function
   1399   // must be able to present a reference to an DisallowHeapAllocation
   1400   // object as a sign that they are not going to use this function
   1401   // from code that allocates and thus invalidates the returned write
   1402   // barrier mode.
   1403   inline WriteBarrierMode GetWriteBarrierMode(
   1404       const DisallowHeapAllocation& promise);
   1405 
   1406   // Dispatched behavior.
   1407   void HeapObjectShortPrint(OStream& os);  // NOLINT
   1408 #ifdef OBJECT_PRINT
   1409   void PrintHeader(OStream& os, const char* id);  // NOLINT
   1410 #endif
   1411   DECLARE_PRINTER(HeapObject)
   1412   DECLARE_VERIFIER(HeapObject)
   1413 #ifdef VERIFY_HEAP
   1414   inline void VerifyObjectField(int offset);
   1415   inline void VerifySmiField(int offset);
   1416 
   1417   // Verify a pointer is a valid HeapObject pointer that points to object
   1418   // areas in the heap.
   1419   static void VerifyHeapPointer(Object* p);
   1420 #endif
   1421 
   1422   // Layout description.
   1423   // First field in a heap object is map.
   1424   static const int kMapOffset = Object::kHeaderSize;
   1425   static const int kHeaderSize = kMapOffset + kPointerSize;
   1426 
   1427   STATIC_ASSERT(kMapOffset == Internals::kHeapObjectMapOffset);
   1428 
   1429  protected:
   1430   // helpers for calling an ObjectVisitor to iterate over pointers in the
   1431   // half-open range [start, end) specified as integer offsets
   1432   inline void IteratePointers(ObjectVisitor* v, int start, int end);
   1433   // as above, for the single element at "offset"
   1434   inline void IteratePointer(ObjectVisitor* v, int offset);
   1435   // as above, for the next code link of a code object.
   1436   inline void IterateNextCodeLink(ObjectVisitor* v, int offset);
   1437 
   1438  private:
   1439   DISALLOW_IMPLICIT_CONSTRUCTORS(HeapObject);
   1440 };
   1441 
   1442 
   1443 // This class describes a body of an object of a fixed size
   1444 // in which all pointer fields are located in the [start_offset, end_offset)
   1445 // interval.
   1446 template<int start_offset, int end_offset, int size>
   1447 class FixedBodyDescriptor {
   1448  public:
   1449   static const int kStartOffset = start_offset;
   1450   static const int kEndOffset = end_offset;
   1451   static const int kSize = size;
   1452 
   1453   static inline void IterateBody(HeapObject* obj, ObjectVisitor* v);
   1454 
   1455   template<typename StaticVisitor>
   1456   static inline void IterateBody(HeapObject* obj) {
   1457     StaticVisitor::VisitPointers(HeapObject::RawField(obj, start_offset),
   1458                                  HeapObject::RawField(obj, end_offset));
   1459   }
   1460 };
   1461 
   1462 
   1463 // This class describes a body of an object of a variable size
   1464 // in which all pointer fields are located in the [start_offset, object_size)
   1465 // interval.
   1466 template<int start_offset>
   1467 class FlexibleBodyDescriptor {
   1468  public:
   1469   static const int kStartOffset = start_offset;
   1470 
   1471   static inline void IterateBody(HeapObject* obj,
   1472                                  int object_size,
   1473                                  ObjectVisitor* v);
   1474 
   1475   template<typename StaticVisitor>
   1476   static inline void IterateBody(HeapObject* obj, int object_size) {
   1477     StaticVisitor::VisitPointers(HeapObject::RawField(obj, start_offset),
   1478                                  HeapObject::RawField(obj, object_size));
   1479   }
   1480 };
   1481 
   1482 
   1483 // The HeapNumber class describes heap allocated numbers that cannot be
   1484 // represented in a Smi (small integer)
   1485 class HeapNumber: public HeapObject {
   1486  public:
   1487   // [value]: number value.
   1488   inline double value() const;
   1489   inline void set_value(double value);
   1490 
   1491   DECLARE_CAST(HeapNumber)
   1492 
   1493   // Dispatched behavior.
   1494   bool HeapNumberBooleanValue();
   1495 
   1496   void HeapNumberPrint(OStream& os);  // NOLINT
   1497   DECLARE_VERIFIER(HeapNumber)
   1498 
   1499   inline int get_exponent();
   1500   inline int get_sign();
   1501 
   1502   // Layout description.
   1503   static const int kValueOffset = HeapObject::kHeaderSize;
   1504   // IEEE doubles are two 32 bit words.  The first is just mantissa, the second
   1505   // is a mixture of sign, exponent and mantissa. The offsets of two 32 bit
   1506   // words within double numbers are endian dependent and they are set
   1507   // accordingly.
   1508 #if defined(V8_TARGET_LITTLE_ENDIAN)
   1509   static const int kMantissaOffset = kValueOffset;
   1510   static const int kExponentOffset = kValueOffset + 4;
   1511 #elif defined(V8_TARGET_BIG_ENDIAN)
   1512   static const int kMantissaOffset = kValueOffset + 4;
   1513   static const int kExponentOffset = kValueOffset;
   1514 #else
   1515 #error Unknown byte ordering
   1516 #endif
   1517 
   1518   static const int kSize = kValueOffset + kDoubleSize;
   1519   static const uint32_t kSignMask = 0x80000000u;
   1520   static const uint32_t kExponentMask = 0x7ff00000u;
   1521   static const uint32_t kMantissaMask = 0xfffffu;
   1522   static const int kMantissaBits = 52;
   1523   static const int kExponentBits = 11;
   1524   static const int kExponentBias = 1023;
   1525   static const int kExponentShift = 20;
   1526   static const int kInfinityOrNanExponent =
   1527       (kExponentMask >> kExponentShift) - kExponentBias;
   1528   static const int kMantissaBitsInTopWord = 20;
   1529   static const int kNonMantissaBitsInTopWord = 12;
   1530 
   1531  private:
   1532   DISALLOW_IMPLICIT_CONSTRUCTORS(HeapNumber);
   1533 };
   1534 
   1535 
   1536 enum EnsureElementsMode {
   1537   DONT_ALLOW_DOUBLE_ELEMENTS,
   1538   ALLOW_COPIED_DOUBLE_ELEMENTS,
   1539   ALLOW_CONVERTED_DOUBLE_ELEMENTS
   1540 };
   1541 
   1542 
   1543 // Indicates whether a property should be set or (re)defined.  Setting of a
   1544 // property causes attributes to remain unchanged, writability to be checked
   1545 // and callbacks to be called.  Defining of a property causes attributes to
   1546 // be updated and callbacks to be overridden.
   1547 enum SetPropertyMode {
   1548   SET_PROPERTY,
   1549   DEFINE_PROPERTY
   1550 };
   1551 
   1552 
   1553 // Indicator for one component of an AccessorPair.
   1554 enum AccessorComponent {
   1555   ACCESSOR_GETTER,
   1556   ACCESSOR_SETTER
   1557 };
   1558 
   1559 
   1560 // JSReceiver includes types on which properties can be defined, i.e.,
   1561 // JSObject and JSProxy.
   1562 class JSReceiver: public HeapObject {
   1563  public:
   1564   enum DeleteMode {
   1565     NORMAL_DELETION,
   1566     STRICT_DELETION,
   1567     FORCE_DELETION
   1568   };
   1569 
   1570   DECLARE_CAST(JSReceiver)
   1571 
   1572   MUST_USE_RESULT static MaybeHandle<Object> SetElement(
   1573       Handle<JSReceiver> object,
   1574       uint32_t index,
   1575       Handle<Object> value,
   1576       PropertyAttributes attributes,
   1577       StrictMode strict_mode);
   1578 
   1579   // Implementation of [[HasProperty]], ECMA-262 5th edition, section 8.12.6.
   1580   MUST_USE_RESULT static inline Maybe<bool> HasProperty(
   1581       Handle<JSReceiver> object, Handle<Name> name);
   1582   MUST_USE_RESULT static inline Maybe<bool> HasOwnProperty(Handle<JSReceiver>,
   1583                                                            Handle<Name> name);
   1584   MUST_USE_RESULT static inline Maybe<bool> HasElement(
   1585       Handle<JSReceiver> object, uint32_t index);
   1586   MUST_USE_RESULT static inline Maybe<bool> HasOwnElement(
   1587       Handle<JSReceiver> object, uint32_t index);
   1588 
   1589   // Implementation of [[Delete]], ECMA-262 5th edition, section 8.12.7.
   1590   MUST_USE_RESULT static MaybeHandle<Object> DeleteProperty(
   1591       Handle<JSReceiver> object,
   1592       Handle<Name> name,
   1593       DeleteMode mode = NORMAL_DELETION);
   1594   MUST_USE_RESULT static MaybeHandle<Object> DeleteElement(
   1595       Handle<JSReceiver> object,
   1596       uint32_t index,
   1597       DeleteMode mode = NORMAL_DELETION);
   1598 
   1599   // Tests for the fast common case for property enumeration.
   1600   bool IsSimpleEnum();
   1601 
   1602   // Returns the class name ([[Class]] property in the specification).
   1603   String* class_name();
   1604 
   1605   // Returns the constructor name (the name (possibly, inferred name) of the
   1606   // function that was used to instantiate the object).
   1607   String* constructor_name();
   1608 
   1609   MUST_USE_RESULT static inline Maybe<PropertyAttributes> GetPropertyAttributes(
   1610       Handle<JSReceiver> object, Handle<Name> name);
   1611   MUST_USE_RESULT static Maybe<PropertyAttributes> GetPropertyAttributes(
   1612       LookupIterator* it);
   1613   MUST_USE_RESULT static Maybe<PropertyAttributes> GetOwnPropertyAttributes(
   1614       Handle<JSReceiver> object, Handle<Name> name);
   1615 
   1616   MUST_USE_RESULT static inline Maybe<PropertyAttributes> GetElementAttribute(
   1617       Handle<JSReceiver> object, uint32_t index);
   1618   MUST_USE_RESULT static inline Maybe<PropertyAttributes>
   1619       GetOwnElementAttribute(Handle<JSReceiver> object, uint32_t index);
   1620 
   1621   // Return the constructor function (may be Heap::null_value()).
   1622   inline Object* GetConstructor();
   1623 
   1624   // Retrieves a permanent object identity hash code. The undefined value might
   1625   // be returned in case no hash was created yet.
   1626   inline Object* GetIdentityHash();
   1627 
   1628   // Retrieves a permanent object identity hash code. May create and store a
   1629   // hash code if needed and none exists.
   1630   inline static Handle<Smi> GetOrCreateIdentityHash(
   1631       Handle<JSReceiver> object);
   1632 
   1633   enum KeyCollectionType { OWN_ONLY, INCLUDE_PROTOS };
   1634 
   1635   // Computes the enumerable keys for a JSObject. Used for implementing
   1636   // "for (n in object) { }".
   1637   MUST_USE_RESULT static MaybeHandle<FixedArray> GetKeys(
   1638       Handle<JSReceiver> object,
   1639       KeyCollectionType type);
   1640 
   1641  private:
   1642   DISALLOW_IMPLICIT_CONSTRUCTORS(JSReceiver);
   1643 };
   1644 
   1645 // Forward declaration for JSObject::GetOrCreateHiddenPropertiesHashTable.
   1646 class ObjectHashTable;
   1647 
   1648 // Forward declaration for JSObject::Copy.
   1649 class AllocationSite;
   1650 
   1651 
   1652 // The JSObject describes real heap allocated JavaScript objects with
   1653 // properties.
   1654 // Note that the map of JSObject changes during execution to enable inline
   1655 // caching.
   1656 class JSObject: public JSReceiver {
   1657  public:
   1658   // [properties]: Backing storage for properties.
   1659   // properties is a FixedArray in the fast case and a Dictionary in the
   1660   // slow case.
   1661   DECL_ACCESSORS(properties, FixedArray)  // Get and set fast properties.
   1662   inline void initialize_properties();
   1663   inline bool HasFastProperties();
   1664   inline NameDictionary* property_dictionary();  // Gets slow properties.
   1665 
   1666   // [elements]: The elements (properties with names that are integers).
   1667   //
   1668   // Elements can be in two general modes: fast and slow. Each mode
   1669   // corrensponds to a set of object representations of elements that
   1670   // have something in common.
   1671   //
   1672   // In the fast mode elements is a FixedArray and so each element can
   1673   // be quickly accessed. This fact is used in the generated code. The
   1674   // elements array can have one of three maps in this mode:
   1675   // fixed_array_map, sloppy_arguments_elements_map or
   1676   // fixed_cow_array_map (for copy-on-write arrays). In the latter case
   1677   // the elements array may be shared by a few objects and so before
   1678   // writing to any element the array must be copied. Use
   1679   // EnsureWritableFastElements in this case.
   1680   //
   1681   // In the slow mode the elements is either a NumberDictionary, an
   1682   // ExternalArray, or a FixedArray parameter map for a (sloppy)
   1683   // arguments object.
   1684   DECL_ACCESSORS(elements, FixedArrayBase)
   1685   inline void initialize_elements();
   1686   static void ResetElements(Handle<JSObject> object);
   1687   static inline void SetMapAndElements(Handle<JSObject> object,
   1688                                        Handle<Map> map,
   1689                                        Handle<FixedArrayBase> elements);
   1690   inline ElementsKind GetElementsKind();
   1691   inline ElementsAccessor* GetElementsAccessor();
   1692   // Returns true if an object has elements of FAST_SMI_ELEMENTS ElementsKind.
   1693   inline bool HasFastSmiElements();
   1694   // Returns true if an object has elements of FAST_ELEMENTS ElementsKind.
   1695   inline bool HasFastObjectElements();
   1696   // Returns true if an object has elements of FAST_ELEMENTS or
   1697   // FAST_SMI_ONLY_ELEMENTS.
   1698   inline bool HasFastSmiOrObjectElements();
   1699   // Returns true if an object has any of the fast elements kinds.
   1700   inline bool HasFastElements();
   1701   // Returns true if an object has elements of FAST_DOUBLE_ELEMENTS
   1702   // ElementsKind.
   1703   inline bool HasFastDoubleElements();
   1704   // Returns true if an object has elements of FAST_HOLEY_*_ELEMENTS
   1705   // ElementsKind.
   1706   inline bool HasFastHoleyElements();
   1707   inline bool HasSloppyArgumentsElements();
   1708   inline bool HasDictionaryElements();
   1709 
   1710   inline bool HasExternalUint8ClampedElements();
   1711   inline bool HasExternalArrayElements();
   1712   inline bool HasExternalInt8Elements();
   1713   inline bool HasExternalUint8Elements();
   1714   inline bool HasExternalInt16Elements();
   1715   inline bool HasExternalUint16Elements();
   1716   inline bool HasExternalInt32Elements();
   1717   inline bool HasExternalUint32Elements();
   1718   inline bool HasExternalFloat32Elements();
   1719   inline bool HasExternalFloat64Elements();
   1720 
   1721   inline bool HasFixedTypedArrayElements();
   1722 
   1723   inline bool HasFixedUint8ClampedElements();
   1724   inline bool HasFixedArrayElements();
   1725   inline bool HasFixedInt8Elements();
   1726   inline bool HasFixedUint8Elements();
   1727   inline bool HasFixedInt16Elements();
   1728   inline bool HasFixedUint16Elements();
   1729   inline bool HasFixedInt32Elements();
   1730   inline bool HasFixedUint32Elements();
   1731   inline bool HasFixedFloat32Elements();
   1732   inline bool HasFixedFloat64Elements();
   1733 
   1734   bool HasFastArgumentsElements();
   1735   bool HasDictionaryArgumentsElements();
   1736   inline SeededNumberDictionary* element_dictionary();  // Gets slow elements.
   1737 
   1738   // Requires: HasFastElements().
   1739   static Handle<FixedArray> EnsureWritableFastElements(
   1740       Handle<JSObject> object);
   1741 
   1742   // Collects elements starting at index 0.
   1743   // Undefined values are placed after non-undefined values.
   1744   // Returns the number of non-undefined values.
   1745   static Handle<Object> PrepareElementsForSort(Handle<JSObject> object,
   1746                                                uint32_t limit);
   1747   // As PrepareElementsForSort, but only on objects where elements is
   1748   // a dictionary, and it will stay a dictionary.  Collates undefined and
   1749   // unexisting elements below limit from position zero of the elements.
   1750   static Handle<Object> PrepareSlowElementsForSort(Handle<JSObject> object,
   1751                                                    uint32_t limit);
   1752 
   1753   MUST_USE_RESULT static MaybeHandle<Object> SetPropertyWithInterceptor(
   1754       LookupIterator* it, Handle<Object> value);
   1755 
   1756   // SetLocalPropertyIgnoreAttributes converts callbacks to fields. We need to
   1757   // grant an exemption to ExecutableAccessor callbacks in some cases.
   1758   enum ExecutableAccessorInfoHandling {
   1759     DEFAULT_HANDLING,
   1760     DONT_FORCE_FIELD
   1761   };
   1762 
   1763   MUST_USE_RESULT static MaybeHandle<Object> SetOwnPropertyIgnoreAttributes(
   1764       Handle<JSObject> object,
   1765       Handle<Name> key,
   1766       Handle<Object> value,
   1767       PropertyAttributes attributes,
   1768       ExecutableAccessorInfoHandling handling = DEFAULT_HANDLING);
   1769 
   1770   static void AddProperty(Handle<JSObject> object, Handle<Name> key,
   1771                           Handle<Object> value, PropertyAttributes attributes);
   1772 
   1773   // Extend the receiver with a single fast property appeared first in the
   1774   // passed map. This also extends the property backing store if necessary.
   1775   static void AllocateStorageForMap(Handle<JSObject> object, Handle<Map> map);
   1776 
   1777   // Migrates the given object to a map whose field representations are the
   1778   // lowest upper bound of all known representations for that field.
   1779   static void MigrateInstance(Handle<JSObject> instance);
   1780 
   1781   // Migrates the given object only if the target map is already available,
   1782   // or returns false if such a map is not yet available.
   1783   static bool TryMigrateInstance(Handle<JSObject> instance);
   1784 
   1785   // Sets the property value in a normalized object given (key, value, details).
   1786   // Handles the special representation of JS global objects.
   1787   static void SetNormalizedProperty(Handle<JSObject> object,
   1788                                     Handle<Name> key,
   1789                                     Handle<Object> value,
   1790                                     PropertyDetails details);
   1791 
   1792   static void OptimizeAsPrototype(Handle<JSObject> object,
   1793                                   PrototypeOptimizationMode mode);
   1794   static void ReoptimizeIfPrototype(Handle<JSObject> object);
   1795 
   1796   // Retrieve interceptors.
   1797   InterceptorInfo* GetNamedInterceptor();
   1798   InterceptorInfo* GetIndexedInterceptor();
   1799 
   1800   // Used from JSReceiver.
   1801   MUST_USE_RESULT static Maybe<PropertyAttributes>
   1802       GetPropertyAttributesWithInterceptor(Handle<JSObject> holder,
   1803                                            Handle<Object> receiver,
   1804                                            Handle<Name> name);
   1805   MUST_USE_RESULT static Maybe<PropertyAttributes>
   1806       GetPropertyAttributesWithFailedAccessCheck(LookupIterator* it);
   1807   MUST_USE_RESULT static Maybe<PropertyAttributes>
   1808       GetElementAttributeWithReceiver(Handle<JSObject> object,
   1809                                       Handle<JSReceiver> receiver,
   1810                                       uint32_t index, bool check_prototype);
   1811 
   1812   // Retrieves an AccessorPair property from the given object. Might return
   1813   // undefined if the property doesn't exist or is of a different kind.
   1814   MUST_USE_RESULT static MaybeHandle<Object> GetAccessor(
   1815       Handle<JSObject> object,
   1816       Handle<Name> name,
   1817       AccessorComponent component);
   1818 
   1819   // Defines an AccessorPair property on the given object.
   1820   // TODO(mstarzinger): Rename to SetAccessor().
   1821   static MaybeHandle<Object> DefineAccessor(Handle<JSObject> object,
   1822                                             Handle<Name> name,
   1823                                             Handle<Object> getter,
   1824                                             Handle<Object> setter,
   1825                                             PropertyAttributes attributes);
   1826 
   1827   // Defines an AccessorInfo property on the given object.
   1828   MUST_USE_RESULT static MaybeHandle<Object> SetAccessor(
   1829       Handle<JSObject> object,
   1830       Handle<AccessorInfo> info);
   1831 
   1832   MUST_USE_RESULT static MaybeHandle<Object> GetPropertyWithInterceptor(
   1833       Handle<JSObject> object,
   1834       Handle<Object> receiver,
   1835       Handle<Name> name);
   1836 
   1837   // Returns true if this is an instance of an api function and has
   1838   // been modified since it was created.  May give false positives.
   1839   bool IsDirty();
   1840 
   1841   // Accessors for hidden properties object.
   1842   //
   1843   // Hidden properties are not own properties of the object itself.
   1844   // Instead they are stored in an auxiliary structure kept as an own
   1845   // property with a special name Heap::hidden_string(). But if the
   1846   // receiver is a JSGlobalProxy then the auxiliary object is a property
   1847   // of its prototype, and if it's a detached proxy, then you can't have
   1848   // hidden properties.
   1849 
   1850   // Sets a hidden property on this object. Returns this object if successful,
   1851   // undefined if called on a detached proxy.
   1852   static Handle<Object> SetHiddenProperty(Handle<JSObject> object,
   1853                                           Handle<Name> key,
   1854                                           Handle<Object> value);
   1855   // Gets the value of a hidden property with the given key. Returns the hole
   1856   // if the property doesn't exist (or if called on a detached proxy),
   1857   // otherwise returns the value set for the key.
   1858   Object* GetHiddenProperty(Handle<Name> key);
   1859   // Deletes a hidden property. Deleting a non-existing property is
   1860   // considered successful.
   1861   static void DeleteHiddenProperty(Handle<JSObject> object,
   1862                                    Handle<Name> key);
   1863   // Returns true if the object has a property with the hidden string as name.
   1864   static bool HasHiddenProperties(Handle<JSObject> object);
   1865 
   1866   static void SetIdentityHash(Handle<JSObject> object, Handle<Smi> hash);
   1867 
   1868   static inline void ValidateElements(Handle<JSObject> object);
   1869 
   1870   // Makes sure that this object can contain HeapObject as elements.
   1871   static inline void EnsureCanContainHeapObjectElements(Handle<JSObject> obj);
   1872 
   1873   // Makes sure that this object can contain the specified elements.
   1874   static inline void EnsureCanContainElements(
   1875       Handle<JSObject> object,
   1876       Object** elements,
   1877       uint32_t count,
   1878       EnsureElementsMode mode);
   1879   static inline void EnsureCanContainElements(
   1880       Handle<JSObject> object,
   1881       Handle<FixedArrayBase> elements,
   1882       uint32_t length,
   1883       EnsureElementsMode mode);
   1884   static void EnsureCanContainElements(
   1885       Handle<JSObject> object,
   1886       Arguments* arguments,
   1887       uint32_t first_arg,
   1888       uint32_t arg_count,
   1889       EnsureElementsMode mode);
   1890 
   1891   // Would we convert a fast elements array to dictionary mode given
   1892   // an access at key?
   1893   bool WouldConvertToSlowElements(Handle<Object> key);
   1894   // Do we want to keep the elements in fast case when increasing the
   1895   // capacity?
   1896   bool ShouldConvertToSlowElements(int new_capacity);
   1897   // Returns true if the backing storage for the slow-case elements of
   1898   // this object takes up nearly as much space as a fast-case backing
   1899   // storage would.  In that case the JSObject should have fast
   1900   // elements.
   1901   bool ShouldConvertToFastElements();
   1902   // Returns true if the elements of JSObject contains only values that can be
   1903   // represented in a FixedDoubleArray and has at least one value that can only
   1904   // be represented as a double and not a Smi.
   1905   bool ShouldConvertToFastDoubleElements(bool* has_smi_only_elements);
   1906 
   1907   // Computes the new capacity when expanding the elements of a JSObject.
   1908   static int NewElementsCapacity(int old_capacity) {
   1909     // (old_capacity + 50%) + 16
   1910     return old_capacity + (old_capacity >> 1) + 16;
   1911   }
   1912 
   1913   // These methods do not perform access checks!
   1914   MUST_USE_RESULT static MaybeHandle<AccessorPair> GetOwnElementAccessorPair(
   1915       Handle<JSObject> object,
   1916       uint32_t index);
   1917 
   1918   MUST_USE_RESULT static MaybeHandle<Object> SetFastElement(
   1919       Handle<JSObject> object,
   1920       uint32_t index,
   1921       Handle<Object> value,
   1922       StrictMode strict_mode,
   1923       bool check_prototype);
   1924 
   1925   MUST_USE_RESULT static MaybeHandle<Object> SetOwnElement(
   1926       Handle<JSObject> object,
   1927       uint32_t index,
   1928       Handle<Object> value,
   1929       StrictMode strict_mode);
   1930 
   1931   // Empty handle is returned if the element cannot be set to the given value.
   1932   MUST_USE_RESULT static MaybeHandle<Object> SetElement(
   1933       Handle<JSObject> object,
   1934       uint32_t index,
   1935       Handle<Object> value,
   1936       PropertyAttributes attributes,
   1937       StrictMode strict_mode,
   1938       bool check_prototype = true,
   1939       SetPropertyMode set_mode = SET_PROPERTY);
   1940 
   1941   // Returns the index'th element.
   1942   // The undefined object if index is out of bounds.
   1943   MUST_USE_RESULT static MaybeHandle<Object> GetElementWithInterceptor(
   1944       Handle<JSObject> object,
   1945       Handle<Object> receiver,
   1946       uint32_t index);
   1947 
   1948   enum SetFastElementsCapacitySmiMode {
   1949     kAllowSmiElements,
   1950     kForceSmiElements,
   1951     kDontAllowSmiElements
   1952   };
   1953 
   1954   // Replace the elements' backing store with fast elements of the given
   1955   // capacity.  Update the length for JSArrays.  Returns the new backing
   1956   // store.
   1957   static Handle<FixedArray> SetFastElementsCapacityAndLength(
   1958       Handle<JSObject> object,
   1959       int capacity,
   1960       int length,
   1961       SetFastElementsCapacitySmiMode smi_mode);
   1962   static void SetFastDoubleElementsCapacityAndLength(
   1963       Handle<JSObject> object,
   1964       int capacity,
   1965       int length);
   1966 
   1967   // Lookup interceptors are used for handling properties controlled by host
   1968   // objects.
   1969   inline bool HasNamedInterceptor();
   1970   inline bool HasIndexedInterceptor();
   1971 
   1972   // Computes the enumerable keys from interceptors. Used for debug mirrors and
   1973   // by JSReceiver::GetKeys.
   1974   MUST_USE_RESULT static MaybeHandle<JSObject> GetKeysForNamedInterceptor(
   1975       Handle<JSObject> object,
   1976       Handle<JSReceiver> receiver);
   1977   MUST_USE_RESULT static MaybeHandle<JSObject> GetKeysForIndexedInterceptor(
   1978       Handle<JSObject> object,
   1979       Handle<JSReceiver> receiver);
   1980 
   1981   // Support functions for v8 api (needed for correct interceptor behavior).
   1982   MUST_USE_RESULT static Maybe<bool> HasRealNamedProperty(
   1983       Handle<JSObject> object, Handle<Name> key);
   1984   MUST_USE_RESULT static Maybe<bool> HasRealElementProperty(
   1985       Handle<JSObject> object, uint32_t index);
   1986   MUST_USE_RESULT static Maybe<bool> HasRealNamedCallbackProperty(
   1987       Handle<JSObject> object, Handle<Name> key);
   1988 
   1989   // Get the header size for a JSObject.  Used to compute the index of
   1990   // internal fields as well as the number of internal fields.
   1991   inline int GetHeaderSize();
   1992 
   1993   inline int GetInternalFieldCount();
   1994   inline int GetInternalFieldOffset(int index);
   1995   inline Object* GetInternalField(int index);
   1996   inline void SetInternalField(int index, Object* value);
   1997   inline void SetInternalField(int index, Smi* value);
   1998 
   1999   // Returns the number of properties on this object filtering out properties
   2000   // with the specified attributes (ignoring interceptors).
   2001   int NumberOfOwnProperties(PropertyAttributes filter = NONE);
   2002   // Fill in details for properties into storage starting at the specified
   2003   // index.
   2004   void GetOwnPropertyNames(
   2005       FixedArray* storage, int index, PropertyAttributes filter = NONE);
   2006 
   2007   // Returns the number of properties on this object filtering out properties
   2008   // with the specified attributes (ignoring interceptors).
   2009   int NumberOfOwnElements(PropertyAttributes filter);
   2010   // Returns the number of enumerable elements (ignoring interceptors).
   2011   int NumberOfEnumElements();
   2012   // Returns the number of elements on this object filtering out elements
   2013   // with the specified attributes (ignoring interceptors).
   2014   int GetOwnElementKeys(FixedArray* storage, PropertyAttributes filter);
   2015   // Count and fill in the enumerable elements into storage.
   2016   // (storage->length() == NumberOfEnumElements()).
   2017   // If storage is NULL, will count the elements without adding
   2018   // them to any storage.
   2019   // Returns the number of enumerable elements.
   2020   int GetEnumElementKeys(FixedArray* storage);
   2021 
   2022   // Returns a new map with all transitions dropped from the object's current
   2023   // map and the ElementsKind set.
   2024   static Handle<Map> GetElementsTransitionMap(Handle<JSObject> object,
   2025                                               ElementsKind to_kind);
   2026   static void TransitionElementsKind(Handle<JSObject> object,
   2027                                      ElementsKind to_kind);
   2028 
   2029   static void MigrateToMap(Handle<JSObject> object, Handle<Map> new_map);
   2030 
   2031   // Convert the object to use the canonical dictionary
   2032   // representation. If the object is expected to have additional properties
   2033   // added this number can be indicated to have the backing store allocated to
   2034   // an initial capacity for holding these properties.
   2035   static void NormalizeProperties(Handle<JSObject> object,
   2036                                   PropertyNormalizationMode mode,
   2037                                   int expected_additional_properties);
   2038 
   2039   // Convert and update the elements backing store to be a
   2040   // SeededNumberDictionary dictionary.  Returns the backing after conversion.
   2041   static Handle<SeededNumberDictionary> NormalizeElements(
   2042       Handle<JSObject> object);
   2043 
   2044   // Transform slow named properties to fast variants.
   2045   static void MigrateSlowToFast(Handle<JSObject> object,
   2046                                 int unused_property_fields);
   2047 
   2048   // Access fast-case object properties at index.
   2049   static Handle<Object> FastPropertyAt(Handle<JSObject> object,
   2050                                        Representation representation,
   2051                                        FieldIndex index);
   2052   inline Object* RawFastPropertyAt(FieldIndex index);
   2053   inline void FastPropertyAtPut(FieldIndex index, Object* value);
   2054   void WriteToField(int descriptor, Object* value);
   2055 
   2056   // Access to in object properties.
   2057   inline int GetInObjectPropertyOffset(int index);
   2058   inline Object* InObjectPropertyAt(int index);
   2059   inline Object* InObjectPropertyAtPut(int index,
   2060                                        Object* value,
   2061                                        WriteBarrierMode mode
   2062                                        = UPDATE_WRITE_BARRIER);
   2063 
   2064   // Set the object's prototype (only JSReceiver and null are allowed values).
   2065   MUST_USE_RESULT static MaybeHandle<Object> SetPrototype(
   2066       Handle<JSObject> object, Handle<Object> value, bool from_javascript);
   2067 
   2068   // Initializes the body after properties slot, properties slot is
   2069   // initialized by set_properties.  Fill the pre-allocated fields with
   2070   // pre_allocated_value and the rest with filler_value.
   2071   // Note: this call does not update write barrier, the caller is responsible
   2072   // to ensure that |filler_value| can be collected without WB here.
   2073   inline void InitializeBody(Map* map,
   2074                              Object* pre_allocated_value,
   2075                              Object* filler_value);
   2076 
   2077   // Check whether this object references another object
   2078   bool ReferencesObject(Object* obj);
   2079 
   2080   // Disalow further properties to be added to the object.
   2081   MUST_USE_RESULT static MaybeHandle<Object> PreventExtensions(
   2082       Handle<JSObject> object);
   2083 
   2084   // ES5 Object.freeze
   2085   MUST_USE_RESULT static MaybeHandle<Object> Freeze(Handle<JSObject> object);
   2086 
   2087   // Called the first time an object is observed with ES7 Object.observe.
   2088   static void SetObserved(Handle<JSObject> object);
   2089 
   2090   // Copy object.
   2091   enum DeepCopyHints { kNoHints = 0, kObjectIsShallow = 1 };
   2092 
   2093   static Handle<JSObject> Copy(Handle<JSObject> object);
   2094   MUST_USE_RESULT static MaybeHandle<JSObject> DeepCopy(
   2095       Handle<JSObject> object,
   2096       AllocationSiteUsageContext* site_context,
   2097       DeepCopyHints hints = kNoHints);
   2098   MUST_USE_RESULT static MaybeHandle<JSObject> DeepWalk(
   2099       Handle<JSObject> object,
   2100       AllocationSiteCreationContext* site_context);
   2101 
   2102   static Handle<Object> GetDataProperty(Handle<JSObject> object,
   2103                                         Handle<Name> key);
   2104   static Handle<Object> GetDataProperty(LookupIterator* it);
   2105 
   2106   DECLARE_CAST(JSObject)
   2107 
   2108   // Dispatched behavior.
   2109   void JSObjectShortPrint(StringStream* accumulator);
   2110   DECLARE_PRINTER(JSObject)
   2111   DECLARE_VERIFIER(JSObject)
   2112 #ifdef OBJECT_PRINT
   2113   void PrintProperties(OStream& os);   // NOLINT
   2114   void PrintElements(OStream& os);     // NOLINT
   2115   void PrintTransitions(OStream& os);  // NOLINT
   2116 #endif
   2117 
   2118   static void PrintElementsTransition(
   2119       FILE* file, Handle<JSObject> object,
   2120       ElementsKind from_kind, Handle<FixedArrayBase> from_elements,
   2121       ElementsKind to_kind, Handle<FixedArrayBase> to_elements);
   2122 
   2123   void PrintInstanceMigration(FILE* file, Map* original_map, Map* new_map);
   2124 
   2125 #ifdef DEBUG
   2126   // Structure for collecting spill information about JSObjects.
   2127   class SpillInformation {
   2128    public:
   2129     void Clear();
   2130     void Print();
   2131     int number_of_objects_;
   2132     int number_of_objects_with_fast_properties_;
   2133     int number_of_objects_with_fast_elements_;
   2134     int number_of_fast_used_fields_;
   2135     int number_of_fast_unused_fields_;
   2136     int number_of_slow_used_properties_;
   2137     int number_of_slow_unused_properties_;
   2138     int number_of_fast_used_elements_;
   2139     int number_of_fast_unused_elements_;
   2140     int number_of_slow_used_elements_;
   2141     int number_of_slow_unused_elements_;
   2142   };
   2143 
   2144   void IncrementSpillStatistics(SpillInformation* info);
   2145 #endif
   2146 
   2147 #ifdef VERIFY_HEAP
   2148   // If a GC was caused while constructing this object, the elements pointer
   2149   // may point to a one pointer filler map. The object won't be rooted, but
   2150   // our heap verification code could stumble across it.
   2151   bool ElementsAreSafeToExamine();
   2152 #endif
   2153 
   2154   Object* SlowReverseLookup(Object* value);
   2155 
   2156   // Maximal number of elements (numbered 0 .. kMaxElementCount - 1).
   2157   // Also maximal value of JSArray's length property.
   2158   static const uint32_t kMaxElementCount = 0xffffffffu;
   2159 
   2160   // Constants for heuristics controlling conversion of fast elements
   2161   // to slow elements.
   2162 
   2163   // Maximal gap that can be introduced by adding an element beyond
   2164   // the current elements length.
   2165   static const uint32_t kMaxGap = 1024;
   2166 
   2167   // Maximal length of fast elements array that won't be checked for
   2168   // being dense enough on expansion.
   2169   static const int kMaxUncheckedFastElementsLength = 5000;
   2170 
   2171   // Same as above but for old arrays. This limit is more strict. We
   2172   // don't want to be wasteful with long lived objects.
   2173   static const int kMaxUncheckedOldFastElementsLength = 500;
   2174 
   2175   // Note that Page::kMaxRegularHeapObjectSize puts a limit on
   2176   // permissible values (see the DCHECK in heap.cc).
   2177   static const int kInitialMaxFastElementArray = 100000;
   2178 
   2179   // This constant applies only to the initial map of "$Object" aka
   2180   // "global.Object" and not to arbitrary other JSObject maps.
   2181   static const int kInitialGlobalObjectUnusedPropertiesCount = 4;
   2182 
   2183   static const int kMaxInstanceSize = 255 * kPointerSize;
   2184   // When extending the backing storage for property values, we increase
   2185   // its size by more than the 1 entry necessary, so sequentially adding fields
   2186   // to the same object requires fewer allocations and copies.
   2187   static const int kFieldsAdded = 3;
   2188 
   2189   // Layout description.
   2190   static const int kPropertiesOffset = HeapObject::kHeaderSize;
   2191   static const int kElementsOffset = kPropertiesOffset + kPointerSize;
   2192   static const int kHeaderSize = kElementsOffset + kPointerSize;
   2193 
   2194   STATIC_ASSERT(kHeaderSize == Internals::kJSObjectHeaderSize);
   2195 
   2196   class BodyDescriptor : public FlexibleBodyDescriptor<kPropertiesOffset> {
   2197    public:
   2198     static inline int SizeOf(Map* map, HeapObject* object);
   2199   };
   2200 
   2201   Context* GetCreationContext();
   2202 
   2203   // Enqueue change record for Object.observe. May cause GC.
   2204   static void EnqueueChangeRecord(Handle<JSObject> object,
   2205                                   const char* type,
   2206                                   Handle<Name> name,
   2207                                   Handle<Object> old_value);
   2208 
   2209   static void MigrateToNewProperty(Handle<JSObject> object,
   2210                                    Handle<Map> transition,
   2211                                    Handle<Object> value);
   2212 
   2213  private:
   2214   friend class DictionaryElementsAccessor;
   2215   friend class JSReceiver;
   2216   friend class Object;
   2217 
   2218   static void MigrateFastToFast(Handle<JSObject> object, Handle<Map> new_map);
   2219   static void MigrateFastToSlow(Handle<JSObject> object,
   2220                                 Handle<Map> new_map,
   2221                                 int expected_additional_properties);
   2222 
   2223   static void GeneralizeFieldRepresentation(Handle<JSObject> object,
   2224                                             int modify_index,
   2225                                             Representation new_representation,
   2226                                             Handle<HeapType> new_field_type);
   2227 
   2228   static void UpdateAllocationSite(Handle<JSObject> object,
   2229                                    ElementsKind to_kind);
   2230 
   2231   // Used from Object::GetProperty().
   2232   MUST_USE_RESULT static MaybeHandle<Object> GetPropertyWithFailedAccessCheck(
   2233       LookupIterator* it);
   2234 
   2235   MUST_USE_RESULT static MaybeHandle<Object> GetElementWithCallback(
   2236       Handle<JSObject> object,
   2237       Handle<Object> receiver,
   2238       Handle<Object> structure,
   2239       uint32_t index,
   2240       Handle<Object> holder);
   2241 
   2242   MUST_USE_RESULT static Maybe<PropertyAttributes>
   2243       GetElementAttributeWithInterceptor(Handle<JSObject> object,
   2244                                          Handle<JSReceiver> receiver,
   2245                                          uint32_t index, bool continue_search);
   2246   MUST_USE_RESULT static Maybe<PropertyAttributes>
   2247       GetElementAttributeWithoutInterceptor(Handle<JSObject> object,
   2248                                             Handle<JSReceiver> receiver,
   2249                                             uint32_t index,
   2250                                             bool continue_search);
   2251   MUST_USE_RESULT static MaybeHandle<Object> SetElementWithCallback(
   2252       Handle<JSObject> object,
   2253       Handle<Object> structure,
   2254       uint32_t index,
   2255       Handle<Object> value,
   2256       Handle<JSObject> holder,
   2257       StrictMode strict_mode);
   2258   MUST_USE_RESULT static MaybeHandle<Object> SetElementWithInterceptor(
   2259       Handle<JSObject> object,
   2260       uint32_t index,
   2261       Handle<Object> value,
   2262       PropertyAttributes attributes,
   2263       StrictMode strict_mode,
   2264       bool check_prototype,
   2265       SetPropertyMode set_mode);
   2266   MUST_USE_RESULT static MaybeHandle<Object> SetElementWithoutInterceptor(
   2267       Handle<JSObject> object,
   2268       uint32_t index,
   2269       Handle<Object> value,
   2270       PropertyAttributes attributes,
   2271       StrictMode strict_mode,
   2272       bool check_prototype,
   2273       SetPropertyMode set_mode);
   2274   MUST_USE_RESULT
   2275   static MaybeHandle<Object> SetElementWithCallbackSetterInPrototypes(
   2276       Handle<JSObject> object,
   2277       uint32_t index,
   2278       Handle<Object> value,
   2279       bool* found,
   2280       StrictMode strict_mode);
   2281   MUST_USE_RESULT static MaybeHandle<Object> SetDictionaryElement(
   2282       Handle<JSObject> object,
   2283       uint32_t index,
   2284       Handle<Object> value,
   2285       PropertyAttributes attributes,
   2286       StrictMode strict_mode,
   2287       bool check_prototype,
   2288       SetPropertyMode set_mode = SET_PROPERTY);
   2289   MUST_USE_RESULT static MaybeHandle<Object> SetFastDoubleElement(
   2290       Handle<JSObject> object,
   2291       uint32_t index,
   2292       Handle<Object> value,
   2293       StrictMode strict_mode,
   2294       bool check_prototype = true);
   2295 
   2296   MUST_USE_RESULT static MaybeHandle<Object> SetPropertyWithFailedAccessCheck(
   2297       LookupIterator* it, Handle<Object> value, StrictMode strict_mode);
   2298 
   2299   // Add a property to a slow-case object.
   2300   static void AddSlowProperty(Handle<JSObject> object,
   2301                               Handle<Name> name,
   2302                               Handle<Object> value,
   2303                               PropertyAttributes attributes);
   2304 
   2305   MUST_USE_RESULT static MaybeHandle<Object> DeleteProperty(
   2306       Handle<JSObject> object,
   2307       Handle<Name> name,
   2308       DeleteMode mode);
   2309   MUST_USE_RESULT static MaybeHandle<Object> DeletePropertyWithInterceptor(
   2310       Handle<JSObject> holder, Handle<JSObject> receiver, Handle<Name> name);
   2311 
   2312   // Deletes the named property in a normalized object.
   2313   static Handle<Object> DeleteNormalizedProperty(Handle<JSObject> object,
   2314                                                  Handle<Name> name,
   2315                                                  DeleteMode mode);
   2316 
   2317   MUST_USE_RESULT static MaybeHandle<Object> DeleteElement(
   2318       Handle<JSObject> object,
   2319       uint32_t index,
   2320       DeleteMode mode);
   2321   MUST_USE_RESULT static MaybeHandle<Object> DeleteElementWithInterceptor(
   2322       Handle<JSObject> object,
   2323       uint32_t index);
   2324 
   2325   bool ReferencesObjectFromElements(FixedArray* elements,
   2326                                     ElementsKind kind,
   2327                                     Object* object);
   2328 
   2329   // Returns true if most of the elements backing storage is used.
   2330   bool HasDenseElements();
   2331 
   2332   // Gets the current elements capacity and the number of used elements.
   2333   void GetElementsCapacityAndUsage(int* capacity, int* used);
   2334 
   2335   static bool CanSetCallback(Handle<JSObject> object, Handle<Name> name);
   2336   static void SetElementCallback(Handle<JSObject> object,
   2337                                  uint32_t index,
   2338                                  Handle<Object> structure,
   2339                                  PropertyAttributes attributes);
   2340   static void SetPropertyCallback(Handle<JSObject> object,
   2341                                   Handle<Name> name,
   2342                                   Handle<Object> structure,
   2343                                   PropertyAttributes attributes);
   2344   static void DefineElementAccessor(Handle<JSObject> object,
   2345                                     uint32_t index,
   2346                                     Handle<Object> getter,
   2347                                     Handle<Object> setter,
   2348                                     PropertyAttributes attributes);
   2349 
   2350   // Return the hash table backing store or the inline stored identity hash,
   2351   // whatever is found.
   2352   MUST_USE_RESULT Object* GetHiddenPropertiesHashTable();
   2353 
   2354   // Return the hash table backing store for hidden properties.  If there is no
   2355   // backing store, allocate one.
   2356   static Handle<ObjectHashTable> GetOrCreateHiddenPropertiesHashtable(
   2357       Handle<JSObject> object);
   2358 
   2359   // Set the hidden property backing store to either a hash table or
   2360   // the inline-stored identity hash.
   2361   static Handle<Object> SetHiddenPropertiesHashTable(
   2362       Handle<JSObject> object,
   2363       Handle<Object> value);
   2364 
   2365   MUST_USE_RESULT Object* GetIdentityHash();
   2366 
   2367   static Handle<Smi> GetOrCreateIdentityHash(Handle<JSObject> object);
   2368 
   2369   DISALLOW_IMPLICIT_CONSTRUCTORS(JSObject);
   2370 };
   2371 
   2372 
   2373 // Common superclass for FixedArrays that allow implementations to share
   2374 // common accessors and some code paths.
   2375 class FixedArrayBase: public HeapObject {
   2376  public:
   2377   // [length]: length of the array.
   2378   inline int length() const;
   2379   inline void set_length(int value);
   2380 
   2381   // Get and set the length using acquire loads and release stores.
   2382   inline int synchronized_length() const;
   2383   inline void synchronized_set_length(int value);
   2384 
   2385   DECLARE_CAST(FixedArrayBase)
   2386 
   2387   // Layout description.
   2388   // Length is smi tagged when it is stored.
   2389   static const int kLengthOffset = HeapObject::kHeaderSize;
   2390   static const int kHeaderSize = kLengthOffset + kPointerSize;
   2391 };
   2392 
   2393 
   2394 class FixedDoubleArray;
   2395 class IncrementalMarking;
   2396 
   2397 
   2398 // FixedArray describes fixed-sized arrays with element type Object*.
   2399 class FixedArray: public FixedArrayBase {
   2400  public:
   2401   // Setter and getter for elements.
   2402   inline Object* get(int index);
   2403   static inline Handle<Object> get(Handle<FixedArray> array, int index);
   2404   // Setter that uses write barrier.
   2405   inline void set(int index, Object* value);
   2406   inline bool is_the_hole(int index);
   2407 
   2408   // Setter that doesn't need write barrier.
   2409   inline void set(int index, Smi* value);
   2410   // Setter with explicit barrier mode.
   2411   inline void set(int index, Object* value, WriteBarrierMode mode);
   2412 
   2413   // Setters for frequently used oddballs located in old space.
   2414   inline void set_undefined(int index);
   2415   inline void set_null(int index);
   2416   inline void set_the_hole(int index);
   2417 
   2418   inline Object** GetFirstElementAddress();
   2419   inline bool ContainsOnlySmisOrHoles();
   2420 
   2421   // Gives access to raw memory which stores the array's data.
   2422   inline Object** data_start();
   2423 
   2424   inline void FillWithHoles(int from, int to);
   2425 
   2426   // Shrink length and insert filler objects.
   2427   void Shrink(int length);
   2428 
   2429   // Copy operation.
   2430   static Handle<FixedArray> CopySize(Handle<FixedArray> array,
   2431                                      int new_length,
   2432                                      PretenureFlag pretenure = NOT_TENURED);
   2433 
   2434   // Add the elements of a JSArray to this FixedArray.
   2435   MUST_USE_RESULT static MaybeHandle<FixedArray> AddKeysFromArrayLike(
   2436       Handle<FixedArray> content,
   2437       Handle<JSObject> array);
   2438 
   2439   // Computes the union of keys and return the result.
   2440   // Used for implementing "for (n in object) { }"
   2441   MUST_USE_RESULT static MaybeHandle<FixedArray> UnionOfKeys(
   2442       Handle<FixedArray> first,
   2443       Handle<FixedArray> second);
   2444 
   2445   // Copy a sub array from the receiver to dest.
   2446   void CopyTo(int pos, FixedArray* dest, int dest_pos, int len);
   2447 
   2448   // Garbage collection support.
   2449   static int SizeFor(int length) { return kHeaderSize + length * kPointerSize; }
   2450 
   2451   // Code Generation support.
   2452   static int OffsetOfElementAt(int index) { return SizeFor(index); }
   2453 
   2454   // Garbage collection support.
   2455   Object** RawFieldOfElementAt(int index) {
   2456     return HeapObject::RawField(this, OffsetOfElementAt(index));
   2457   }
   2458 
   2459   DECLARE_CAST(FixedArray)
   2460 
   2461   // Maximal allowed size, in bytes, of a single FixedArray.
   2462   // Prevents overflowing size computations, as well as extreme memory
   2463   // consumption.
   2464   static const int kMaxSize = 128 * MB * kPointerSize;
   2465   // Maximally allowed length of a FixedArray.
   2466   static const int kMaxLength = (kMaxSize - kHeaderSize) / kPointerSize;
   2467 
   2468   // Dispatched behavior.
   2469   DECLARE_PRINTER(FixedArray)
   2470   DECLARE_VERIFIER(FixedArray)
   2471 #ifdef DEBUG
   2472   // Checks if two FixedArrays have identical contents.
   2473   bool IsEqualTo(FixedArray* other);
   2474 #endif
   2475 
   2476   // Swap two elements in a pair of arrays.  If this array and the
   2477   // numbers array are the same object, the elements are only swapped
   2478   // once.
   2479   void SwapPairs(FixedArray* numbers, int i, int j);
   2480 
   2481   // Sort prefix of this array and the numbers array as pairs wrt. the
   2482   // numbers.  If the numbers array and the this array are the same
   2483   // object, the prefix of this array is sorted.
   2484   void SortPairs(FixedArray* numbers, uint32_t len);
   2485 
   2486   class BodyDescriptor : public FlexibleBodyDescriptor<kHeaderSize> {
   2487    public:
   2488     static inline int SizeOf(Map* map, HeapObject* object) {
   2489       return SizeFor(reinterpret_cast<FixedArray*>(object)->length());
   2490     }
   2491   };
   2492 
   2493  protected:
   2494   // Set operation on FixedArray without using write barriers. Can
   2495   // only be used for storing old space objects or smis.
   2496   static inline void NoWriteBarrierSet(FixedArray* array,
   2497                                        int index,
   2498                                        Object* value);
   2499 
   2500   // Set operation on FixedArray without incremental write barrier. Can
   2501   // only be used if the object is guaranteed to be white (whiteness witness
   2502   // is present).
   2503   static inline void NoIncrementalWriteBarrierSet(FixedArray* array,
   2504                                                   int index,
   2505                                                   Object* value);
   2506 
   2507  private:
   2508   STATIC_ASSERT(kHeaderSize == Internals::kFixedArrayHeaderSize);
   2509 
   2510   DISALLOW_IMPLICIT_CONSTRUCTORS(FixedArray);
   2511 };
   2512 
   2513 
   2514 // FixedDoubleArray describes fixed-sized arrays with element type double.
   2515 class FixedDoubleArray: public FixedArrayBase {
   2516  public:
   2517   // Setter and getter for elements.
   2518   inline double get_scalar(int index);
   2519   inline int64_t get_representation(int index);
   2520   static inline Handle<Object> get(Handle<FixedDoubleArray> array, int index);
   2521   inline void set(int index, double value);
   2522   inline void set_the_hole(int index);
   2523 
   2524   // Checking for the hole.
   2525   inline bool is_the_hole(int index);
   2526 
   2527   // Garbage collection support.
   2528   inline static int SizeFor(int length) {
   2529     return kHeaderSize + length * kDoubleSize;
   2530   }
   2531 
   2532   // Gives access to raw memory which stores the array's data.
   2533   inline double* data_start();
   2534 
   2535   inline void FillWithHoles(int from, int to);
   2536 
   2537   // Code Generation support.
   2538   static int OffsetOfElementAt(int index) { return SizeFor(index); }
   2539 
   2540   inline static bool is_the_hole_nan(double value);
   2541   inline static double hole_nan_as_double();
   2542   inline static double canonical_not_the_hole_nan_as_double();
   2543 
   2544   DECLARE_CAST(FixedDoubleArray)
   2545 
   2546   // Maximal allowed size, in bytes, of a single FixedDoubleArray.
   2547   // Prevents overflowing size computations, as well as extreme memory
   2548   // consumption.
   2549   static const int kMaxSize = 512 * MB;
   2550   // Maximally allowed length of a FixedArray.
   2551   static const int kMaxLength = (kMaxSize - kHeaderSize) / kDoubleSize;
   2552 
   2553   // Dispatched behavior.
   2554   DECLARE_PRINTER(FixedDoubleArray)
   2555   DECLARE_VERIFIER(FixedDoubleArray)
   2556 
   2557  private:
   2558   DISALLOW_IMPLICIT_CONSTRUCTORS(FixedDoubleArray);
   2559 };
   2560 
   2561 
   2562 // ConstantPoolArray describes a fixed-sized array containing constant pool
   2563 // entries.
   2564 //
   2565 // A ConstantPoolArray can be structured in two different ways depending upon
   2566 // whether it is extended or small. The is_extended_layout() method can be used
   2567 // to discover which layout the constant pool has.
   2568 //
   2569 // The format of a small constant pool is:
   2570 //   [kSmallLayout1Offset]                    : Small section layout bitmap 1
   2571 //   [kSmallLayout2Offset]                    : Small section layout bitmap 2
   2572 //   [first_index(INT64, SMALL_SECTION)]      : 64 bit entries
   2573 //    ...                                     :  ...
   2574 //   [first_index(CODE_PTR, SMALL_SECTION)]   : code pointer entries
   2575 //    ...                                     :  ...
   2576 //   [first_index(HEAP_PTR, SMALL_SECTION)]   : heap pointer entries
   2577 //    ...                                     :  ...
   2578 //   [first_index(INT32, SMALL_SECTION)]      : 32 bit entries
   2579 //    ...                                     :  ...
   2580 //
   2581 // If the constant pool has an extended layout, the extended section constant
   2582 // pool also contains an extended section, which has the following format at
   2583 // location get_extended_section_header_offset():
   2584 //   [kExtendedInt64CountOffset]              : count of extended 64 bit entries
   2585 //   [kExtendedCodePtrCountOffset]            : count of extended code pointers
   2586 //   [kExtendedHeapPtrCountOffset]            : count of extended heap pointers
   2587 //   [kExtendedInt32CountOffset]              : count of extended 32 bit entries
   2588 //   [first_index(INT64, EXTENDED_SECTION)]   : 64 bit entries
   2589 //    ...                                     :  ...
   2590 //   [first_index(CODE_PTR, EXTENDED_SECTION)]: code pointer entries
   2591 //    ...                                     :  ...
   2592 //   [first_index(HEAP_PTR, EXTENDED_SECTION)]: heap pointer entries
   2593 //    ...                                     :  ...
   2594 //   [first_index(INT32, EXTENDED_SECTION)]   : 32 bit entries
   2595 //    ...                                     :  ...
   2596 //
   2597 class ConstantPoolArray: public HeapObject {
   2598  public:
   2599   enum WeakObjectState {
   2600     NO_WEAK_OBJECTS,
   2601     WEAK_OBJECTS_IN_OPTIMIZED_CODE,
   2602     WEAK_OBJECTS_IN_IC
   2603   };
   2604 
   2605   enum Type {
   2606     INT64 = 0,
   2607     CODE_PTR,
   2608     HEAP_PTR,
   2609     INT32,
   2610     // Number of types stored by the ConstantPoolArrays.
   2611     NUMBER_OF_TYPES,
   2612     FIRST_TYPE = INT64,
   2613     LAST_TYPE = INT32
   2614   };
   2615 
   2616   enum LayoutSection {
   2617     SMALL_SECTION = 0,
   2618     EXTENDED_SECTION,
   2619     NUMBER_OF_LAYOUT_SECTIONS
   2620   };
   2621 
   2622   class NumberOfEntries BASE_EMBEDDED {
   2623    public:
   2624     inline NumberOfEntries() {
   2625       for (int i = 0; i < NUMBER_OF_TYPES; i++) {
   2626         element_counts_[i] = 0;
   2627       }
   2628     }
   2629 
   2630     inline NumberOfEntries(int int64_count, int code_ptr_count,
   2631                            int heap_ptr_count, int int32_count) {
   2632       element_counts_[INT64] = int64_count;
   2633       element_counts_[CODE_PTR] = code_ptr_count;
   2634       element_counts_[HEAP_PTR] = heap_ptr_count;
   2635       element_counts_[INT32] = int32_count;
   2636     }
   2637 
   2638     inline NumberOfEntries(ConstantPoolArray* array, LayoutSection section) {
   2639       element_counts_[INT64] = array->number_of_entries(INT64, section);
   2640       element_counts_[CODE_PTR] = array->number_of_entries(CODE_PTR, section);
   2641       element_counts_[HEAP_PTR] = array->number_of_entries(HEAP_PTR, section);
   2642       element_counts_[INT32] = array->number_of_entries(INT32, section);
   2643     }
   2644 
   2645     inline void increment(Type type);
   2646     inline int equals(const NumberOfEntries& other) const;
   2647     inline bool is_empty() const;
   2648     inline int count_of(Type type) const;
   2649     inline int base_of(Type type) const;
   2650     inline int total_count() const;
   2651     inline int are_in_range(int min, int max) const;
   2652 
   2653    private:
   2654     int element_counts_[NUMBER_OF_TYPES];
   2655   };
   2656 
   2657   class Iterator BASE_EMBEDDED {
   2658    public:
   2659     inline Iterator(ConstantPoolArray* array, Type type)
   2660         : array_(array),
   2661           type_(type),
   2662           final_section_(array->final_section()),
   2663           current_section_(SMALL_SECTION),
   2664           next_index_(array->first_index(type, SMALL_SECTION)) {
   2665       update_section();
   2666     }
   2667 
   2668     inline Iterator(ConstantPoolArray* array, Type type, LayoutSection section)
   2669         : array_(array),
   2670           type_(type),
   2671           final_section_(section),
   2672           current_section_(section),
   2673           next_index_(array->first_index(type, section)) {
   2674       update_section();
   2675     }
   2676 
   2677     inline int next_index();
   2678     inline bool is_finished();
   2679 
   2680    private:
   2681     inline void update_section();
   2682     ConstantPoolArray* array_;
   2683     const Type type_;
   2684     const LayoutSection final_section_;
   2685 
   2686     LayoutSection current_section_;
   2687     int next_index_;
   2688   };
   2689 
   2690   // Getters for the first index, the last index and the count of entries of
   2691   // a given type for a given layout section.
   2692   inline int first_index(Type type, LayoutSection layout_section);
   2693   inline int last_index(Type type, LayoutSection layout_section);
   2694   inline int number_of_entries(Type type, LayoutSection layout_section);
   2695 
   2696   // Returns the type of the entry at the given index.
   2697   inline Type get_type(int index);
   2698   inline bool offset_is_type(int offset, Type type);
   2699 
   2700   // Setter and getter for pool elements.
   2701   inline Address get_code_ptr_entry(int index);
   2702   inline Object* get_heap_ptr_entry(int index);
   2703   inline int64_t get_int64_entry(int index);
   2704   inline int32_t get_int32_entry(int index);
   2705   inline double get_int64_entry_as_double(int index);
   2706 
   2707   inline void set(int index, Address value);
   2708   inline void set(int index, Object* value);
   2709   inline void set(int index, int64_t value);
   2710   inline void set(int index, double value);
   2711   inline void set(int index, int32_t value);
   2712 
   2713   // Setters which take a raw offset rather than an index (for code generation).
   2714   inline void set_at_offset(int offset, int32_t value);
   2715   inline void set_at_offset(int offset, int64_t value);
   2716   inline void set_at_offset(int offset, double value);
   2717   inline void set_at_offset(int offset, Address value);
   2718   inline void set_at_offset(int offset, Object* value);
   2719 
   2720   // Setter and getter for weak objects state
   2721   inline void set_weak_object_state(WeakObjectState state);
   2722   inline WeakObjectState get_weak_object_state();
   2723 
   2724   // Returns true if the constant pool has an extended layout, false if it has
   2725   // only the small layout.
   2726   inline bool is_extended_layout();
   2727 
   2728   // Returns the last LayoutSection in this constant pool array.
   2729   inline LayoutSection final_section();
   2730 
   2731   // Set up initial state for a small layout constant pool array.
   2732   inline void Init(const NumberOfEntries& small);
   2733 
   2734   // Set up initial state for an extended layout constant pool array.
   2735   inline void InitExtended(const NumberOfEntries& small,
   2736                            const NumberOfEntries& extended);
   2737 
   2738   // Clears the pointer entries with GC safe values.
   2739   void ClearPtrEntries(Isolate* isolate);
   2740 
   2741   // returns the total number of entries in the constant pool array.
   2742   inline int length();
   2743 
   2744   // Garbage collection support.
   2745   inline int size();
   2746 
   2747 
   2748   inline static int MaxInt64Offset(int number_of_int64) {
   2749     return kFirstEntryOffset + (number_of_int64 * kInt64Size);
   2750   }
   2751 
   2752   inline static int SizeFor(const NumberOfEntries& small) {
   2753     int size = kFirstEntryOffset +
   2754         (small.count_of(INT64)  * kInt64Size) +
   2755         (small.count_of(CODE_PTR) * kPointerSize) +
   2756         (small.count_of(HEAP_PTR) * kPointerSize) +
   2757         (small.count_of(INT32) * kInt32Size);
   2758     return RoundUp(size, kPointerSize);
   2759   }
   2760 
   2761   inline static int SizeForExtended(const NumberOfEntries& small,
   2762                                     const NumberOfEntries& extended) {
   2763     int size = SizeFor(small);
   2764     size = RoundUp(size, kInt64Size);  // Align extended header to 64 bits.
   2765     size += kExtendedFirstOffset +
   2766         (extended.count_of(INT64) * kInt64Size) +
   2767         (extended.count_of(CODE_PTR) * kPointerSize) +
   2768         (extended.count_of(HEAP_PTR) * kPointerSize) +
   2769         (extended.count_of(INT32) * kInt32Size);
   2770     return RoundUp(size, kPointerSize);
   2771   }
   2772 
   2773   inline static int entry_size(Type type) {
   2774     switch (type) {
   2775       case INT32:
   2776         return kInt32Size;
   2777       case INT64:
   2778         return kInt64Size;
   2779       case CODE_PTR:
   2780       case HEAP_PTR:
   2781         return kPointerSize;
   2782       default:
   2783         UNREACHABLE();
   2784         return 0;
   2785     }
   2786   }
   2787 
   2788   // Code Generation support.
   2789   inline int OffsetOfElementAt(int index) {
   2790     int offset;
   2791     LayoutSection section;
   2792     if (is_extended_layout() && index >= first_extended_section_index()) {
   2793       section = EXTENDED_SECTION;
   2794       offset = get_extended_section_header_offset() + kExtendedFirstOffset;
   2795     } else {
   2796       section = SMALL_SECTION;
   2797       offset = kFirstEntryOffset;
   2798     }
   2799 
   2800     // Add offsets for the preceding type sections.
   2801     DCHECK(index <= last_index(LAST_TYPE, section));
   2802     for (Type type = FIRST_TYPE; index > last_index(type, section);
   2803          type = next_type(type)) {
   2804       offset += entry_size(type) * number_of_entries(type, section);
   2805     }
   2806 
   2807     // Add offset for the index in it's type.
   2808     Type type = get_type(index);
   2809     offset += entry_size(type) * (index - first_index(type, section));
   2810     return offset;
   2811   }
   2812 
   2813   DECLARE_CAST(ConstantPoolArray)
   2814 
   2815   // Garbage collection support.
   2816   Object** RawFieldOfElementAt(int index) {
   2817     return HeapObject::RawField(this, OffsetOfElementAt(index));
   2818   }
   2819 
   2820   // Small Layout description.
   2821   static const int kSmallLayout1Offset = HeapObject::kHeaderSize;
   2822   static const int kSmallLayout2Offset = kSmallLayout1Offset + kInt32Size;
   2823   static const int kHeaderSize = kSmallLayout2Offset + kInt32Size;
   2824   static const int kFirstEntryOffset = ROUND_UP(kHeaderSize, kInt64Size);
   2825 
   2826   static const int kSmallLayoutCountBits = 10;
   2827   static const int kMaxSmallEntriesPerType = (1 << kSmallLayoutCountBits) - 1;
   2828 
   2829   // Fields in kSmallLayout1Offset.
   2830   class Int64CountField: public BitField<int, 1, kSmallLayoutCountBits> {};
   2831   class CodePtrCountField: public BitField<int, 11, kSmallLayoutCountBits> {};
   2832   class HeapPtrCountField: public BitField<int, 21, kSmallLayoutCountBits> {};
   2833   class IsExtendedField: public BitField<bool, 31, 1> {};
   2834 
   2835   // Fields in kSmallLayout2Offset.
   2836   class Int32CountField: public BitField<int, 1, kSmallLayoutCountBits> {};
   2837   class TotalCountField: public BitField<int, 11, 12> {};
   2838   class WeakObjectStateField: public BitField<WeakObjectState, 23, 2> {};
   2839 
   2840   // Extended layout description, which starts at
   2841   // get_extended_section_header_offset().
   2842   static const int kExtendedInt64CountOffset = 0;
   2843   static const int kExtendedCodePtrCountOffset =
   2844       kExtendedInt64CountOffset + kPointerSize;
   2845   static const int kExtendedHeapPtrCountOffset =
   2846       kExtendedCodePtrCountOffset + kPointerSize;
   2847   static const int kExtendedInt32CountOffset =
   2848       kExtendedHeapPtrCountOffset + kPointerSize;
   2849   static const int kExtendedFirstOffset =
   2850       kExtendedInt32CountOffset + kPointerSize;
   2851 
   2852   // Dispatched behavior.
   2853   void ConstantPoolIterateBody(ObjectVisitor* v);
   2854 
   2855   DECLARE_PRINTER(ConstantPoolArray)
   2856   DECLARE_VERIFIER(ConstantPoolArray)
   2857 
   2858  private:
   2859   inline int first_extended_section_index();
   2860   inline int get_extended_section_header_offset();
   2861 
   2862   inline static Type next_type(Type type) {
   2863     DCHECK(type >= FIRST_TYPE && type < NUMBER_OF_TYPES);
   2864     int type_int = static_cast<int>(type);
   2865     return static_cast<Type>(++type_int);
   2866   }
   2867 
   2868   DISALLOW_IMPLICIT_CONSTRUCTORS(ConstantPoolArray);
   2869 };
   2870 
   2871 
   2872 // DescriptorArrays are fixed arrays used to hold instance descriptors.
   2873 // The format of the these objects is:
   2874 //   [0]: Number of descriptors
   2875 //   [1]: Either Smi(0) if uninitialized, or a pointer to small fixed array:
   2876 //          [0]: pointer to fixed array with enum cache
   2877 //          [1]: either Smi(0) or pointer to fixed array with indices
   2878 //   [2]: first key
   2879 //   [2 + number of descriptors * kDescriptorSize]: start of slack
   2880 class DescriptorArray: public FixedArray {
   2881  public:
   2882   // Returns true for both shared empty_descriptor_array and for smis, which the
   2883   // map uses to encode additional bit fields when the descriptor array is not
   2884   // yet used.
   2885   inline bool IsEmpty();
   2886 
   2887   // Returns the number of descriptors in the array.
   2888   int number_of_descriptors() {
   2889     DCHECK(length() >= kFirstIndex || IsEmpty());
   2890     int len = length();
   2891     return len == 0 ? 0 : Smi::cast(get(kDescriptorLengthIndex))->value();
   2892   }
   2893 
   2894   int number_of_descriptors_storage() {
   2895     int len = length();
   2896     return len == 0 ? 0 : (len - kFirstIndex) / kDescriptorSize;
   2897   }
   2898 
   2899   int NumberOfSlackDescriptors() {
   2900     return number_of_descriptors_storage() - number_of_descriptors();
   2901   }
   2902 
   2903   inline void SetNumberOfDescriptors(int number_of_descriptors);
   2904   inline int number_of_entries() { return number_of_descriptors(); }
   2905 
   2906   bool HasEnumCache() {
   2907     return !IsEmpty() && !get(kEnumCacheIndex)->IsSmi();
   2908   }
   2909 
   2910   void CopyEnumCacheFrom(DescriptorArray* array) {
   2911     set(kEnumCacheIndex, array->get(kEnumCacheIndex));
   2912   }
   2913 
   2914   FixedArray* GetEnumCache() {
   2915     DCHECK(HasEnumCache());
   2916     FixedArray* bridge = FixedArray::cast(get(kEnumCacheIndex));
   2917     return FixedArray::cast(bridge->get(kEnumCacheBridgeCacheIndex));
   2918   }
   2919 
   2920   bool HasEnumIndicesCache() {
   2921     if (IsEmpty()) return false;
   2922     Object* object = get(kEnumCacheIndex);
   2923     if (object->IsSmi()) return false;
   2924     FixedArray* bridge = FixedArray::cast(object);
   2925     return !bridge->get(kEnumCacheBridgeIndicesCacheIndex)->IsSmi();
   2926   }
   2927 
   2928   FixedArray* GetEnumIndicesCache() {
   2929     DCHECK(HasEnumIndicesCache());
   2930     FixedArray* bridge = FixedArray::cast(get(kEnumCacheIndex));
   2931     return FixedArray::cast(bridge->get(kEnumCacheBridgeIndicesCacheIndex));
   2932   }
   2933 
   2934   Object** GetEnumCacheSlot() {
   2935     DCHECK(HasEnumCache());
   2936     return HeapObject::RawField(reinterpret_cast<HeapObject*>(this),
   2937                                 kEnumCacheOffset);
   2938   }
   2939 
   2940   void ClearEnumCache();
   2941 
   2942   // Initialize or change the enum cache,
   2943   // using the supplied storage for the small "bridge".
   2944   void SetEnumCache(FixedArray* bridge_storage,
   2945                     FixedArray* new_cache,
   2946                     Object* new_index_cache);
   2947 
   2948   bool CanHoldValue(int descriptor, Object* value);
   2949 
   2950   // Accessors for fetching instance descriptor at descriptor number.
   2951   inline Name* GetKey(int descriptor_number);
   2952   inline Object** GetKeySlot(int descriptor_number);
   2953   inline Object* GetValue(int descriptor_number);
   2954   inline void SetValue(int descriptor_number, Object* value);
   2955   inline Object** GetValueSlot(int descriptor_number);
   2956   static inline int GetValueOffset(int descriptor_number);
   2957   inline Object** GetDescriptorStartSlot(int descriptor_number);
   2958   inline Object** GetDescriptorEndSlot(int descriptor_number);
   2959   inline PropertyDetails GetDetails(int descriptor_number);
   2960   inline PropertyType GetType(int descriptor_number);
   2961   inline int GetFieldIndex(int descriptor_number);
   2962   inline HeapType* GetFieldType(int descriptor_number);
   2963   inline Object* GetConstant(int descriptor_number);
   2964   inline Object* GetCallbacksObject(int descriptor_number);
   2965   inline AccessorDescriptor* GetCallbacks(int descriptor_number);
   2966 
   2967   inline Name* GetSortedKey(int descriptor_number);
   2968   inline int GetSortedKeyIndex(int descriptor_number);
   2969   inline void SetSortedKey(int pointer, int descriptor_number);
   2970   inline void SetRepresentation(int descriptor_number,
   2971                                 Representation representation);
   2972 
   2973   // Accessor for complete descriptor.
   2974   inline void Get(int descriptor_number, Descriptor* desc);
   2975   inline void Set(int descriptor_number, Descriptor* desc);
   2976   void Replace(int descriptor_number, Descriptor* descriptor);
   2977 
   2978   // Append automatically sets the enumeration index. This should only be used
   2979   // to add descriptors in bulk at the end, followed by sorting the descriptor
   2980   // array.
   2981   inline void Append(Descriptor* desc);
   2982 
   2983   static Handle<DescriptorArray> CopyUpTo(Handle<DescriptorArray> desc,
   2984                                           int enumeration_index,
   2985                                           int slack = 0);
   2986 
   2987   static Handle<DescriptorArray> CopyUpToAddAttributes(
   2988       Handle<DescriptorArray> desc,
   2989       int enumeration_index,
   2990       PropertyAttributes attributes,
   2991       int slack = 0);
   2992 
   2993   // Sort the instance descriptors by the hash codes of their keys.
   2994   void Sort();
   2995 
   2996   // Search the instance descriptors for given name.
   2997   INLINE(int Search(Name* name, int number_of_own_descriptors));
   2998 
   2999   // As the above, but uses DescriptorLookupCache and updates it when
   3000   // necessary.
   3001   INLINE(int SearchWithCache(Name* name, Map* map));
   3002 
   3003   // Allocates a DescriptorArray, but returns the singleton
   3004   // empty descriptor array object if number_of_descriptors is 0.
   3005   static Handle<DescriptorArray> Allocate(Isolate* isolate,
   3006                                           int number_of_descriptors,
   3007                                           int slack = 0);
   3008 
   3009   DECLARE_CAST(DescriptorArray)
   3010 
   3011   // Constant for denoting key was not found.
   3012   static const int kNotFound = -1;
   3013 
   3014   static const int kDescriptorLengthIndex = 0;
   3015   static const int kEnumCacheIndex = 1;
   3016   static const int kFirstIndex = 2;
   3017 
   3018   // The length of the "bridge" to the enum cache.
   3019   static const int kEnumCacheBridgeLength = 2;
   3020   static const int kEnumCacheBridgeCacheIndex = 0;
   3021   static const int kEnumCacheBridgeIndicesCacheIndex = 1;
   3022 
   3023   // Layout description.
   3024   static const int kDescriptorLengthOffset = FixedArray::kHeaderSize;
   3025   static const int kEnumCacheOffset = kDescriptorLengthOffset + kPointerSize;
   3026   static const int kFirstOffset = kEnumCacheOffset + kPointerSize;
   3027 
   3028   // Layout description for the bridge array.
   3029   static const int kEnumCacheBridgeCacheOffset = FixedArray::kHeaderSize;
   3030 
   3031   // Layout of descriptor.
   3032   static const int kDescriptorKey = 0;
   3033   static const int kDescriptorDetails = 1;
   3034   static const int kDescriptorValue = 2;
   3035   static const int kDescriptorSize = 3;
   3036 
   3037 #ifdef OBJECT_PRINT
   3038   // Print all the descriptors.
   3039   void PrintDescriptors(OStream& os);  // NOLINT
   3040 #endif
   3041 
   3042 #ifdef DEBUG
   3043   // Is the descriptor array sorted and without duplicates?
   3044   bool IsSortedNoDuplicates(int valid_descriptors = -1);
   3045 
   3046   // Is the descriptor array consistent with the back pointers in targets?
   3047   bool IsConsistentWithBackPointers(Map* current_map);
   3048 
   3049   // Are two DescriptorArrays equal?
   3050   bool IsEqualTo(DescriptorArray* other);
   3051 #endif
   3052 
   3053   // Returns the fixed array length required to hold number_of_descriptors
   3054   // descriptors.
   3055   static int LengthFor(int number_of_descriptors) {
   3056     return ToKeyIndex(number_of_descriptors);
   3057   }
   3058 
   3059  private:
   3060   // WhitenessWitness is used to prove that a descriptor array is white
   3061   // (unmarked), so incremental write barriers can be skipped because the
   3062   // marking invariant cannot be broken and slots pointing into evacuation
   3063   // candidates will be discovered when the object is scanned. A witness is
   3064   // always stack-allocated right after creating an array. By allocating a
   3065   // witness, incremental marking is globally disabled. The witness is then
   3066   // passed along wherever needed to statically prove that the array is known to
   3067   // be white.
   3068   class WhitenessWitness {
   3069    public:
   3070     inline explicit WhitenessWitness(DescriptorArray* array);
   3071     inline ~WhitenessWitness();
   3072 
   3073    private:
   3074     IncrementalMarking* marking_;
   3075   };
   3076 
   3077   // An entry in a DescriptorArray, represented as an (array, index) pair.
   3078   class Entry {
   3079    public:
   3080     inline explicit Entry(DescriptorArray* descs, int index) :
   3081         descs_(descs), index_(index) { }
   3082 
   3083     inline PropertyType type() { return descs_->GetType(index_); }
   3084     inline Object* GetCallbackObject() { return descs_->GetValue(index_); }
   3085 
   3086    private:
   3087     DescriptorArray* descs_;
   3088     int index_;
   3089   };
   3090 
   3091   // Conversion from descriptor number to array indices.
   3092   static int ToKeyIndex(int descriptor_number) {
   3093     return kFirstIndex +
   3094            (descriptor_number * kDescriptorSize) +
   3095            kDescriptorKey;
   3096   }
   3097 
   3098   static int ToDetailsIndex(int descriptor_number) {
   3099     return kFirstIndex +
   3100            (descriptor_number * kDescriptorSize) +
   3101            kDescriptorDetails;
   3102   }
   3103 
   3104   static int ToValueIndex(int descriptor_number) {
   3105     return kFirstIndex +
   3106            (descriptor_number * kDescriptorSize) +
   3107            kDescriptorValue;
   3108   }
   3109 
   3110   // Transfer a complete descriptor from the src descriptor array to this
   3111   // descriptor array.
   3112   void CopyFrom(int index,
   3113                 DescriptorArray* src,
   3114                 const WhitenessWitness&);
   3115 
   3116   inline void Set(int descriptor_number,
   3117                   Descriptor* desc,
   3118                   const WhitenessWitness&);
   3119 
   3120   // Swap first and second descriptor.
   3121   inline void SwapSortedKeys(int first, int second);
   3122 
   3123   DISALLOW_IMPLICIT_CONSTRUCTORS(DescriptorArray);
   3124 };
   3125 
   3126 
   3127 enum SearchMode { ALL_ENTRIES, VALID_ENTRIES };
   3128 
   3129 template<SearchMode search_mode, typename T>
   3130 inline int LinearSearch(T* array, Name* name, int len, int valid_entries);
   3131 
   3132 
   3133 template<SearchMode search_mode, typename T>
   3134 inline int Search(T* array, Name* name, int valid_entries = 0);
   3135 
   3136 
   3137 // HashTable is a subclass of FixedArray that implements a hash table
   3138 // that uses open addressing and quadratic probing.
   3139 //
   3140 // In order for the quadratic probing to work, elements that have not
   3141 // yet been used and elements that have been deleted are
   3142 // distinguished.  Probing continues when deleted elements are
   3143 // encountered and stops when unused elements are encountered.
   3144 //
   3145 // - Elements with key == undefined have not been used yet.
   3146 // - Elements with key == the_hole have been deleted.
   3147 //
   3148 // The hash table class is parameterized with a Shape and a Key.
   3149 // Shape must be a class with the following interface:
   3150 //   class ExampleShape {
   3151 //    public:
   3152 //      // Tells whether key matches other.
   3153 //     static bool IsMatch(Key key, Object* other);
   3154 //     // Returns the hash value for key.
   3155 //     static uint32_t Hash(Key key);
   3156 //     // Returns the hash value for object.
   3157 //     static uint32_t HashForObject(Key key, Object* object);
   3158 //     // Convert key to an object.
   3159 //     static inline Handle<Object> AsHandle(Isolate* isolate, Key key);
   3160 //     // The prefix size indicates number of elements in the beginning
   3161 //     // of the backing storage.
   3162 //     static const int kPrefixSize = ..;
   3163 //     // The Element size indicates number of elements per entry.
   3164 //     static const int kEntrySize = ..;
   3165 //   };
   3166 // The prefix size indicates an amount of memory in the
   3167 // beginning of the backing storage that can be used for non-element
   3168 // information by subclasses.
   3169 
   3170 template<typename Key>
   3171 class BaseShape {
   3172  public:
   3173   static const bool UsesSeed = false;
   3174   static uint32_t Hash(Key key) { return 0; }
   3175   static uint32_t SeededHash(Key key, uint32_t seed) {
   3176     DCHECK(UsesSeed);
   3177     return Hash(key);
   3178   }
   3179   static uint32_t HashForObject(Key key, Object* object) { return 0; }
   3180   static uint32_t SeededHashForObject(Key key, uint32_t seed, Object* object) {
   3181     DCHECK(UsesSeed);
   3182     return HashForObject(key, object);
   3183   }
   3184 };
   3185 
   3186 template<typename Derived, typename Shape, typename Key>
   3187 class HashTable: public FixedArray {
   3188  public:
   3189   // Wrapper methods
   3190   inline uint32_t Hash(Key key) {
   3191     if (Shape::UsesSeed) {
   3192       return Shape::SeededHash(key, GetHeap()->HashSeed());
   3193     } else {
   3194       return Shape::Hash(key);
   3195     }
   3196   }
   3197 
   3198   inline uint32_t HashForObject(Key key, Object* object) {
   3199     if (Shape::UsesSeed) {
   3200       return Shape::SeededHashForObject(key, GetHeap()->HashSeed(), object);
   3201     } else {
   3202       return Shape::HashForObject(key, object);
   3203     }
   3204   }
   3205 
   3206   // Returns the number of elements in the hash table.
   3207   int NumberOfElements() {
   3208     return Smi::cast(get(kNumberOfElementsIndex))->value();
   3209   }
   3210 
   3211   // Returns the number of deleted elements in the hash table.
   3212   int NumberOfDeletedElements() {
   3213     return Smi::cast(get(kNumberOfDeletedElementsIndex))->value();
   3214   }
   3215 
   3216   // Returns the capacity of the hash table.
   3217   int Capacity() {
   3218     return Smi::cast(get(kCapacityIndex))->value();
   3219   }
   3220 
   3221   // ElementAdded should be called whenever an element is added to a
   3222   // hash table.
   3223   void ElementAdded() { SetNumberOfElements(NumberOfElements() + 1); }
   3224 
   3225   // ElementRemoved should be called whenever an element is removed from
   3226   // a hash table.
   3227   void ElementRemoved() {
   3228     SetNumberOfElements(NumberOfElements() - 1);
   3229     SetNumberOfDeletedElements(NumberOfDeletedElements() + 1);
   3230   }
   3231   void ElementsRemoved(int n) {
   3232     SetNumberOfElements(NumberOfElements() - n);
   3233     SetNumberOfDeletedElements(NumberOfDeletedElements() + n);
   3234   }
   3235 
   3236   // Returns a new HashTable object.
   3237   MUST_USE_RESULT static Handle<Derived> New(
   3238       Isolate* isolate,
   3239       int at_least_space_for,
   3240       MinimumCapacity capacity_option = USE_DEFAULT_MINIMUM_CAPACITY,
   3241       PretenureFlag pretenure = NOT_TENURED);
   3242 
   3243   // Computes the required capacity for a table holding the given
   3244   // number of elements. May be more than HashTable::kMaxCapacity.
   3245   static int ComputeCapacity(int at_least_space_for);
   3246 
   3247   // Returns the key at entry.
   3248   Object* KeyAt(int entry) { return get(EntryToIndex(entry)); }
   3249 
   3250   // Tells whether k is a real key.  The hole and undefined are not allowed
   3251   // as keys and can be used to indicate missing or deleted elements.
   3252   bool IsKey(Object* k) {
   3253     return !k->IsTheHole() && !k->IsUndefined();
   3254   }
   3255 
   3256   // Garbage collection support.
   3257   void IteratePrefix(ObjectVisitor* visitor);
   3258   void IterateElements(ObjectVisitor* visitor);
   3259 
   3260   DECLARE_CAST(HashTable)
   3261 
   3262   // Compute the probe offset (quadratic probing).
   3263   INLINE(static uint32_t GetProbeOffset(uint32_t n)) {
   3264     return (n + n * n) >> 1;
   3265   }
   3266 
   3267   static const int kNumberOfElementsIndex = 0;
   3268   static const int kNumberOfDeletedElementsIndex = 1;
   3269   static const int kCapacityIndex = 2;
   3270   static const int kPrefixStartIndex = 3;
   3271   static const int kElementsStartIndex =
   3272       kPrefixStartIndex + Shape::kPrefixSize;
   3273   static const int kEntrySize = Shape::kEntrySize;
   3274   static const int kElementsStartOffset =
   3275       kHeaderSize + kElementsStartIndex * kPointerSize;
   3276   static const int kCapacityOffset =
   3277       kHeaderSize + kCapacityIndex * kPointerSize;
   3278 
   3279   // Constant used for denoting a absent entry.
   3280   static const int kNotFound = -1;
   3281 
   3282   // Maximal capacity of HashTable. Based on maximal length of underlying
   3283   // FixedArray. Staying below kMaxCapacity also ensures that EntryToIndex
   3284   // cannot overflow.
   3285   static const int kMaxCapacity =
   3286       (FixedArray::kMaxLength - kElementsStartOffset) / kEntrySize;
   3287 
   3288   // Find entry for key otherwise return kNotFound.
   3289   inline int FindEntry(Key key);
   3290   int FindEntry(Isolate* isolate, Key key);
   3291 
   3292   // Rehashes the table in-place.
   3293   void Rehash(Key key);
   3294 
   3295  protected:
   3296   friend class ObjectHashTable;
   3297 
   3298   // Find the entry at which to insert element with the given key that
   3299   // has the given hash value.
   3300   uint32_t FindInsertionEntry(uint32_t hash);
   3301 
   3302   // Returns the index for an entry (of the key)
   3303   static inline int EntryToIndex(int entry) {
   3304     return (entry * kEntrySize) + kElementsStartIndex;
   3305   }
   3306 
   3307   // Update the number of elements in the hash table.
   3308   void SetNumberOfElements(int nof) {
   3309     set(kNumberOfElementsIndex, Smi::FromInt(nof));
   3310   }
   3311 
   3312   // Update the number of deleted elements in the hash table.
   3313   void SetNumberOfDeletedElements(int nod) {
   3314     set(kNumberOfDeletedElementsIndex, Smi::FromInt(nod));
   3315   }
   3316 
   3317   // Sets the capacity of the hash table.
   3318   void SetCapacity(int capacity) {
   3319     // To scale a computed hash code to fit within the hash table, we
   3320     // use bit-wise AND with a mask, so the capacity must be positive
   3321     // and non-zero.
   3322     DCHECK(capacity > 0);
   3323     DCHECK(capacity <= kMaxCapacity);
   3324     set(kCapacityIndex, Smi::FromInt(capacity));
   3325   }
   3326 
   3327 
   3328   // Returns probe entry.
   3329   static uint32_t GetProbe(uint32_t hash, uint32_t number, uint32_t size) {
   3330     DCHECK(base::bits::IsPowerOfTwo32(size));
   3331     return (hash + GetProbeOffset(number)) & (size - 1);
   3332   }
   3333 
   3334   inline static uint32_t FirstProbe(uint32_t hash, uint32_t size) {
   3335     return hash & (size - 1);
   3336   }
   3337 
   3338   inline static uint32_t NextProbe(
   3339       uint32_t last, uint32_t number, uint32_t size) {
   3340     return (last + number) & (size - 1);
   3341   }
   3342 
   3343   // Attempt to shrink hash table after removal of key.
   3344   MUST_USE_RESULT static Handle<Derived> Shrink(Handle<Derived> table, Key key);
   3345 
   3346   // Ensure enough space for n additional elements.
   3347   MUST_USE_RESULT static Handle<Derived> EnsureCapacity(
   3348       Handle<Derived> table,
   3349       int n,
   3350       Key key,
   3351       PretenureFlag pretenure = NOT_TENURED);
   3352 
   3353  private:
   3354   // Returns _expected_ if one of entries given by the first _probe_ probes is
   3355   // equal to  _expected_. Otherwise, returns the entry given by the probe
   3356   // number _probe_.
   3357   uint32_t EntryForProbe(Key key, Object* k, int probe, uint32_t expected);
   3358 
   3359   void Swap(uint32_t entry1, uint32_t entry2, WriteBarrierMode mode);
   3360 
   3361   // Rehashes this hash-table into the new table.
   3362   void Rehash(Handle<Derived> new_table, Key key);
   3363 };
   3364 
   3365 
   3366 // HashTableKey is an abstract superclass for virtual key behavior.
   3367 class HashTableKey {
   3368  public:
   3369   // Returns whether the other object matches this key.
   3370   virtual bool IsMatch(Object* other) = 0;
   3371   // Returns the hash value for this key.
   3372   virtual uint32_t Hash() = 0;
   3373   // Returns the hash value for object.
   3374   virtual uint32_t HashForObject(Object* key) = 0;
   3375   // Returns the key object for storing into the hash table.
   3376   MUST_USE_RESULT virtual Handle<Object> AsHandle(Isolate* isolate) = 0;
   3377   // Required.
   3378   virtual ~HashTableKey() {}
   3379 };
   3380 
   3381 
   3382 class StringTableShape : public BaseShape<HashTableKey*> {
   3383  public:
   3384   static inline bool IsMatch(HashTableKey* key, Object* value) {
   3385     return key->IsMatch(value);
   3386   }
   3387 
   3388   static inline uint32_t Hash(HashTableKey* key) {
   3389     return key->Hash();
   3390   }
   3391 
   3392   static inline uint32_t HashForObject(HashTableKey* key, Object* object) {
   3393     return key->HashForObject(object);
   3394   }
   3395 
   3396   static inline Handle<Object> AsHandle(Isolate* isolate, HashTableKey* key);
   3397 
   3398   static const int kPrefixSize = 0;
   3399   static const int kEntrySize = 1;
   3400 };
   3401 
   3402 class SeqOneByteString;
   3403 
   3404 // StringTable.
   3405 //
   3406 // No special elements in the prefix and the element size is 1
   3407 // because only the string itself (the key) needs to be stored.
   3408 class StringTable: public HashTable<StringTable,
   3409                                     StringTableShape,
   3410                                     HashTableKey*> {
   3411  public:
   3412   // Find string in the string table. If it is not there yet, it is
   3413   // added. The return value is the string found.
   3414   static Handle<String> LookupString(Isolate* isolate, Handle<String> key);
   3415   static Handle<String> LookupKey(Isolate* isolate, HashTableKey* key);
   3416 
   3417   // Tries to internalize given string and returns string handle on success
   3418   // or an empty handle otherwise.
   3419   MUST_USE_RESULT static MaybeHandle<String> InternalizeStringIfExists(
   3420       Isolate* isolate,
   3421       Handle<String> string);
   3422 
   3423   // Looks up a string that is equal to the given string and returns
   3424   // string handle if it is found, or an empty handle otherwise.
   3425   MUST_USE_RESULT static MaybeHandle<String> LookupStringIfExists(
   3426       Isolate* isolate,
   3427       Handle<String> str);
   3428   MUST_USE_RESULT static MaybeHandle<String> LookupTwoCharsStringIfExists(
   3429       Isolate* isolate,
   3430       uint16_t c1,
   3431       uint16_t c2);
   3432 
   3433   DECLARE_CAST(StringTable)
   3434 
   3435  private:
   3436   template <bool seq_one_byte>
   3437   friend class JsonParser;
   3438 
   3439   DISALLOW_IMPLICIT_CONSTRUCTORS(StringTable);
   3440 };
   3441 
   3442 
   3443 class MapCacheShape : public BaseShape<HashTableKey*> {
   3444  public:
   3445   static inline bool IsMatch(HashTableKey* key, Object* value) {
   3446     return key->IsMatch(value);
   3447   }
   3448 
   3449   static inline uint32_t Hash(HashTableKey* key) {
   3450     return key->Hash();
   3451   }
   3452 
   3453   static inline uint32_t HashForObject(HashTableKey* key, Object* object) {
   3454     return key->HashForObject(object);
   3455   }
   3456 
   3457   static inline Handle<Object> AsHandle(Isolate* isolate, HashTableKey* key);
   3458 
   3459   static const int kPrefixSize = 0;
   3460   static const int kEntrySize = 2;
   3461 };
   3462 
   3463 
   3464 // MapCache.
   3465 //
   3466 // Maps keys that are a fixed array of unique names to a map.
   3467 // Used for canonicalize maps for object literals.
   3468 class MapCache: public HashTable<MapCache, MapCacheShape, HashTableKey*> {
   3469  public:
   3470   // Find cached value for a name key, otherwise return null.
   3471   Object* Lookup(FixedArray* key);
   3472   static Handle<MapCache> Put(
   3473       Handle<MapCache> map_cache, Handle<FixedArray> key, Handle<Map> value);
   3474   DECLARE_CAST(MapCache)
   3475 
   3476  private:
   3477   DISALLOW_IMPLICIT_CONSTRUCTORS(MapCache);
   3478 };
   3479 
   3480 
   3481 template <typename Derived, typename Shape, typename Key>
   3482 class Dictionary: public HashTable<Derived, Shape, Key> {
   3483  protected:
   3484   typedef HashTable<Derived, Shape, Key> DerivedHashTable;
   3485 
   3486  public:
   3487   // Returns the value at entry.
   3488   Object* ValueAt(int entry) {
   3489     return this->get(DerivedHashTable::EntryToIndex(entry) + 1);
   3490   }
   3491 
   3492   // Set the value for entry.
   3493   void ValueAtPut(int entry, Object* value) {
   3494     this->set(DerivedHashTable::EntryToIndex(entry) + 1, value);
   3495   }
   3496 
   3497   // Returns the property details for the property at entry.
   3498   PropertyDetails DetailsAt(int entry) {
   3499     DCHECK(entry >= 0);  // Not found is -1, which is not caught by get().
   3500     return PropertyDetails(
   3501         Smi::cast(this->get(DerivedHashTable::EntryToIndex(entry) + 2)));
   3502   }
   3503 
   3504   // Set the details for entry.
   3505   void DetailsAtPut(int entry, PropertyDetails value) {
   3506     this->set(DerivedHashTable::EntryToIndex(entry) + 2, value.AsSmi());
   3507   }
   3508 
   3509   // Sorting support
   3510   void CopyValuesTo(FixedArray* elements);
   3511 
   3512   // Delete a property from the dictionary.
   3513   static Handle<Object> DeleteProperty(
   3514       Handle<Derived> dictionary,
   3515       int entry,
   3516       JSObject::DeleteMode mode);
   3517 
   3518   // Attempt to shrink the dictionary after deletion of key.
   3519   MUST_USE_RESULT static inline Handle<Derived> Shrink(
   3520       Handle<Derived> dictionary,
   3521       Key key) {
   3522     return DerivedHashTable::Shrink(dictionary, key);
   3523   }
   3524 
   3525   // Returns the number of elements in the dictionary filtering out properties
   3526   // with the specified attributes.
   3527   int NumberOfElementsFilterAttributes(PropertyAttributes filter);
   3528 
   3529   // Returns the number of enumerable elements in the dictionary.
   3530   int NumberOfEnumElements();
   3531 
   3532   enum SortMode { UNSORTED, SORTED };
   3533   // Copies keys to preallocated fixed array.
   3534   void CopyKeysTo(FixedArray* storage,
   3535                   PropertyAttributes filter,
   3536                   SortMode sort_mode);
   3537   // Fill in details for properties into storage.
   3538   void CopyKeysTo(FixedArray* storage,
   3539                   int index,
   3540                   PropertyAttributes filter,
   3541                   SortMode sort_mode);
   3542 
   3543   // Accessors for next enumeration index.
   3544   void SetNextEnumerationIndex(int index) {
   3545     DCHECK(index != 0);
   3546     this->set(kNextEnumerationIndexIndex, Smi::FromInt(index));
   3547   }
   3548 
   3549   int NextEnumerationIndex() {
   3550     return Smi::cast(this->get(kNextEnumerationIndexIndex))->value();
   3551   }
   3552 
   3553   // Creates a new dictionary.
   3554   MUST_USE_RESULT static Handle<Derived> New(
   3555       Isolate* isolate,
   3556       int at_least_space_for,
   3557       PretenureFlag pretenure = NOT_TENURED);
   3558 
   3559   // Ensure enough space for n additional elements.
   3560   static Handle<Derived> EnsureCapacity(Handle<Derived> obj, int n, Key key);
   3561 
   3562 #ifdef OBJECT_PRINT
   3563   void Print(OStream& os);  // NOLINT
   3564 #endif
   3565   // Returns the key (slow).
   3566   Object* SlowReverseLookup(Object* value);
   3567 
   3568   // Sets the entry to (key, value) pair.
   3569   inline void SetEntry(int entry,
   3570                        Handle<Object> key,
   3571                        Handle<Object> value);
   3572   inline void SetEntry(int entry,
   3573                        Handle<Object> key,
   3574                        Handle<Object> value,
   3575                        PropertyDetails details);
   3576 
   3577   MUST_USE_RESULT static Handle<Derived> Add(
   3578       Handle<Derived> dictionary,
   3579       Key key,
   3580       Handle<Object> value,
   3581       PropertyDetails details);
   3582 
   3583  protected:
   3584   // Generic at put operation.
   3585   MUST_USE_RESULT static Handle<Derived> AtPut(
   3586       Handle<Derived> dictionary,
   3587       Key key,
   3588       Handle<Object> value);
   3589 
   3590   // Add entry to dictionary.
   3591   static void AddEntry(
   3592       Handle<Derived> dictionary,
   3593       Key key,
   3594       Handle<Object> value,
   3595       PropertyDetails details,
   3596       uint32_t hash);
   3597 
   3598   // Generate new enumeration indices to avoid enumeration index overflow.
   3599   static void GenerateNewEnumerationIndices(Handle<Derived> dictionary);
   3600   static const int kMaxNumberKeyIndex = DerivedHashTable::kPrefixStartIndex;
   3601   static const int kNextEnumerationIndexIndex = kMaxNumberKeyIndex + 1;
   3602 };
   3603 
   3604 
   3605 class NameDictionaryShape : public BaseShape<Handle<Name> > {
   3606  public:
   3607   static inline bool IsMatch(Handle<Name> key, Object* other);
   3608   static inline uint32_t Hash(Handle<Name> key);
   3609   static inline uint32_t HashForObject(Handle<Name> key, Object* object);
   3610   static inline Handle<Object> AsHandle(Isolate* isolate, Handle<Name> key);
   3611   static const int kPrefixSize = 2;
   3612   static const int kEntrySize = 3;
   3613   static const bool kIsEnumerable = true;
   3614 };
   3615 
   3616 
   3617 class NameDictionary: public Dictionary<NameDictionary,
   3618                                         NameDictionaryShape,
   3619                                         Handle<Name> > {
   3620   typedef Dictionary<
   3621       NameDictionary, NameDictionaryShape, Handle<Name> > DerivedDictionary;
   3622 
   3623  public:
   3624   DECLARE_CAST(NameDictionary)
   3625 
   3626   // Copies enumerable keys to preallocated fixed array.
   3627   void CopyEnumKeysTo(FixedArray* storage);
   3628   inline static void DoGenerateNewEnumerationIndices(
   3629       Handle<NameDictionary> dictionary);
   3630 
   3631   // Find entry for key, otherwise return kNotFound. Optimized version of
   3632   // HashTable::FindEntry.
   3633   int FindEntry(Handle<Name> key);
   3634 };
   3635 
   3636 
   3637 class NumberDictionaryShape : public BaseShape<uint32_t> {
   3638  public:
   3639   static inline bool IsMatch(uint32_t key, Object* other);
   3640   static inline Handle<Object> AsHandle(Isolate* isolate, uint32_t key);
   3641   static const int kEntrySize = 3;
   3642   static const bool kIsEnumerable = false;
   3643 };
   3644 
   3645 
   3646 class SeededNumberDictionaryShape : public NumberDictionaryShape {
   3647  public:
   3648   static const bool UsesSeed = true;
   3649   static const int kPrefixSize = 2;
   3650 
   3651   static inline uint32_t SeededHash(uint32_t key, uint32_t seed);
   3652   static inline uint32_t SeededHashForObject(uint32_t key,
   3653                                              uint32_t seed,
   3654                                              Object* object);
   3655 };
   3656 
   3657 
   3658 class UnseededNumberDictionaryShape : public NumberDictionaryShape {
   3659  public:
   3660   static const int kPrefixSize = 0;
   3661 
   3662   static inline uint32_t Hash(uint32_t key);
   3663   static inline uint32_t HashForObject(uint32_t key, Object* object);
   3664 };
   3665 
   3666 
   3667 class SeededNumberDictionary
   3668     : public Dictionary<SeededNumberDictionary,
   3669                         SeededNumberDictionaryShape,
   3670                         uint32_t> {
   3671  public:
   3672   DECLARE_CAST(SeededNumberDictionary)
   3673 
   3674   // Type specific at put (default NONE attributes is used when adding).
   3675   MUST_USE_RESULT static Handle<SeededNumberDictionary> AtNumberPut(
   3676       Handle<SeededNumberDictionary> dictionary,
   3677       uint32_t key,
   3678       Handle<Object> value);
   3679   MUST_USE_RESULT static Handle<SeededNumberDictionary> AddNumberEntry(
   3680       Handle<SeededNumberDictionary> dictionary,
   3681       uint32_t key,
   3682       Handle<Object> value,
   3683       PropertyDetails details);
   3684 
   3685   // Set an existing entry or add a new one if needed.
   3686   // Return the updated dictionary.
   3687   MUST_USE_RESULT static Handle<SeededNumberDictionary> Set(
   3688       Handle<SeededNumberDictionary> dictionary,
   3689       uint32_t key,
   3690       Handle<Object> value,
   3691       PropertyDetails details);
   3692 
   3693   void UpdateMaxNumberKey(uint32_t key);
   3694 
   3695   // If slow elements are required we will never go back to fast-case
   3696   // for the elements kept in this dictionary.  We require slow
   3697   // elements if an element has been added at an index larger than
   3698   // kRequiresSlowElementsLimit or set_requires_slow_elements() has been called
   3699   // when defining a getter or setter with a number key.
   3700   inline bool requires_slow_elements();
   3701   inline void set_requires_slow_elements();
   3702 
   3703   // Get the value of the max number key that has been added to this
   3704   // dictionary.  max_number_key can only be called if
   3705   // requires_slow_elements returns false.
   3706   inline uint32_t max_number_key();
   3707 
   3708   // Bit masks.
   3709   static const int kRequiresSlowElementsMask = 1;
   3710   static const int kRequiresSlowElementsTagSize = 1;
   3711   static const uint32_t kRequiresSlowElementsLimit = (1 << 29) - 1;
   3712 };
   3713 
   3714 
   3715 class UnseededNumberDictionary
   3716     : public Dictionary<UnseededNumberDictionary,
   3717                         UnseededNumberDictionaryShape,
   3718                         uint32_t> {
   3719  public:
   3720   DECLARE_CAST(UnseededNumberDictionary)
   3721 
   3722   // Type specific at put (default NONE attributes is used when adding).
   3723   MUST_USE_RESULT static Handle<UnseededNumberDictionary> AtNumberPut(
   3724       Handle<UnseededNumberDictionary> dictionary,
   3725       uint32_t key,
   3726       Handle<Object> value);
   3727   MUST_USE_RESULT static Handle<UnseededNumberDictionary> AddNumberEntry(
   3728       Handle<UnseededNumberDictionary> dictionary,
   3729       uint32_t key,
   3730       Handle<Object> value);
   3731 
   3732   // Set an existing entry or add a new one if needed.
   3733   // Return the updated dictionary.
   3734   MUST_USE_RESULT static Handle<UnseededNumberDictionary> Set(
   3735       Handle<UnseededNumberDictionary> dictionary,
   3736       uint32_t key,
   3737       Handle<Object> value);
   3738 };
   3739 
   3740 
   3741 class ObjectHashTableShape : public BaseShape<Handle<Object> > {
   3742  public:
   3743   static inline bool IsMatch(Handle<Object> key, Object* other);
   3744   static inline uint32_t Hash(Handle<Object> key);
   3745   static inline uint32_t HashForObject(Handle<Object> key, Object* object);
   3746   static inline Handle<Object> AsHandle(Isolate* isolate, Handle<Object> key);
   3747   static const int kPrefixSize = 0;
   3748   static const int kEntrySize = 2;
   3749 };
   3750 
   3751 
   3752 // ObjectHashTable maps keys that are arbitrary objects to object values by
   3753 // using the identity hash of the key for hashing purposes.
   3754 class ObjectHashTable: public HashTable<ObjectHashTable,
   3755                                         ObjectHashTableShape,
   3756                                         Handle<Object> > {
   3757   typedef HashTable<
   3758       ObjectHashTable, ObjectHashTableShape, Handle<Object> > DerivedHashTable;
   3759  public:
   3760   DECLARE_CAST(ObjectHashTable)
   3761 
   3762   // Attempt to shrink hash table after removal of key.
   3763   MUST_USE_RESULT static inline Handle<ObjectHashTable> Shrink(
   3764       Handle<ObjectHashTable> table,
   3765       Handle<Object> key);
   3766 
   3767   // Looks up the value associated with the given key. The hole value is
   3768   // returned in case the key is not present.
   3769   Object* Lookup(Handle<Object> key);
   3770 
   3771   // Adds (or overwrites) the value associated with the given key.
   3772   static Handle<ObjectHashTable> Put(Handle<ObjectHashTable> table,
   3773                                      Handle<Object> key,
   3774                                      Handle<Object> value);
   3775 
   3776   // Returns an ObjectHashTable (possibly |table|) where |key| has been removed.
   3777   static Handle<ObjectHashTable> Remove(Handle<ObjectHashTable> table,
   3778                                         Handle<Object> key,
   3779                                         bool* was_present);
   3780 
   3781  private:
   3782   friend class MarkCompactCollector;
   3783 
   3784   void AddEntry(int entry, Object* key, Object* value);
   3785   void RemoveEntry(int entry);
   3786 
   3787   // Returns the index to the value of an entry.
   3788   static inline int EntryToValueIndex(int entry) {
   3789     return EntryToIndex(entry) + 1;
   3790   }
   3791 };
   3792 
   3793 
   3794 // OrderedHashTable is a HashTable with Object keys that preserves
   3795 // insertion order. There are Map and Set interfaces (OrderedHashMap
   3796 // and OrderedHashTable, below). It is meant to be used by JSMap/JSSet.
   3797 //
   3798 // Only Object* keys are supported, with Object::SameValueZero() used as the
   3799 // equality operator and Object::GetHash() for the hash function.
   3800 //
   3801 // Based on the "Deterministic Hash Table" as described by Jason Orendorff at
   3802 // https://wiki.mozilla.org/User:Jorend/Deterministic_hash_tables
   3803 // Originally attributed to Tyler Close.
   3804 //
   3805 // Memory layout:
   3806 //   [0]: bucket count
   3807 //   [1]: element count
   3808 //   [2]: deleted element count
   3809 //   [3..(3 + NumberOfBuckets() - 1)]: "hash table", where each item is an
   3810 //                            offset into the data table (see below) where the
   3811 //                            first item in this bucket is stored.
   3812 //   [3 + NumberOfBuckets()..length]: "data table", an array of length
   3813 //                            Capacity() * kEntrySize, where the first entrysize
   3814 //                            items are handled by the derived class and the
   3815 //                            item at kChainOffset is another entry into the
   3816 //                            data table indicating the next entry in this hash
   3817 //                            bucket.
   3818 //
   3819 // When we transition the table to a new version we obsolete it and reuse parts
   3820 // of the memory to store information how to transition an iterator to the new
   3821 // table:
   3822 //
   3823 // Memory layout for obsolete table:
   3824 //   [0]: bucket count
   3825 //   [1]: Next newer table
   3826 //   [2]: Number of removed holes or -1 when the table was cleared.
   3827 //   [3..(3 + NumberOfRemovedHoles() - 1)]: The indexes of the removed holes.
   3828 //   [3 + NumberOfRemovedHoles()..length]: Not used
   3829 //
   3830 template<class Derived, class Iterator, int entrysize>
   3831 class OrderedHashTable: public FixedArray {
   3832  public:
   3833   // Returns an OrderedHashTable with a capacity of at least |capacity|.
   3834   static Handle<Derived> Allocate(
   3835       Isolate* isolate, int capacity, PretenureFlag pretenure = NOT_TENURED);
   3836 
   3837   // Returns an OrderedHashTable (possibly |table|) with enough space
   3838   // to add at least one new element.
   3839   static Handle<Derived> EnsureGrowable(Handle<Derived> table);
   3840 
   3841   // Returns an OrderedHashTable (possibly |table|) that's shrunken
   3842   // if possible.
   3843   static Handle<Derived> Shrink(Handle<Derived> table);
   3844 
   3845   // Returns a new empty OrderedHashTable and records the clearing so that
   3846   // exisiting iterators can be updated.
   3847   static Handle<Derived> Clear(Handle<Derived> table);
   3848 
   3849   // Returns an OrderedHashTable (possibly |table|) where |key| has been
   3850   // removed.
   3851   static Handle<Derived> Remove(Handle<Derived> table, Handle<Object> key,
   3852       bool* was_present);
   3853 
   3854   // Returns kNotFound if the key isn't present.
   3855   int FindEntry(Handle<Object> key, int hash);
   3856 
   3857   // Like the above, but doesn't require the caller to provide a hash.
   3858   int FindEntry(Handle<Object> key);
   3859 
   3860   int NumberOfElements() {
   3861     return Smi::cast(get(kNumberOfElementsIndex))->value();
   3862   }
   3863 
   3864   int NumberOfDeletedElements() {
   3865     return Smi::cast(get(kNumberOfDeletedElementsIndex))->value();
   3866   }
   3867 
   3868   int UsedCapacity() { return NumberOfElements() + NumberOfDeletedElements(); }
   3869 
   3870   int NumberOfBuckets() {
   3871     return Smi::cast(get(kNumberOfBucketsIndex))->value();
   3872   }
   3873 
   3874   // Returns the index into the data table where the new entry
   3875   // should be placed. The table is assumed to have enough space
   3876   // for a new entry.
   3877   int AddEntry(int hash);
   3878 
   3879   // Removes the entry, and puts the_hole in entrysize pointers
   3880   // (leaving the hash table chain intact).
   3881   void RemoveEntry(int entry);
   3882 
   3883   // Returns an index into |this| for the given entry.
   3884   int EntryToIndex(int entry) {
   3885     return kHashTableStartIndex + NumberOfBuckets() + (entry * kEntrySize);
   3886   }
   3887 
   3888   Object* KeyAt(int entry) { return get(EntryToIndex(entry)); }
   3889 
   3890   bool IsObsolete() {
   3891     return !get(kNextTableIndex)->IsSmi();
   3892   }
   3893 
   3894   // The next newer table. This is only valid if the table is obsolete.
   3895   Derived* NextTable() {
   3896     return Derived::cast(get(kNextTableIndex));
   3897   }
   3898 
   3899   // When the table is obsolete we store the indexes of the removed holes.
   3900   int RemovedIndexAt(int index) {
   3901     return Smi::cast(get(kRemovedHolesIndex + index))->value();
   3902   }
   3903 
   3904   static const int kNotFound = -1;
   3905   static const int kMinCapacity = 4;
   3906 
   3907  private:
   3908   static Handle<Derived> Rehash(Handle<Derived> table, int new_capacity);
   3909 
   3910   void SetNumberOfBuckets(int num) {
   3911     set(kNumberOfBucketsIndex, Smi::FromInt(num));
   3912   }
   3913 
   3914   void SetNumberOfElements(int num) {
   3915     set(kNumberOfElementsIndex, Smi::FromInt(num));
   3916   }
   3917 
   3918   void SetNumberOfDeletedElements(int num) {
   3919     set(kNumberOfDeletedElementsIndex, Smi::FromInt(num));
   3920   }
   3921 
   3922   int Capacity() {
   3923     return NumberOfBuckets() * kLoadFactor;
   3924   }
   3925 
   3926   // Returns the next entry for the given entry.
   3927   int ChainAt(int entry) {
   3928     return Smi::cast(get(EntryToIndex(entry) + kChainOffset))->value();
   3929   }
   3930 
   3931   int HashToBucket(int hash) {
   3932     return hash & (NumberOfBuckets() - 1);
   3933   }
   3934 
   3935   int HashToEntry(int hash) {
   3936     int bucket = HashToBucket(hash);
   3937     return Smi::cast(get(kHashTableStartIndex + bucket))->value();
   3938   }
   3939 
   3940   void SetNextTable(Derived* next_table) {
   3941     set(kNextTableIndex, next_table);
   3942   }
   3943 
   3944   void SetRemovedIndexAt(int index, int removed_index) {
   3945     return set(kRemovedHolesIndex + index, Smi::FromInt(removed_index));
   3946   }
   3947 
   3948   static const int kNumberOfBucketsIndex = 0;
   3949   static const int kNumberOfElementsIndex = kNumberOfBucketsIndex + 1;
   3950   static const int kNumberOfDeletedElementsIndex = kNumberOfElementsIndex + 1;
   3951   static const int kHashTableStartIndex = kNumberOfDeletedElementsIndex + 1;
   3952 
   3953   static const int kNextTableIndex = kNumberOfElementsIndex;
   3954   static const int kRemovedHolesIndex = kHashTableStartIndex;
   3955 
   3956   static const int kEntrySize = entrysize + 1;
   3957   static const int kChainOffset = entrysize;
   3958 
   3959   static const int kLoadFactor = 2;
   3960   static const int kMaxCapacity =
   3961       (FixedArray::kMaxLength - kHashTableStartIndex)
   3962       / (1 + (kEntrySize * kLoadFactor));
   3963 };
   3964 
   3965 
   3966 class JSSetIterator;
   3967 
   3968 
   3969 class OrderedHashSet: public OrderedHashTable<
   3970     OrderedHashSet, JSSetIterator, 1> {
   3971  public:
   3972   DECLARE_CAST(OrderedHashSet)
   3973 
   3974   bool Contains(Handle<Object> key);
   3975   static Handle<OrderedHashSet> Add(
   3976       Handle<OrderedHashSet> table, Handle<Object> key);
   3977 };
   3978 
   3979 
   3980 class JSMapIterator;
   3981 
   3982 
   3983 class OrderedHashMap:public OrderedHashTable<
   3984     OrderedHashMap, JSMapIterator, 2> {
   3985  public:
   3986   DECLARE_CAST(OrderedHashMap)
   3987 
   3988   Object* Lookup(Handle<Object> key);
   3989   static Handle<OrderedHashMap> Put(
   3990       Handle<OrderedHashMap> table,
   3991       Handle<Object> key,
   3992       Handle<Object> value);
   3993 
   3994   Object* ValueAt(int entry) {
   3995     return get(EntryToIndex(entry) + kValueOffset);
   3996   }
   3997 
   3998  private:
   3999   static const int kValueOffset = 1;
   4000 };
   4001 
   4002 
   4003 template <int entrysize>
   4004 class WeakHashTableShape : public BaseShape<Handle<Object> > {
   4005  public:
   4006   static inline bool IsMatch(Handle<Object> key, Object* other);
   4007   static inline uint32_t Hash(Handle<Object> key);
   4008   static inline uint32_t HashForObject(Handle<Object> key, Object* object);
   4009   static inline Handle<Object> AsHandle(Isolate* isolate, Handle<Object> key);
   4010   static const int kPrefixSize = 0;
   4011   static const int kEntrySize = entrysize;
   4012 };
   4013 
   4014 
   4015 // WeakHashTable maps keys that are arbitrary objects to object values.
   4016 // It is used for the global weak hash table that maps objects
   4017 // embedded in optimized code to dependent code lists.
   4018 class WeakHashTable: public HashTable<WeakHashTable,
   4019                                       WeakHashTableShape<2>,
   4020                                       Handle<Object> > {
   4021   typedef HashTable<
   4022       WeakHashTable, WeakHashTableShape<2>, Handle<Object> > DerivedHashTable;
   4023  public:
   4024   DECLARE_CAST(WeakHashTable)
   4025 
   4026   // Looks up the value associated with the given key. The hole value is
   4027   // returned in case the key is not present.
   4028   Object* Lookup(Handle<Object> key);
   4029 
   4030   // Adds (or overwrites) the value associated with the given key. Mapping a
   4031   // key to the hole value causes removal of the whole entry.
   4032   MUST_USE_RESULT static Handle<WeakHashTable> Put(Handle<WeakHashTable> table,
   4033                                                    Handle<Object> key,
   4034                                                    Handle<Object> value);
   4035 
   4036   // This function is called when heap verification is turned on.
   4037   void Zap(Object* value) {
   4038     int capacity = Capacity();
   4039     for (int i = 0; i < capacity; i++) {
   4040       set(EntryToIndex(i), value);
   4041       set(EntryToValueIndex(i), value);
   4042     }
   4043   }
   4044 
   4045  private:
   4046   friend class MarkCompactCollector;
   4047 
   4048   void AddEntry(int entry, Handle<Object> key, Handle<Object> value);
   4049 
   4050   // Returns the index to the value of an entry.
   4051   static inline int EntryToValueIndex(int entry) {
   4052     return EntryToIndex(entry) + 1;
   4053   }
   4054 };
   4055 
   4056 
   4057 // JSFunctionResultCache caches results of some JSFunction invocation.
   4058 // It is a fixed array with fixed structure:
   4059 //   [0]: factory function
   4060 //   [1]: finger index
   4061 //   [2]: current cache size
   4062 //   [3]: dummy field.
   4063 // The rest of array are key/value pairs.
   4064 class JSFunctionResultCache: public FixedArray {
   4065  public:
   4066   static const int kFactoryIndex = 0;
   4067   static const int kFingerIndex = kFactoryIndex + 1;
   4068   static const int kCacheSizeIndex = kFingerIndex + 1;
   4069   static const int kDummyIndex = kCacheSizeIndex + 1;
   4070   static const int kEntriesIndex = kDummyIndex + 1;
   4071 
   4072   static const int kEntrySize = 2;  // key + value
   4073 
   4074   static const int kFactoryOffset = kHeaderSize;
   4075   static const int kFingerOffset = kFactoryOffset + kPointerSize;
   4076   static const int kCacheSizeOffset = kFingerOffset + kPointerSize;
   4077 
   4078   inline void MakeZeroSize();
   4079   inline void Clear();
   4080 
   4081   inline int size();
   4082   inline void set_size(int size);
   4083   inline int finger_index();
   4084   inline void set_finger_index(int finger_index);
   4085 
   4086   DECLARE_CAST(JSFunctionResultCache)
   4087 
   4088   DECLARE_VERIFIER(JSFunctionResultCache)
   4089 };
   4090 
   4091 
   4092 // ScopeInfo represents information about different scopes of a source
   4093 // program  and the allocation of the scope's variables. Scope information
   4094 // is stored in a compressed form in ScopeInfo objects and is used
   4095 // at runtime (stack dumps, deoptimization, etc.).
   4096 
   4097 // This object provides quick access to scope info details for runtime
   4098 // routines.
   4099 class ScopeInfo : public FixedArray {
   4100  public:
   4101   DECLARE_CAST(ScopeInfo)
   4102 
   4103   // Return the type of this scope.
   4104   ScopeType scope_type();
   4105 
   4106   // Does this scope call eval?
   4107   bool CallsEval();
   4108 
   4109   // Return the strict mode of this scope.
   4110   StrictMode strict_mode();
   4111 
   4112   // Does this scope make a sloppy eval call?
   4113   bool CallsSloppyEval() { return CallsEval() && strict_mode() == SLOPPY; }
   4114 
   4115   // Return the total number of locals allocated on the stack and in the
   4116   // context. This includes the parameters that are allocated in the context.
   4117   int LocalCount();
   4118 
   4119   // Return the number of stack slots for code. This number consists of two
   4120   // parts:
   4121   //  1. One stack slot per stack allocated local.
   4122   //  2. One stack slot for the function name if it is stack allocated.
   4123   int StackSlotCount();
   4124 
   4125   // Return the number of context slots for code if a context is allocated. This
   4126   // number consists of three parts:
   4127   //  1. Size of fixed header for every context: Context::MIN_CONTEXT_SLOTS
   4128   //  2. One context slot per context allocated local.
   4129   //  3. One context slot for the function name if it is context allocated.
   4130   // Parameters allocated in the context count as context allocated locals. If
   4131   // no contexts are allocated for this scope ContextLength returns 0.
   4132   int ContextLength();
   4133 
   4134   // Is this scope the scope of a named function expression?
   4135   bool HasFunctionName();
   4136 
   4137   // Return if this has context allocated locals.
   4138   bool HasHeapAllocatedLocals();
   4139 
   4140   // Return if contexts are allocated for this scope.
   4141   bool HasContext();
   4142 
   4143   // Return if this is a function scope with "use asm".
   4144   bool IsAsmModule() { return AsmModuleField::decode(Flags()); }
   4145 
   4146   // Return if this is a nested function within an asm module scope.
   4147   bool IsAsmFunction() { return AsmFunctionField::decode(Flags()); }
   4148 
   4149   // Return the function_name if present.
   4150   String* FunctionName();
   4151 
   4152   // Return the name of the given parameter.
   4153   String* ParameterName(int var);
   4154 
   4155   // Return the name of the given local.
   4156   String* LocalName(int var);
   4157 
   4158   // Return the name of the given stack local.
   4159   String* StackLocalName(int var);
   4160 
   4161   // Return the name of the given context local.
   4162   String* ContextLocalName(int var);
   4163 
   4164   // Return the mode of the given context local.
   4165   VariableMode ContextLocalMode(int var);
   4166 
   4167   // Return the initialization flag of the given context local.
   4168   InitializationFlag ContextLocalInitFlag(int var);
   4169 
   4170   // Return the initialization flag of the given context local.
   4171   MaybeAssignedFlag ContextLocalMaybeAssignedFlag(int var);
   4172 
   4173   // Return true if this local was introduced by the compiler, and should not be
   4174   // exposed to the user in a debugger.
   4175   bool LocalIsSynthetic(int var);
   4176 
   4177   // Lookup support for serialized scope info. Returns the
   4178   // the stack slot index for a given slot name if the slot is
   4179   // present; otherwise returns a value < 0. The name must be an internalized
   4180   // string.
   4181   int StackSlotIndex(String* name);
   4182 
   4183   // Lookup support for serialized scope info. Returns the
   4184   // context slot index for a given slot name if the slot is present; otherwise
   4185   // returns a value < 0. The name must be an internalized string.
   4186   // If the slot is present and mode != NULL, sets *mode to the corresponding
   4187   // mode for that variable.
   4188   static int ContextSlotIndex(Handle<ScopeInfo> scope_info, Handle<String> name,
   4189                               VariableMode* mode, InitializationFlag* init_flag,
   4190                               MaybeAssignedFlag* maybe_assigned_flag);
   4191 
   4192   // Lookup support for serialized scope info. Returns the
   4193   // parameter index for a given parameter name if the parameter is present;
   4194   // otherwise returns a value < 0. The name must be an internalized string.
   4195   int ParameterIndex(String* name);
   4196 
   4197   // Lookup support for serialized scope info. Returns the function context
   4198   // slot index if the function name is present and context-allocated (named
   4199   // function expressions, only), otherwise returns a value < 0. The name
   4200   // must be an internalized string.
   4201   int FunctionContextSlotIndex(String* name, VariableMode* mode);
   4202 
   4203 
   4204   // Copies all the context locals into an object used to materialize a scope.
   4205   static bool CopyContextLocalsToScopeObject(Handle<ScopeInfo> scope_info,
   4206                                              Handle<Context> context,
   4207                                              Handle<JSObject> scope_object);
   4208 
   4209 
   4210   static Handle<ScopeInfo> Create(Scope* scope, Zone* zone);
   4211 
   4212   // Serializes empty scope info.
   4213   static ScopeInfo* Empty(Isolate* isolate);
   4214 
   4215 #ifdef DEBUG
   4216   void Print();
   4217 #endif
   4218 
   4219   // The layout of the static part of a ScopeInfo is as follows. Each entry is
   4220   // numeric and occupies one array slot.
   4221   // 1. A set of properties of the scope
   4222   // 2. The number of parameters. This only applies to function scopes. For
   4223   //    non-function scopes this is 0.
   4224   // 3. The number of non-parameter variables allocated on the stack.
   4225   // 4. The number of non-parameter and parameter variables allocated in the
   4226   //    context.
   4227 #define FOR_EACH_NUMERIC_FIELD(V)          \
   4228   V(Flags)                                 \
   4229   V(ParameterCount)                        \
   4230   V(StackLocalCount)                       \
   4231   V(ContextLocalCount)
   4232 
   4233 #define FIELD_ACCESSORS(name)                            \
   4234   void Set##name(int value) {                            \
   4235     set(k##name, Smi::FromInt(value));                   \
   4236   }                                                      \
   4237   int name() {                                           \
   4238     if (length() > 0) {                                  \
   4239       return Smi::cast(get(k##name))->value();           \
   4240     } else {                                             \
   4241       return 0;                                          \
   4242     }                                                    \
   4243   }
   4244   FOR_EACH_NUMERIC_FIELD(FIELD_ACCESSORS)
   4245 #undef FIELD_ACCESSORS
   4246 
   4247  private:
   4248   enum {
   4249 #define DECL_INDEX(name) k##name,
   4250   FOR_EACH_NUMERIC_FIELD(DECL_INDEX)
   4251 #undef DECL_INDEX
   4252 #undef FOR_EACH_NUMERIC_FIELD
   4253     kVariablePartIndex
   4254   };
   4255 
   4256   // The layout of the variable part of a ScopeInfo is as follows:
   4257   // 1. ParameterEntries:
   4258   //    This part stores the names of the parameters for function scopes. One
   4259   //    slot is used per parameter, so in total this part occupies
   4260   //    ParameterCount() slots in the array. For other scopes than function
   4261   //    scopes ParameterCount() is 0.
   4262   // 2. StackLocalEntries:
   4263   //    Contains the names of local variables that are allocated on the stack,
   4264   //    in increasing order of the stack slot index. One slot is used per stack
   4265   //    local, so in total this part occupies StackLocalCount() slots in the
   4266   //    array.
   4267   // 3. ContextLocalNameEntries:
   4268   //    Contains the names of local variables and parameters that are allocated
   4269   //    in the context. They are stored in increasing order of the context slot
   4270   //    index starting with Context::MIN_CONTEXT_SLOTS. One slot is used per
   4271   //    context local, so in total this part occupies ContextLocalCount() slots
   4272   //    in the array.
   4273   // 4. ContextLocalInfoEntries:
   4274   //    Contains the variable modes and initialization flags corresponding to
   4275   //    the context locals in ContextLocalNameEntries. One slot is used per
   4276   //    context local, so in total this part occupies ContextLocalCount()
   4277   //    slots in the array.
   4278   // 5. FunctionNameEntryIndex:
   4279   //    If the scope belongs to a named function expression this part contains
   4280   //    information about the function variable. It always occupies two array
   4281   //    slots:  a. The name of the function variable.
   4282   //            b. The context or stack slot index for the variable.
   4283   int ParameterEntriesIndex();
   4284   int StackLocalEntriesIndex();
   4285   int ContextLocalNameEntriesIndex();
   4286   int ContextLocalInfoEntriesIndex();
   4287   int FunctionNameEntryIndex();
   4288 
   4289   // Location of the function variable for named function expressions.
   4290   enum FunctionVariableInfo {
   4291     NONE,     // No function name present.
   4292     STACK,    // Function
   4293     CONTEXT,
   4294     UNUSED
   4295   };
   4296 
   4297   // Properties of scopes.
   4298   class ScopeTypeField:        public BitField<ScopeType,            0, 3> {};
   4299   class CallsEvalField:        public BitField<bool,                 3, 1> {};
   4300   class StrictModeField:       public BitField<StrictMode,           4, 1> {};
   4301   class FunctionVariableField: public BitField<FunctionVariableInfo, 5, 2> {};
   4302   class FunctionVariableMode:  public BitField<VariableMode,         7, 3> {};
   4303   class AsmModuleField : public BitField<bool, 10, 1> {};
   4304   class AsmFunctionField : public BitField<bool, 11, 1> {};
   4305 
   4306   // BitFields representing the encoded information for context locals in the
   4307   // ContextLocalInfoEntries part.
   4308   class ContextLocalMode:      public BitField<VariableMode,         0, 3> {};
   4309   class ContextLocalInitFlag:  public BitField<InitializationFlag,   3, 1> {};
   4310   class ContextLocalMaybeAssignedFlag
   4311       : public BitField<MaybeAssignedFlag, 4, 1> {};
   4312 };
   4313 
   4314 
   4315 // The cache for maps used by normalized (dictionary mode) objects.
   4316 // Such maps do not have property descriptors, so a typical program
   4317 // needs very limited number of distinct normalized maps.
   4318 class NormalizedMapCache: public FixedArray {
   4319  public:
   4320   static Handle<NormalizedMapCache> New(Isolate* isolate);
   4321 
   4322   MUST_USE_RESULT MaybeHandle<Map> Get(Handle<Map> fast_map,
   4323                                        PropertyNormalizationMode mode);
   4324   void Set(Handle<Map> fast_map, Handle<Map> normalized_map);
   4325 
   4326   void Clear();
   4327 
   4328   DECLARE_CAST(NormalizedMapCache)
   4329 
   4330   static inline bool IsNormalizedMapCache(const Object* obj);
   4331 
   4332   DECLARE_VERIFIER(NormalizedMapCache)
   4333  private:
   4334   static const int kEntries = 64;
   4335 
   4336   static inline int GetIndex(Handle<Map> map);
   4337 
   4338   // The following declarations hide base class methods.
   4339   Object* get(int index);
   4340   void set(int index, Object* value);
   4341 };
   4342 
   4343 
   4344 // ByteArray represents fixed sized byte arrays.  Used for the relocation info
   4345 // that is attached to code objects.
   4346 class ByteArray: public FixedArrayBase {
   4347  public:
   4348   inline int Size() { return RoundUp(length() + kHeaderSize, kPointerSize); }
   4349 
   4350   // Setter and getter.
   4351   inline byte get(int index);
   4352   inline void set(int index, byte value);
   4353 
   4354   // Treat contents as an int array.
   4355   inline int get_int(int index);
   4356 
   4357   static int SizeFor(int length) {
   4358     return OBJECT_POINTER_ALIGN(kHeaderSize + length);
   4359   }
   4360   // We use byte arrays for free blocks in the heap.  Given a desired size in
   4361   // bytes that is a multiple of the word size and big enough to hold a byte
   4362   // array, this function returns the number of elements a byte array should
   4363   // have.
   4364   static int LengthFor(int size_in_bytes) {
   4365     DCHECK(IsAligned(size_in_bytes, kPointerSize));
   4366     DCHECK(size_in_bytes >= kHeaderSize);
   4367     return size_in_bytes - kHeaderSize;
   4368   }
   4369 
   4370   // Returns data start address.
   4371   inline Address GetDataStartAddress();
   4372 
   4373   // Returns a pointer to the ByteArray object for a given data start address.
   4374   static inline ByteArray* FromDataStartAddress(Address address);
   4375 
   4376   DECLARE_CAST(ByteArray)
   4377 
   4378   // Dispatched behavior.
   4379   inline int ByteArraySize() {
   4380     return SizeFor(this->length());
   4381   }
   4382   DECLARE_PRINTER(ByteArray)
   4383   DECLARE_VERIFIER(ByteArray)
   4384 
   4385   // Layout description.
   4386   static const int kAlignedSize = OBJECT_POINTER_ALIGN(kHeaderSize);
   4387 
   4388   // Maximal memory consumption for a single ByteArray.
   4389   static const int kMaxSize = 512 * MB;
   4390   // Maximal length of a single ByteArray.
   4391   static const int kMaxLength = kMaxSize - kHeaderSize;
   4392 
   4393  private:
   4394   DISALLOW_IMPLICIT_CONSTRUCTORS(ByteArray);
   4395 };
   4396 
   4397 
   4398 // FreeSpace represents fixed sized areas of the heap that are not currently in
   4399 // use.  Used by the heap and GC.
   4400 class FreeSpace: public HeapObject {
   4401  public:
   4402   // [size]: size of the free space including the header.
   4403   inline int size() const;
   4404   inline void set_size(int value);
   4405 
   4406   inline int nobarrier_size() const;
   4407   inline void nobarrier_set_size(int value);
   4408 
   4409   inline int Size() { return size(); }
   4410 
   4411   DECLARE_CAST(FreeSpace)
   4412 
   4413   // Dispatched behavior.
   4414   DECLARE_PRINTER(FreeSpace)
   4415   DECLARE_VERIFIER(FreeSpace)
   4416 
   4417   // Layout description.
   4418   // Size is smi tagged when it is stored.
   4419   static const int kSizeOffset = HeapObject::kHeaderSize;
   4420   static const int kHeaderSize = kSizeOffset + kPointerSize;
   4421 
   4422   static const int kAlignedSize = OBJECT_POINTER_ALIGN(kHeaderSize);
   4423 
   4424  private:
   4425   DISALLOW_IMPLICIT_CONSTRUCTORS(FreeSpace);
   4426 };
   4427 
   4428 
   4429 // V has parameters (Type, type, TYPE, C type, element_size)
   4430 #define TYPED_ARRAYS(V) \
   4431   V(Uint8, uint8, UINT8, uint8_t, 1)                                           \
   4432   V(Int8, int8, INT8, int8_t, 1)                                               \
   4433   V(Uint16, uint16, UINT16, uint16_t, 2)                                       \
   4434   V(Int16, int16, INT16, int16_t, 2)                                           \
   4435   V(Uint32, uint32, UINT32, uint32_t, 4)                                       \
   4436   V(Int32, int32, INT32, int32_t, 4)                                           \
   4437   V(Float32, float32, FLOAT32, float, 4)                                       \
   4438   V(Float64, float64, FLOAT64, double, 8)                                      \
   4439   V(Uint8Clamped, uint8_clamped, UINT8_CLAMPED, uint8_t, 1)
   4440 
   4441 
   4442 
   4443 // An ExternalArray represents a fixed-size array of primitive values
   4444 // which live outside the JavaScript heap. Its subclasses are used to
   4445 // implement the CanvasArray types being defined in the WebGL
   4446 // specification. As of this writing the first public draft is not yet
   4447 // available, but Khronos members can access the draft at:
   4448 //   https://cvs.khronos.org/svn/repos/3dweb/trunk/doc/spec/WebGL-spec.html
   4449 //
   4450 // The semantics of these arrays differ from CanvasPixelArray.
   4451 // Out-of-range values passed to the setter are converted via a C
   4452 // cast, not clamping. Out-of-range indices cause exceptions to be
   4453 // raised rather than being silently ignored.
   4454 class ExternalArray: public FixedArrayBase {
   4455  public:
   4456   inline bool is_the_hole(int index) { return false; }
   4457 
   4458   // [external_pointer]: The pointer to the external memory area backing this
   4459   // external array.
   4460   DECL_ACCESSORS(external_pointer, void)  // Pointer to the data store.
   4461 
   4462   DECLARE_CAST(ExternalArray)
   4463 
   4464   // Maximal acceptable length for an external array.
   4465   static const int kMaxLength = 0x3fffffff;
   4466 
   4467   // ExternalArray headers are not quadword aligned.
   4468   static const int kExternalPointerOffset =
   4469       POINTER_SIZE_ALIGN(FixedArrayBase::kLengthOffset + kPointerSize);
   4470   static const int kHeaderSize = kExternalPointerOffset + kPointerSize;
   4471   static const int kAlignedSize = OBJECT_POINTER_ALIGN(kHeaderSize);
   4472 
   4473  private:
   4474   DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalArray);
   4475 };
   4476 
   4477 
   4478 // A ExternalUint8ClampedArray represents a fixed-size byte array with special
   4479 // semantics used for implementing the CanvasPixelArray object. Please see the
   4480 // specification at:
   4481 
   4482 // http://www.whatwg.org/specs/web-apps/current-work/
   4483 //                      multipage/the-canvas-element.html#canvaspixelarray
   4484 // In particular, write access clamps the value written to 0 or 255 if the
   4485 // value written is outside this range.
   4486 class ExternalUint8ClampedArray: public ExternalArray {
   4487  public:
   4488   inline uint8_t* external_uint8_clamped_pointer();
   4489 
   4490   // Setter and getter.
   4491   inline uint8_t get_scalar(int index);
   4492   static inline Handle<Object> get(Handle<ExternalUint8ClampedArray> array,
   4493                                    int index);
   4494   inline void set(int index, uint8_t value);
   4495 
   4496   // This accessor applies the correct conversion from Smi, HeapNumber
   4497   // and undefined and clamps the converted value between 0 and 255.
   4498   static Handle<Object> SetValue(Handle<ExternalUint8ClampedArray> array,
   4499                                  uint32_t index,
   4500                                  Handle<Object> value);
   4501 
   4502   DECLARE_CAST(ExternalUint8ClampedArray)
   4503 
   4504   // Dispatched behavior.
   4505   DECLARE_PRINTER(ExternalUint8ClampedArray)
   4506   DECLARE_VERIFIER(ExternalUint8ClampedArray)
   4507 
   4508  private:
   4509   DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalUint8ClampedArray);
   4510 };
   4511 
   4512 
   4513 class ExternalInt8Array: public ExternalArray {
   4514  public:
   4515   // Setter and getter.
   4516   inline int8_t get_scalar(int index);
   4517   static inline Handle<Object> get(Handle<ExternalInt8Array> array, int index);
   4518   inline void set(int index, int8_t value);
   4519 
   4520   // This accessor applies the correct conversion from Smi, HeapNumber
   4521   // and undefined.
   4522   static Handle<Object> SetValue(Handle<ExternalInt8Array> array,
   4523                                  uint32_t index,
   4524                                  Handle<Object> value);
   4525 
   4526   DECLARE_CAST(ExternalInt8Array)
   4527 
   4528   // Dispatched behavior.
   4529   DECLARE_PRINTER(ExternalInt8Array)
   4530   DECLARE_VERIFIER(ExternalInt8Array)
   4531 
   4532  private:
   4533   DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalInt8Array);
   4534 };
   4535 
   4536 
   4537 class ExternalUint8Array: public ExternalArray {
   4538  public:
   4539   // Setter and getter.
   4540   inline uint8_t get_scalar(int index);
   4541   static inline Handle<Object> get(Handle<ExternalUint8Array> array, int index);
   4542   inline void set(int index, uint8_t value);
   4543 
   4544   // This accessor applies the correct conversion from Smi, HeapNumber
   4545   // and undefined.
   4546   static Handle<Object> SetValue(Handle<ExternalUint8Array> array,
   4547                                  uint32_t index,
   4548                                  Handle<Object> value);
   4549 
   4550   DECLARE_CAST(ExternalUint8Array)
   4551 
   4552   // Dispatched behavior.
   4553   DECLARE_PRINTER(ExternalUint8Array)
   4554   DECLARE_VERIFIER(ExternalUint8Array)
   4555 
   4556  private:
   4557   DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalUint8Array);
   4558 };
   4559 
   4560 
   4561 class ExternalInt16Array: public ExternalArray {
   4562  public:
   4563   // Setter and getter.
   4564   inline int16_t get_scalar(int index);
   4565   static inline Handle<Object> get(Handle<ExternalInt16Array> array, int index);
   4566   inline void set(int index, int16_t value);
   4567 
   4568   // This accessor applies the correct conversion from Smi, HeapNumber
   4569   // and undefined.
   4570   static Handle<Object> SetValue(Handle<ExternalInt16Array> array,
   4571                                  uint32_t index,
   4572                                  Handle<Object> value);
   4573 
   4574   DECLARE_CAST(ExternalInt16Array)
   4575 
   4576   // Dispatched behavior.
   4577   DECLARE_PRINTER(ExternalInt16Array)
   4578   DECLARE_VERIFIER(ExternalInt16Array)
   4579 
   4580  private:
   4581   DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalInt16Array);
   4582 };
   4583 
   4584 
   4585 class ExternalUint16Array: public ExternalArray {
   4586  public:
   4587   // Setter and getter.
   4588   inline uint16_t get_scalar(int index);
   4589   static inline Handle<Object> get(Handle<ExternalUint16Array> array,
   4590                                    int index);
   4591   inline void set(int index, uint16_t value);
   4592 
   4593   // This accessor applies the correct conversion from Smi, HeapNumber
   4594   // and undefined.
   4595   static Handle<Object> SetValue(Handle<ExternalUint16Array> array,
   4596                                  uint32_t index,
   4597                                  Handle<Object> value);
   4598 
   4599   DECLARE_CAST(ExternalUint16Array)
   4600 
   4601   // Dispatched behavior.
   4602   DECLARE_PRINTER(ExternalUint16Array)
   4603   DECLARE_VERIFIER(ExternalUint16Array)
   4604 
   4605  private:
   4606   DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalUint16Array);
   4607 };
   4608 
   4609 
   4610 class ExternalInt32Array: public ExternalArray {
   4611  public:
   4612   // Setter and getter.
   4613   inline int32_t get_scalar(int index);
   4614   static inline Handle<Object> get(Handle<ExternalInt32Array> array, int index);
   4615   inline void set(int index, int32_t value);
   4616 
   4617   // This accessor applies the correct conversion from Smi, HeapNumber
   4618   // and undefined.
   4619   static Handle<Object> SetValue(Handle<ExternalInt32Array> array,
   4620                                  uint32_t index,
   4621                                  Handle<Object> value);
   4622 
   4623   DECLARE_CAST(ExternalInt32Array)
   4624 
   4625   // Dispatched behavior.
   4626   DECLARE_PRINTER(ExternalInt32Array)
   4627   DECLARE_VERIFIER(ExternalInt32Array)
   4628 
   4629  private:
   4630   DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalInt32Array);
   4631 };
   4632 
   4633 
   4634 class ExternalUint32Array: public ExternalArray {
   4635  public:
   4636   // Setter and getter.
   4637   inline uint32_t get_scalar(int index);
   4638   static inline Handle<Object> get(Handle<ExternalUint32Array> array,
   4639                                    int index);
   4640   inline void set(int index, uint32_t value);
   4641 
   4642   // This accessor applies the correct conversion from Smi, HeapNumber
   4643   // and undefined.
   4644   static Handle<Object> SetValue(Handle<ExternalUint32Array> array,
   4645                                  uint32_t index,
   4646                                  Handle<Object> value);
   4647 
   4648   DECLARE_CAST(ExternalUint32Array)
   4649 
   4650   // Dispatched behavior.
   4651   DECLARE_PRINTER(ExternalUint32Array)
   4652   DECLARE_VERIFIER(ExternalUint32Array)
   4653 
   4654  private:
   4655   DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalUint32Array);
   4656 };
   4657 
   4658 
   4659 class ExternalFloat32Array: public ExternalArray {
   4660  public:
   4661   // Setter and getter.
   4662   inline float get_scalar(int index);
   4663   static inline Handle<Object> get(Handle<ExternalFloat32Array> array,
   4664                                    int index);
   4665   inline void set(int index, float value);
   4666 
   4667   // This accessor applies the correct conversion from Smi, HeapNumber
   4668   // and undefined.
   4669   static Handle<Object> SetValue(Handle<ExternalFloat32Array> array,
   4670                                  uint32_t index,
   4671                                  Handle<Object> value);
   4672 
   4673   DECLARE_CAST(ExternalFloat32Array)
   4674 
   4675   // Dispatched behavior.
   4676   DECLARE_PRINTER(ExternalFloat32Array)
   4677   DECLARE_VERIFIER(ExternalFloat32Array)
   4678 
   4679  private:
   4680   DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalFloat32Array);
   4681 };
   4682 
   4683 
   4684 class ExternalFloat64Array: public ExternalArray {
   4685  public:
   4686   // Setter and getter.
   4687   inline double get_scalar(int index);
   4688   static inline Handle<Object> get(Handle<ExternalFloat64Array> array,
   4689                                    int index);
   4690   inline void set(int index, double value);
   4691 
   4692   // This accessor applies the correct conversion from Smi, HeapNumber
   4693   // and undefined.
   4694   static Handle<Object> SetValue(Handle<ExternalFloat64Array> array,
   4695                                  uint32_t index,
   4696                                  Handle<Object> value);
   4697 
   4698   DECLARE_CAST(ExternalFloat64Array)
   4699 
   4700   // Dispatched behavior.
   4701   DECLARE_PRINTER(ExternalFloat64Array)
   4702   DECLARE_VERIFIER(ExternalFloat64Array)
   4703 
   4704  private:
   4705   DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalFloat64Array);
   4706 };
   4707 
   4708 
   4709 class FixedTypedArrayBase: public FixedArrayBase {
   4710  public:
   4711   DECLARE_CAST(FixedTypedArrayBase)
   4712 
   4713   static const int kDataOffset = kHeaderSize;
   4714 
   4715   inline int size();
   4716 
   4717   inline int TypedArraySize(InstanceType type);
   4718 
   4719   // Use with care: returns raw pointer into heap.
   4720   inline void* DataPtr();
   4721 
   4722   inline int DataSize();
   4723 
   4724  private:
   4725   inline int DataSize(InstanceType type);
   4726 
   4727   DISALLOW_IMPLICIT_CONSTRUCTORS(FixedTypedArrayBase);
   4728 };
   4729 
   4730 
   4731 template <class Traits>
   4732 class FixedTypedArray: public FixedTypedArrayBase {
   4733  public:
   4734   typedef typename Traits::ElementType ElementType;
   4735   static const InstanceType kInstanceType = Traits::kInstanceType;
   4736 
   4737   DECLARE_CAST(FixedTypedArray<Traits>)
   4738 
   4739   static inline int ElementOffset(int index) {
   4740     return kDataOffset + index * sizeof(ElementType);
   4741   }
   4742 
   4743   static inline int SizeFor(int length) {
   4744     return ElementOffset(length);
   4745   }
   4746 
   4747   inline ElementType get_scalar(int index);
   4748   static inline Handle<Object> get(Handle<FixedTypedArray> array, int index);
   4749   inline void set(int index, ElementType value);
   4750 
   4751   static inline ElementType from_int(int value);
   4752   static inline ElementType from_double(double value);
   4753 
   4754   // This accessor applies the correct conversion from Smi, HeapNumber
   4755   // and undefined.
   4756   static Handle<Object> SetValue(Handle<FixedTypedArray<Traits> > array,
   4757                                  uint32_t index,
   4758                                  Handle<Object> value);
   4759 
   4760   DECLARE_PRINTER(FixedTypedArray)
   4761   DECLARE_VERIFIER(FixedTypedArray)
   4762 
   4763  private:
   4764   DISALLOW_IMPLICIT_CONSTRUCTORS(FixedTypedArray);
   4765 };
   4766 
   4767 #define FIXED_TYPED_ARRAY_TRAITS(Type, type, TYPE, elementType, size)         \
   4768   class Type##ArrayTraits {                                                   \
   4769    public:   /* NOLINT */                                                     \
   4770     typedef elementType ElementType;                                          \
   4771     static const InstanceType kInstanceType = FIXED_##TYPE##_ARRAY_TYPE;      \
   4772     static const char* Designator() { return #type " array"; }                \
   4773     static inline Handle<Object> ToHandle(Isolate* isolate,                   \
   4774                                           elementType scalar);                \
   4775     static inline elementType defaultValue();                                 \
   4776   };                                                                          \
   4777                                                                               \
   4778   typedef FixedTypedArray<Type##ArrayTraits> Fixed##Type##Array;
   4779 
   4780 TYPED_ARRAYS(FIXED_TYPED_ARRAY_TRAITS)
   4781 
   4782 #undef FIXED_TYPED_ARRAY_TRAITS
   4783 
   4784 // DeoptimizationInputData is a fixed array used to hold the deoptimization
   4785 // data for code generated by the Hydrogen/Lithium compiler.  It also
   4786 // contains information about functions that were inlined.  If N different
   4787 // functions were inlined then first N elements of the literal array will
   4788 // contain these functions.
   4789 //
   4790 // It can be empty.
   4791 class DeoptimizationInputData: public FixedArray {
   4792  public:
   4793   // Layout description.  Indices in the array.
   4794   static const int kTranslationByteArrayIndex = 0;
   4795   static const int kInlinedFunctionCountIndex = 1;
   4796   static const int kLiteralArrayIndex = 2;
   4797   static const int kOsrAstIdIndex = 3;
   4798   static const int kOsrPcOffsetIndex = 4;
   4799   static const int kOptimizationIdIndex = 5;
   4800   static const int kSharedFunctionInfoIndex = 6;
   4801   static const int kFirstDeoptEntryIndex = 7;
   4802 
   4803   // Offsets of deopt entry elements relative to the start of the entry.
   4804   static const int kAstIdRawOffset = 0;
   4805   static const int kTranslationIndexOffset = 1;
   4806   static const int kArgumentsStackHeightOffset = 2;
   4807   static const int kPcOffset = 3;
   4808   static const int kDeoptEntrySize = 4;
   4809 
   4810   // Simple element accessors.
   4811 #define DEFINE_ELEMENT_ACCESSORS(name, type)      \
   4812   type* name() {                                  \
   4813     return type::cast(get(k##name##Index));       \
   4814   }                                               \
   4815   void Set##name(type* value) {                   \
   4816     set(k##name##Index, value);                   \
   4817   }
   4818 
   4819   DEFINE_ELEMENT_ACCESSORS(TranslationByteArray, ByteArray)
   4820   DEFINE_ELEMENT_ACCESSORS(InlinedFunctionCount, Smi)
   4821   DEFINE_ELEMENT_ACCESSORS(LiteralArray, FixedArray)
   4822   DEFINE_ELEMENT_ACCESSORS(OsrAstId, Smi)
   4823   DEFINE_ELEMENT_ACCESSORS(OsrPcOffset, Smi)
   4824   DEFINE_ELEMENT_ACCESSORS(OptimizationId, Smi)
   4825   DEFINE_ELEMENT_ACCESSORS(SharedFunctionInfo, Object)
   4826 
   4827 #undef DEFINE_ELEMENT_ACCESSORS
   4828 
   4829   // Accessors for elements of the ith deoptimization entry.
   4830 #define DEFINE_ENTRY_ACCESSORS(name, type)                      \
   4831   type* name(int i) {                                           \
   4832     return type::cast(get(IndexForEntry(i) + k##name##Offset)); \
   4833   }                                                             \
   4834   void Set##name(int i, type* value) {                          \
   4835     set(IndexForEntry(i) + k##name##Offset, value);             \
   4836   }
   4837 
   4838   DEFINE_ENTRY_ACCESSORS(AstIdRaw, Smi)
   4839   DEFINE_ENTRY_ACCESSORS(TranslationIndex, Smi)
   4840   DEFINE_ENTRY_ACCESSORS(ArgumentsStackHeight, Smi)
   4841   DEFINE_ENTRY_ACCESSORS(Pc, Smi)
   4842 
   4843 #undef DEFINE_DEOPT_ENTRY_ACCESSORS
   4844 
   4845   BailoutId AstId(int i) {
   4846     return BailoutId(AstIdRaw(i)->value());
   4847   }
   4848 
   4849   void SetAstId(int i, BailoutId value) {
   4850     SetAstIdRaw(i, Smi::FromInt(value.ToInt()));
   4851   }
   4852 
   4853   int DeoptCount() {
   4854     return (length() - kFirstDeoptEntryIndex) / kDeoptEntrySize;
   4855   }
   4856 
   4857   // Allocates a DeoptimizationInputData.
   4858   static Handle<DeoptimizationInputData> New(Isolate* isolate,
   4859                                              int deopt_entry_count,
   4860                                              PretenureFlag pretenure);
   4861 
   4862   DECLARE_CAST(DeoptimizationInputData)
   4863 
   4864 #ifdef ENABLE_DISASSEMBLER
   4865   void DeoptimizationInputDataPrint(OStream& os);  // NOLINT
   4866 #endif
   4867 
   4868  private:
   4869   static int IndexForEntry(int i) {
   4870     return kFirstDeoptEntryIndex + (i * kDeoptEntrySize);
   4871   }
   4872 
   4873 
   4874   static int LengthFor(int entry_count) { return IndexForEntry(entry_count); }
   4875 };
   4876 
   4877 
   4878 // DeoptimizationOutputData is a fixed array used to hold the deoptimization
   4879 // data for code generated by the full compiler.
   4880 // The format of the these objects is
   4881 //   [i * 2]: Ast ID for ith deoptimization.
   4882 //   [i * 2 + 1]: PC and state of ith deoptimization
   4883 class DeoptimizationOutputData: public FixedArray {
   4884  public:
   4885   int DeoptPoints() { return length() / 2; }
   4886 
   4887   BailoutId AstId(int index) {
   4888     return BailoutId(Smi::cast(get(index * 2))->value());
   4889   }
   4890 
   4891   void SetAstId(int index, BailoutId id) {
   4892     set(index * 2, Smi::FromInt(id.ToInt()));
   4893   }
   4894 
   4895   Smi* PcAndState(int index) { return Smi::cast(get(1 + index * 2)); }
   4896   void SetPcAndState(int index, Smi* offset) { set(1 + index * 2, offset); }
   4897 
   4898   static int LengthOfFixedArray(int deopt_points) {
   4899     return deopt_points * 2;
   4900   }
   4901 
   4902   // Allocates a DeoptimizationOutputData.
   4903   static Handle<DeoptimizationOutputData> New(Isolate* isolate,
   4904                                               int number_of_deopt_points,
   4905                                               PretenureFlag pretenure);
   4906 
   4907   DECLARE_CAST(DeoptimizationOutputData)
   4908 
   4909 #if defined(OBJECT_PRINT) || defined(ENABLE_DISASSEMBLER)
   4910   void DeoptimizationOutputDataPrint(OStream& os);  // NOLINT
   4911 #endif
   4912 };
   4913 
   4914 
   4915 // Forward declaration.
   4916 class Cell;
   4917 class PropertyCell;
   4918 class SafepointEntry;
   4919 class TypeFeedbackInfo;
   4920 
   4921 // Code describes objects with on-the-fly generated machine code.
   4922 class Code: public HeapObject {
   4923  public:
   4924   // Opaque data type for encapsulating code flags like kind, inline
   4925   // cache state, and arguments count.
   4926   typedef uint32_t Flags;
   4927 
   4928 #define NON_IC_KIND_LIST(V) \
   4929   V(FUNCTION)               \
   4930   V(OPTIMIZED_FUNCTION)     \
   4931   V(STUB)                   \
   4932   V(HANDLER)                \
   4933   V(BUILTIN)                \
   4934   V(REGEXP)
   4935 
   4936 #define IC_KIND_LIST(V) \
   4937   V(LOAD_IC)            \
   4938   V(KEYED_LOAD_IC)      \
   4939   V(CALL_IC)            \
   4940   V(STORE_IC)           \
   4941   V(KEYED_STORE_IC)     \
   4942   V(BINARY_OP_IC)       \
   4943   V(COMPARE_IC)         \
   4944   V(COMPARE_NIL_IC)     \
   4945   V(TO_BOOLEAN_IC)
   4946 
   4947 #define CODE_KIND_LIST(V) \
   4948   NON_IC_KIND_LIST(V)     \
   4949   IC_KIND_LIST(V)
   4950 
   4951   enum Kind {
   4952 #define DEFINE_CODE_KIND_ENUM(name) name,
   4953     CODE_KIND_LIST(DEFINE_CODE_KIND_ENUM)
   4954 #undef DEFINE_CODE_KIND_ENUM
   4955     NUMBER_OF_KINDS
   4956   };
   4957 
   4958   // No more than 16 kinds. The value is currently encoded in four bits in
   4959   // Flags.
   4960   STATIC_ASSERT(NUMBER_OF_KINDS <= 16);
   4961 
   4962   static const char* Kind2String(Kind kind);
   4963 
   4964   // Types of stubs.
   4965   enum StubType {
   4966     NORMAL,
   4967     FAST
   4968   };
   4969 
   4970   static const int kPrologueOffsetNotSet = -1;
   4971 
   4972 #ifdef ENABLE_DISASSEMBLER
   4973   // Printing
   4974   static const char* ICState2String(InlineCacheState state);
   4975   static const char* StubType2String(StubType type);
   4976   static void PrintExtraICState(OStream& os,  // NOLINT
   4977                                 Kind kind, ExtraICState extra);
   4978   void Disassemble(const char* name, OStream& os);  // NOLINT
   4979 #endif  // ENABLE_DISASSEMBLER
   4980 
   4981   // [instruction_size]: Size of the native instructions
   4982   inline int instruction_size() const;
   4983   inline void set_instruction_size(int value);
   4984 
   4985   // [relocation_info]: Code relocation information
   4986   DECL_ACCESSORS(relocation_info, ByteArray)
   4987   void InvalidateRelocation();
   4988   void InvalidateEmbeddedObjects();
   4989 
   4990   // [handler_table]: Fixed array containing offsets of exception handlers.
   4991   DECL_ACCESSORS(handler_table, FixedArray)
   4992 
   4993   // [deoptimization_data]: Array containing data for deopt.
   4994   DECL_ACCESSORS(deoptimization_data, FixedArray)
   4995 
   4996   // [raw_type_feedback_info]: This field stores various things, depending on
   4997   // the kind of the code object.
   4998   //   FUNCTION           => type feedback information.
   4999   //   STUB and ICs       => major/minor key as Smi.
   5000   DECL_ACCESSORS(raw_type_feedback_info, Object)
   5001   inline Object* type_feedback_info();
   5002   inline void set_type_feedback_info(
   5003       Object* value, WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
   5004   inline uint32_t stub_key();
   5005   inline void set_stub_key(uint32_t key);
   5006 
   5007   // [next_code_link]: Link for lists of optimized or deoptimized code.
   5008   // Note that storage for this field is overlapped with typefeedback_info.
   5009   DECL_ACCESSORS(next_code_link, Object)
   5010 
   5011   // [gc_metadata]: Field used to hold GC related metadata. The contents of this
   5012   // field does not have to be traced during garbage collection since
   5013   // it is only used by the garbage collector itself.
   5014   DECL_ACCESSORS(gc_metadata, Object)
   5015 
   5016   // [ic_age]: Inline caching age: the value of the Heap::global_ic_age
   5017   // at the moment when this object was created.
   5018   inline void set_ic_age(int count);
   5019   inline int ic_age() const;
   5020 
   5021   // [prologue_offset]: Offset of the function prologue, used for aging
   5022   // FUNCTIONs and OPTIMIZED_FUNCTIONs.
   5023   inline int prologue_offset() const;
   5024   inline void set_prologue_offset(int offset);
   5025 
   5026   // Unchecked accessors to be used during GC.
   5027   inline ByteArray* unchecked_relocation_info();
   5028 
   5029   inline int relocation_size();
   5030 
   5031   // [flags]: Various code flags.
   5032   inline Flags flags();
   5033   inline void set_flags(Flags flags);
   5034 
   5035   // [flags]: Access to specific code flags.
   5036   inline Kind kind();
   5037   inline InlineCacheState ic_state();  // Only valid for IC stubs.
   5038   inline ExtraICState extra_ic_state();  // Only valid for IC stubs.
   5039 
   5040   inline StubType type();  // Only valid for monomorphic IC stubs.
   5041 
   5042   // Testers for IC stub kinds.
   5043   inline bool is_inline_cache_stub();
   5044   inline bool is_debug_stub();
   5045   inline bool is_handler() { return kind() == HANDLER; }
   5046   inline bool is_load_stub() { return kind() == LOAD_IC; }
   5047   inline bool is_keyed_load_stub() { return kind() == KEYED_LOAD_IC; }
   5048   inline bool is_store_stub() { return kind() == STORE_IC; }
   5049   inline bool is_keyed_store_stub() { return kind() == KEYED_STORE_IC; }
   5050   inline bool is_call_stub() { return kind() == CALL_IC; }
   5051   inline bool is_binary_op_stub() { return kind() == BINARY_OP_IC; }
   5052   inline bool is_compare_ic_stub() { return kind() == COMPARE_IC; }
   5053   inline bool is_compare_nil_ic_stub() { return kind() == COMPARE_NIL_IC; }
   5054   inline bool is_to_boolean_ic_stub() { return kind() == TO_BOOLEAN_IC; }
   5055   inline bool is_keyed_stub();
   5056   inline bool is_optimized_code() { return kind() == OPTIMIZED_FUNCTION; }
   5057   inline bool is_weak_stub();
   5058   inline void mark_as_weak_stub();
   5059   inline bool is_invalidated_weak_stub();
   5060   inline void mark_as_invalidated_weak_stub();
   5061 
   5062   inline bool CanBeWeakStub() {
   5063     Kind k = kind();
   5064     return (k == LOAD_IC || k == STORE_IC || k == KEYED_LOAD_IC ||
   5065             k == KEYED_STORE_IC || k == COMPARE_NIL_IC) &&
   5066            ic_state() == MONOMORPHIC;
   5067   }
   5068 
   5069   inline bool IsCodeStubOrIC();
   5070 
   5071   inline void set_raw_kind_specific_flags1(int value);
   5072   inline void set_raw_kind_specific_flags2(int value);
   5073 
   5074   // [is_crankshafted]: For kind STUB or ICs, tells whether or not a code
   5075   // object was generated by either the hydrogen or the TurboFan optimizing
   5076   // compiler (but it may not be an optimized function).
   5077   inline bool is_crankshafted();
   5078   inline bool is_hydrogen_stub();  // Crankshafted, but not a function.
   5079   inline void set_is_crankshafted(bool value);
   5080 
   5081   // [is_turbofanned]: For kind STUB or OPTIMIZED_FUNCTION, tells whether the
   5082   // code object was generated by the TurboFan optimizing compiler.
   5083   inline bool is_turbofanned();
   5084   inline void set_is_turbofanned(bool value);
   5085 
   5086   // [optimizable]: For FUNCTION kind, tells if it is optimizable.
   5087   inline bool optimizable();
   5088   inline void set_optimizable(bool value);
   5089 
   5090   // [has_deoptimization_support]: For FUNCTION kind, tells if it has
   5091   // deoptimization support.
   5092   inline bool has_deoptimization_support();
   5093   inline void set_has_deoptimization_support(bool value);
   5094 
   5095   // [has_debug_break_slots]: For FUNCTION kind, tells if it has
   5096   // been compiled with debug break slots.
   5097   inline bool has_debug_break_slots();
   5098   inline void set_has_debug_break_slots(bool value);
   5099 
   5100   // [compiled_with_optimizing]: For FUNCTION kind, tells if it has
   5101   // been compiled with IsOptimizing set to true.
   5102   inline bool is_compiled_optimizable();
   5103   inline void set_compiled_optimizable(bool value);
   5104 
   5105   // [allow_osr_at_loop_nesting_level]: For FUNCTION kind, tells for
   5106   // how long the function has been marked for OSR and therefore which
   5107   // level of loop nesting we are willing to do on-stack replacement
   5108   // for.
   5109   inline void set_allow_osr_at_loop_nesting_level(int level);
   5110   inline int allow_osr_at_loop_nesting_level();
   5111 
   5112   // [profiler_ticks]: For FUNCTION kind, tells for how many profiler ticks
   5113   // the code object was seen on the stack with no IC patching going on.
   5114   inline int profiler_ticks();
   5115   inline void set_profiler_ticks(int ticks);
   5116 
   5117   // [builtin_index]: For BUILTIN kind, tells which builtin index it has.
   5118   inline int builtin_index();
   5119   inline void set_builtin_index(int id);
   5120 
   5121   // [stack_slots]: For kind OPTIMIZED_FUNCTION, the number of stack slots
   5122   // reserved in the code prologue.
   5123   inline unsigned stack_slots();
   5124   inline void set_stack_slots(unsigned slots);
   5125 
   5126   // [safepoint_table_start]: For kind OPTIMIZED_FUNCTION, the offset in
   5127   // the instruction stream where the safepoint table starts.
   5128   inline unsigned safepoint_table_offset();
   5129   inline void set_safepoint_table_offset(unsigned offset);
   5130 
   5131   // [back_edge_table_start]: For kind FUNCTION, the offset in the
   5132   // instruction stream where the back edge table starts.
   5133   inline unsigned back_edge_table_offset();
   5134   inline void set_back_edge_table_offset(unsigned offset);
   5135 
   5136   inline bool back_edges_patched_for_osr();
   5137 
   5138   // [to_boolean_foo]: For kind TO_BOOLEAN_IC tells what state the stub is in.
   5139   inline byte to_boolean_state();
   5140 
   5141   // [has_function_cache]: For kind STUB tells whether there is a function
   5142   // cache is passed to the stub.
   5143   inline bool has_function_cache();
   5144   inline void set_has_function_cache(bool flag);
   5145 
   5146 
   5147   // [marked_for_deoptimization]: For kind OPTIMIZED_FUNCTION tells whether
   5148   // the code is going to be deoptimized because of dead embedded maps.
   5149   inline bool marked_for_deoptimization();
   5150   inline void set_marked_for_deoptimization(bool flag);
   5151 
   5152   // [constant_pool]: The constant pool for this function.
   5153   inline ConstantPoolArray* constant_pool();
   5154   inline void set_constant_pool(Object* constant_pool);
   5155 
   5156   // Get the safepoint entry for the given pc.
   5157   SafepointEntry GetSafepointEntry(Address pc);
   5158 
   5159   // Find an object in a stub with a specified map
   5160   Object* FindNthObject(int n, Map* match_map);
   5161 
   5162   // Find the first allocation site in an IC stub.
   5163   AllocationSite* FindFirstAllocationSite();
   5164 
   5165   // Find the first map in an IC stub.
   5166   Map* FindFirstMap();
   5167   void FindAllMaps(MapHandleList* maps);
   5168 
   5169   // Find the first handler in an IC stub.
   5170   Code* FindFirstHandler();
   5171 
   5172   // Find |length| handlers and put them into |code_list|. Returns false if not
   5173   // enough handlers can be found.
   5174   bool FindHandlers(CodeHandleList* code_list, int length = -1);
   5175 
   5176   // Find the handler for |map|.
   5177   MaybeHandle<Code> FindHandlerForMap(Map* map);
   5178 
   5179   // Find the first name in an IC stub.
   5180   Name* FindFirstName();
   5181 
   5182   class FindAndReplacePattern;
   5183   // For each (map-to-find, object-to-replace) pair in the pattern, this
   5184   // function replaces the corresponding placeholder in the code with the
   5185   // object-to-replace. The function assumes that pairs in the pattern come in
   5186   // the same order as the placeholders in the code.
   5187   void FindAndReplace(const FindAndReplacePattern& pattern);
   5188 
   5189   // The entire code object including its header is copied verbatim to the
   5190   // snapshot so that it can be written in one, fast, memcpy during
   5191   // deserialization. The deserializer will overwrite some pointers, rather
   5192   // like a runtime linker, but the random allocation addresses used in the
   5193   // mksnapshot process would still be present in the unlinked snapshot data,
   5194   // which would make snapshot production non-reproducible. This method wipes
   5195   // out the to-be-overwritten header data for reproducible snapshots.
   5196   inline void WipeOutHeader();
   5197 
   5198   // Flags operations.
   5199   static inline Flags ComputeFlags(
   5200       Kind kind, InlineCacheState ic_state = UNINITIALIZED,
   5201       ExtraICState extra_ic_state = kNoExtraICState, StubType type = NORMAL,
   5202       CacheHolderFlag holder = kCacheOnReceiver);
   5203 
   5204   static inline Flags ComputeMonomorphicFlags(
   5205       Kind kind, ExtraICState extra_ic_state = kNoExtraICState,
   5206       CacheHolderFlag holder = kCacheOnReceiver, StubType type = NORMAL);
   5207 
   5208   static inline Flags ComputeHandlerFlags(
   5209       Kind handler_kind, StubType type = NORMAL,
   5210       CacheHolderFlag holder = kCacheOnReceiver);
   5211 
   5212   static inline InlineCacheState ExtractICStateFromFlags(Flags flags);
   5213   static inline StubType ExtractTypeFromFlags(Flags flags);
   5214   static inline CacheHolderFlag ExtractCacheHolderFromFlags(Flags flags);
   5215   static inline Kind ExtractKindFromFlags(Flags flags);
   5216   static inline ExtraICState ExtractExtraICStateFromFlags(Flags flags);
   5217 
   5218   static inline Flags RemoveTypeFromFlags(Flags flags);
   5219   static inline Flags RemoveTypeAndHolderFromFlags(Flags flags);
   5220 
   5221   // Convert a target address into a code object.
   5222   static inline Code* GetCodeFromTargetAddress(Address address);
   5223 
   5224   // Convert an entry address into an object.
   5225   static inline Object* GetObjectFromEntryAddress(Address location_of_address);
   5226 
   5227   // Returns the address of the first instruction.
   5228   inline byte* instruction_start();
   5229 
   5230   // Returns the address right after the last instruction.
   5231   inline byte* instruction_end();
   5232 
   5233   // Returns the size of the instructions, padding, and relocation information.
   5234   inline int body_size();
   5235 
   5236   // Returns the address of the first relocation info (read backwards!).
   5237   inline byte* relocation_start();
   5238 
   5239   // Code entry point.
   5240   inline byte* entry();
   5241 
   5242   // Returns true if pc is inside this object's instructions.
   5243   inline bool contains(byte* pc);
   5244 
   5245   // Relocate the code by delta bytes. Called to signal that this code
   5246   // object has been moved by delta bytes.
   5247   void Relocate(intptr_t delta);
   5248 
   5249   // Migrate code described by desc.
   5250   void CopyFrom(const CodeDesc& desc);
   5251 
   5252   // Returns the object size for a given body (used for allocation).
   5253   static int SizeFor(int body_size) {
   5254     DCHECK_SIZE_TAG_ALIGNED(body_size);
   5255     return RoundUp(kHeaderSize + body_size, kCodeAlignment);
   5256   }
   5257 
   5258   // Calculate the size of the code object to report for log events. This takes
   5259   // the layout of the code object into account.
   5260   int ExecutableSize() {
   5261     // Check that the assumptions about the layout of the code object holds.
   5262     DCHECK_EQ(static_cast<int>(instruction_start() - address()),
   5263               Code::kHeaderSize);
   5264     return instruction_size() + Code::kHeaderSize;
   5265   }
   5266 
   5267   // Locating source position.
   5268   int SourcePosition(Address pc);
   5269   int SourceStatementPosition(Address pc);
   5270 
   5271   DECLARE_CAST(Code)
   5272 
   5273   // Dispatched behavior.
   5274   int CodeSize() { return SizeFor(body_size()); }
   5275   inline void CodeIterateBody(ObjectVisitor* v);
   5276 
   5277   template<typename StaticVisitor>
   5278   inline void CodeIterateBody(Heap* heap);
   5279 
   5280   DECLARE_PRINTER(Code)
   5281   DECLARE_VERIFIER(Code)
   5282 
   5283   void ClearInlineCaches();
   5284   void ClearInlineCaches(Kind kind);
   5285 
   5286   BailoutId TranslatePcOffsetToAstId(uint32_t pc_offset);
   5287   uint32_t TranslateAstIdToPcOffset(BailoutId ast_id);
   5288 
   5289 #define DECLARE_CODE_AGE_ENUM(X) k##X##CodeAge,
   5290   enum Age {
   5291     kNotExecutedCodeAge = -2,
   5292     kExecutedOnceCodeAge = -1,
   5293     kNoAgeCodeAge = 0,
   5294     CODE_AGE_LIST(DECLARE_CODE_AGE_ENUM)
   5295     kAfterLastCodeAge,
   5296     kFirstCodeAge = kNotExecutedCodeAge,
   5297     kLastCodeAge = kAfterLastCodeAge - 1,
   5298     kCodeAgeCount = kAfterLastCodeAge - kNotExecutedCodeAge - 1,
   5299     kIsOldCodeAge = kSexagenarianCodeAge,
   5300     kPreAgedCodeAge = kIsOldCodeAge - 1
   5301   };
   5302 #undef DECLARE_CODE_AGE_ENUM
   5303 
   5304   // Code aging.  Indicates how many full GCs this code has survived without
   5305   // being entered through the prologue.  Used to determine when it is
   5306   // relatively safe to flush this code object and replace it with the lazy
   5307   // compilation stub.
   5308   static void MakeCodeAgeSequenceYoung(byte* sequence, Isolate* isolate);
   5309   static void MarkCodeAsExecuted(byte* sequence, Isolate* isolate);
   5310   void MakeOlder(MarkingParity);
   5311   static bool IsYoungSequence(Isolate* isolate, byte* sequence);
   5312   bool IsOld();
   5313   Age GetAge();
   5314   // Gets the raw code age, including psuedo code-age values such as
   5315   // kNotExecutedCodeAge and kExecutedOnceCodeAge.
   5316   Age GetRawAge();
   5317   static inline Code* GetPreAgedCodeAgeStub(Isolate* isolate) {
   5318     return GetCodeAgeStub(isolate, kNotExecutedCodeAge, NO_MARKING_PARITY);
   5319   }
   5320 
   5321   void PrintDeoptLocation(FILE* out, int bailout_id);
   5322   bool CanDeoptAt(Address pc);
   5323 
   5324 #ifdef VERIFY_HEAP
   5325   void VerifyEmbeddedObjectsDependency();
   5326 #endif
   5327 
   5328   inline bool CanContainWeakObjects() {
   5329     return is_optimized_code() || is_weak_stub();
   5330   }
   5331 
   5332   inline bool IsWeakObject(Object* object) {
   5333     return (is_optimized_code() && !is_turbofanned() &&
   5334             IsWeakObjectInOptimizedCode(object)) ||
   5335            (is_weak_stub() && IsWeakObjectInIC(object));
   5336   }
   5337 
   5338   static inline bool IsWeakObjectInOptimizedCode(Object* object);
   5339   static inline bool IsWeakObjectInIC(Object* object);
   5340 
   5341   // Max loop nesting marker used to postpose OSR. We don't take loop
   5342   // nesting that is deeper than 5 levels into account.
   5343   static const int kMaxLoopNestingMarker = 6;
   5344 
   5345   // Layout description.
   5346   static const int kInstructionSizeOffset = HeapObject::kHeaderSize;
   5347   static const int kRelocationInfoOffset = kInstructionSizeOffset + kIntSize;
   5348   static const int kHandlerTableOffset = kRelocationInfoOffset + kPointerSize;
   5349   static const int kDeoptimizationDataOffset =
   5350       kHandlerTableOffset + kPointerSize;
   5351   // For FUNCTION kind, we store the type feedback info here.
   5352   static const int kTypeFeedbackInfoOffset =
   5353       kDeoptimizationDataOffset + kPointerSize;
   5354   static const int kNextCodeLinkOffset = kTypeFeedbackInfoOffset + kPointerSize;
   5355   static const int kGCMetadataOffset = kNextCodeLinkOffset + kPointerSize;
   5356   static const int kICAgeOffset =
   5357       kGCMetadataOffset + kPointerSize;
   5358   static const int kFlagsOffset = kICAgeOffset + kIntSize;
   5359   static const int kKindSpecificFlags1Offset = kFlagsOffset + kIntSize;
   5360   static const int kKindSpecificFlags2Offset =
   5361       kKindSpecificFlags1Offset + kIntSize;
   5362   // Note: We might be able to squeeze this into the flags above.
   5363   static const int kPrologueOffset = kKindSpecificFlags2Offset + kIntSize;
   5364   static const int kConstantPoolOffset = kPrologueOffset + kPointerSize;
   5365 
   5366   static const int kHeaderPaddingStart = kConstantPoolOffset + kIntSize;
   5367 
   5368   // Add padding to align the instruction start following right after
   5369   // the Code object header.
   5370   static const int kHeaderSize =
   5371       (kHeaderPaddingStart + kCodeAlignmentMask) & ~kCodeAlignmentMask;
   5372 
   5373   // Byte offsets within kKindSpecificFlags1Offset.
   5374   static const int kOptimizableOffset = kKindSpecificFlags1Offset;
   5375 
   5376   static const int kFullCodeFlags = kOptimizableOffset + 1;
   5377   class FullCodeFlagsHasDeoptimizationSupportField:
   5378       public BitField<bool, 0, 1> {};  // NOLINT
   5379   class FullCodeFlagsHasDebugBreakSlotsField: public BitField<bool, 1, 1> {};
   5380   class FullCodeFlagsIsCompiledOptimizable: public BitField<bool, 2, 1> {};
   5381 
   5382   static const int kProfilerTicksOffset = kFullCodeFlags + 1;
   5383 
   5384   // Flags layout.  BitField<type, shift, size>.
   5385   class ICStateField : public BitField<InlineCacheState, 0, 4> {};
   5386   class TypeField : public BitField<StubType, 4, 1> {};
   5387   class CacheHolderField : public BitField<CacheHolderFlag, 5, 2> {};
   5388   class KindField : public BitField<Kind, 7, 4> {};
   5389   class ExtraICStateField: public BitField<ExtraICState, 11,
   5390       PlatformSmiTagging::kSmiValueSize - 11 + 1> {};  // NOLINT
   5391 
   5392   // KindSpecificFlags1 layout (STUB and OPTIMIZED_FUNCTION)
   5393   static const int kStackSlotsFirstBit = 0;
   5394   static const int kStackSlotsBitCount = 24;
   5395   static const int kHasFunctionCacheBit =
   5396       kStackSlotsFirstBit + kStackSlotsBitCount;
   5397   static const int kMarkedForDeoptimizationBit = kHasFunctionCacheBit + 1;
   5398   static const int kWeakStubBit = kMarkedForDeoptimizationBit + 1;
   5399   static const int kInvalidatedWeakStubBit = kWeakStubBit + 1;
   5400   static const int kIsTurbofannedBit = kInvalidatedWeakStubBit + 1;
   5401 
   5402   STATIC_ASSERT(kStackSlotsFirstBit + kStackSlotsBitCount <= 32);
   5403   STATIC_ASSERT(kIsTurbofannedBit + 1 <= 32);
   5404 
   5405   class StackSlotsField: public BitField<int,
   5406       kStackSlotsFirstBit, kStackSlotsBitCount> {};  // NOLINT
   5407   class HasFunctionCacheField : public BitField<bool, kHasFunctionCacheBit, 1> {
   5408   };  // NOLINT
   5409   class MarkedForDeoptimizationField
   5410       : public BitField<bool, kMarkedForDeoptimizationBit, 1> {};   // NOLINT
   5411   class WeakStubField : public BitField<bool, kWeakStubBit, 1> {};  // NOLINT
   5412   class InvalidatedWeakStubField
   5413       : public BitField<bool, kInvalidatedWeakStubBit, 1> {};  // NOLINT
   5414   class IsTurbofannedField : public BitField<bool, kIsTurbofannedBit, 1> {
   5415   };  // NOLINT
   5416 
   5417   // KindSpecificFlags2 layout (ALL)
   5418   static const int kIsCrankshaftedBit = 0;
   5419   class IsCrankshaftedField: public BitField<bool,
   5420       kIsCrankshaftedBit, 1> {};  // NOLINT
   5421 
   5422   // KindSpecificFlags2 layout (STUB and OPTIMIZED_FUNCTION)
   5423   static const int kSafepointTableOffsetFirstBit = kIsCrankshaftedBit + 1;
   5424   static const int kSafepointTableOffsetBitCount = 24;
   5425 
   5426   STATIC_ASSERT(kSafepointTableOffsetFirstBit +
   5427                 kSafepointTableOffsetBitCount <= 32);
   5428   STATIC_ASSERT(1 + kSafepointTableOffsetBitCount <= 32);
   5429 
   5430   class SafepointTableOffsetField: public BitField<int,
   5431       kSafepointTableOffsetFirstBit,
   5432       kSafepointTableOffsetBitCount> {};  // NOLINT
   5433 
   5434   // KindSpecificFlags2 layout (FUNCTION)
   5435   class BackEdgeTableOffsetField: public BitField<int,
   5436       kIsCrankshaftedBit + 1, 27> {};  // NOLINT
   5437   class AllowOSRAtLoopNestingLevelField: public BitField<int,
   5438       kIsCrankshaftedBit + 1 + 27, 4> {};  // NOLINT
   5439   STATIC_ASSERT(AllowOSRAtLoopNestingLevelField::kMax >= kMaxLoopNestingMarker);
   5440 
   5441   static const int kArgumentsBits = 16;
   5442   static const int kMaxArguments = (1 << kArgumentsBits) - 1;
   5443 
   5444   // This constant should be encodable in an ARM instruction.
   5445   static const int kFlagsNotUsedInLookup =
   5446       TypeField::kMask | CacheHolderField::kMask;
   5447 
   5448  private:
   5449   friend class RelocIterator;
   5450   friend class Deoptimizer;  // For FindCodeAgeSequence.
   5451 
   5452   void ClearInlineCaches(Kind* kind);
   5453 
   5454   // Code aging
   5455   byte* FindCodeAgeSequence();
   5456   static void GetCodeAgeAndParity(Code* code, Age* age,
   5457                                   MarkingParity* parity);
   5458   static void GetCodeAgeAndParity(Isolate* isolate, byte* sequence, Age* age,
   5459                                   MarkingParity* parity);
   5460   static Code* GetCodeAgeStub(Isolate* isolate, Age age, MarkingParity parity);
   5461 
   5462   // Code aging -- platform-specific
   5463   static void PatchPlatformCodeAge(Isolate* isolate,
   5464                                    byte* sequence, Age age,
   5465                                    MarkingParity parity);
   5466 
   5467   DISALLOW_IMPLICIT_CONSTRUCTORS(Code);
   5468 };
   5469 
   5470 
   5471 class CompilationInfo;
   5472 
   5473 // This class describes the layout of dependent codes array of a map. The
   5474 // array is partitioned into several groups of dependent codes. Each group
   5475 // contains codes with the same dependency on the map. The array has the
   5476 // following layout for n dependency groups:
   5477 //
   5478 // +----+----+-----+----+---------+----------+-----+---------+-----------+
   5479 // | C1 | C2 | ... | Cn | group 1 |  group 2 | ... | group n | undefined |
   5480 // +----+----+-----+----+---------+----------+-----+---------+-----------+
   5481 //
   5482 // The first n elements are Smis, each of them specifies the number of codes
   5483 // in the corresponding group. The subsequent elements contain grouped code
   5484 // objects. The suffix of the array can be filled with the undefined value if
   5485 // the number of codes is less than the length of the array. The order of the
   5486 // code objects within a group is not preserved.
   5487 //
   5488 // All code indexes used in the class are counted starting from the first
   5489 // code object of the first group. In other words, code index 0 corresponds
   5490 // to array index n = kCodesStartIndex.
   5491 
   5492 class DependentCode: public FixedArray {
   5493  public:
   5494   enum DependencyGroup {
   5495     // Group of IC stubs that weakly embed this map and depend on being
   5496     // invalidated when the map is garbage collected. Dependent IC stubs form
   5497     // a linked list. This group stores only the head of the list. This means
   5498     // that the number_of_entries(kWeakICGroup) is 0 or 1.
   5499     kWeakICGroup,
   5500     // Group of code that weakly embed this map and depend on being
   5501     // deoptimized when the map is garbage collected.
   5502     kWeakCodeGroup,
   5503     // Group of code that embed a transition to this map, and depend on being
   5504     // deoptimized when the transition is replaced by a new version.
   5505     kTransitionGroup,
   5506     // Group of code that omit run-time prototype checks for prototypes
   5507     // described by this map. The group is deoptimized whenever an object
   5508     // described by this map changes shape (and transitions to a new map),
   5509     // possibly invalidating the assumptions embedded in the code.
   5510     kPrototypeCheckGroup,
   5511     // Group of code that depends on elements not being added to objects with
   5512     // this map.
   5513     kElementsCantBeAddedGroup,
   5514     // Group of code that depends on global property values in property cells
   5515     // not being changed.
   5516     kPropertyCellChangedGroup,
   5517     // Group of code that omit run-time type checks for the field(s) introduced
   5518     // by this map.
   5519     kFieldTypeGroup,
   5520     // Group of code that omit run-time type checks for initial maps of
   5521     // constructors.
   5522     kInitialMapChangedGroup,
   5523     // Group of code that depends on tenuring information in AllocationSites
   5524     // not being changed.
   5525     kAllocationSiteTenuringChangedGroup,
   5526     // Group of code that depends on element transition information in
   5527     // AllocationSites not being changed.
   5528     kAllocationSiteTransitionChangedGroup
   5529   };
   5530 
   5531   static const int kGroupCount = kAllocationSiteTransitionChangedGroup + 1;
   5532 
   5533   // Array for holding the index of the first code object of each group.
   5534   // The last element stores the total number of code objects.
   5535   class GroupStartIndexes {
   5536    public:
   5537     explicit GroupStartIndexes(DependentCode* entries);
   5538     void Recompute(DependentCode* entries);
   5539     int at(int i) { return start_indexes_[i]; }
   5540     int number_of_entries() { return start_indexes_[kGroupCount]; }
   5541    private:
   5542     int start_indexes_[kGroupCount + 1];
   5543   };
   5544 
   5545   bool Contains(DependencyGroup group, Code* code);
   5546   static Handle<DependentCode> Insert(Handle<DependentCode> entries,
   5547                                       DependencyGroup group,
   5548                                       Handle<Object> object);
   5549   void UpdateToFinishedCode(DependencyGroup group,
   5550                             CompilationInfo* info,
   5551                             Code* code);
   5552   void RemoveCompilationInfo(DependentCode::DependencyGroup group,
   5553                              CompilationInfo* info);
   5554 
   5555   void DeoptimizeDependentCodeGroup(Isolate* isolate,
   5556                                     DependentCode::DependencyGroup group);
   5557 
   5558   bool MarkCodeForDeoptimization(Isolate* isolate,
   5559                                  DependentCode::DependencyGroup group);
   5560   void AddToDependentICList(Handle<Code> stub);
   5561 
   5562   // The following low-level accessors should only be used by this class
   5563   // and the mark compact collector.
   5564   inline int number_of_entries(DependencyGroup group);
   5565   inline void set_number_of_entries(DependencyGroup group, int value);
   5566   inline bool is_code_at(int i);
   5567   inline Code* code_at(int i);
   5568   inline CompilationInfo* compilation_info_at(int i);
   5569   inline void set_object_at(int i, Object* object);
   5570   inline Object** slot_at(int i);
   5571   inline Object* object_at(int i);
   5572   inline void clear_at(int i);
   5573   inline void copy(int from, int to);
   5574   DECLARE_CAST(DependentCode)
   5575 
   5576   static DependentCode* ForObject(Handle<HeapObject> object,
   5577                                   DependencyGroup group);
   5578 
   5579   static const char* DependencyGroupName(DependencyGroup group);
   5580   static void SetMarkedForDeoptimization(Code* code, DependencyGroup group);
   5581 
   5582  private:
   5583   // Make a room at the end of the given group by moving out the first
   5584   // code objects of the subsequent groups.
   5585   inline void ExtendGroup(DependencyGroup group);
   5586   static const int kCodesStartIndex = kGroupCount;
   5587 };
   5588 
   5589 
   5590 // All heap objects have a Map that describes their structure.
   5591 //  A Map contains information about:
   5592 //  - Size information about the object
   5593 //  - How to iterate over an object (for garbage collection)
   5594 class Map: public HeapObject {
   5595  public:
   5596   // Instance size.
   5597   // Size in bytes or kVariableSizeSentinel if instances do not have
   5598   // a fixed size.
   5599   inline int instance_size();
   5600   inline void set_instance_size(int value);
   5601 
   5602   // Count of properties allocated in the object.
   5603   inline int inobject_properties();
   5604   inline void set_inobject_properties(int value);
   5605 
   5606   // Count of property fields pre-allocated in the object when first allocated.
   5607   inline int pre_allocated_property_fields();
   5608   inline void set_pre_allocated_property_fields(int value);
   5609 
   5610   // Instance type.
   5611   inline InstanceType instance_type();
   5612   inline void set_instance_type(InstanceType value);
   5613 
   5614   // Tells how many unused property fields are available in the
   5615   // instance (only used for JSObject in fast mode).
   5616   inline int unused_property_fields();
   5617   inline void set_unused_property_fields(int value);
   5618 
   5619   // Bit field.
   5620   inline byte bit_field();
   5621   inline void set_bit_field(byte value);
   5622 
   5623   // Bit field 2.
   5624   inline byte bit_field2();
   5625   inline void set_bit_field2(byte value);
   5626 
   5627   // Bit field 3.
   5628   inline uint32_t bit_field3();
   5629   inline void set_bit_field3(uint32_t bits);
   5630 
   5631   class EnumLengthBits:             public BitField<int,
   5632       0, kDescriptorIndexBitCount> {};  // NOLINT
   5633   class NumberOfOwnDescriptorsBits: public BitField<int,
   5634       kDescriptorIndexBitCount, kDescriptorIndexBitCount> {};  // NOLINT
   5635   STATIC_ASSERT(kDescriptorIndexBitCount + kDescriptorIndexBitCount == 20);
   5636   class DictionaryMap : public BitField<bool, 20, 1> {};
   5637   class OwnsDescriptors : public BitField<bool, 21, 1> {};
   5638   class HasInstanceCallHandler : public BitField<bool, 22, 1> {};
   5639   class Deprecated : public BitField<bool, 23, 1> {};
   5640   class IsFrozen : public BitField<bool, 24, 1> {};
   5641   class IsUnstable : public BitField<bool, 25, 1> {};
   5642   class IsMigrationTarget : public BitField<bool, 26, 1> {};
   5643   class DoneInobjectSlackTracking : public BitField<bool, 27, 1> {};
   5644   // Bit 28 is free.
   5645 
   5646   // Keep this bit field at the very end for better code in
   5647   // Builtins::kJSConstructStubGeneric stub.
   5648   class ConstructionCount:          public BitField<int, 29, 3> {};
   5649 
   5650   // Tells whether the object in the prototype property will be used
   5651   // for instances created from this function.  If the prototype
   5652   // property is set to a value that is not a JSObject, the prototype
   5653   // property will not be used to create instances of the function.
   5654   // See ECMA-262, 13.2.2.
   5655   inline void set_non_instance_prototype(bool value);
   5656   inline bool has_non_instance_prototype();
   5657 
   5658   // Tells whether function has special prototype property. If not, prototype
   5659   // property will not be created when accessed (will return undefined),
   5660   // and construction from this function will not be allowed.
   5661   inline void set_function_with_prototype(bool value);
   5662   inline bool function_with_prototype();
   5663 
   5664   // Tells whether the instance with this map should be ignored by the
   5665   // Object.getPrototypeOf() function and the __proto__ accessor.
   5666   inline void set_is_hidden_prototype() {
   5667     set_bit_field(bit_field() | (1 << kIsHiddenPrototype));
   5668   }
   5669 
   5670   inline bool is_hidden_prototype() {
   5671     return ((1 << kIsHiddenPrototype) & bit_field()) != 0;
   5672   }
   5673 
   5674   // Records and queries whether the instance has a named interceptor.
   5675   inline void set_has_named_interceptor() {
   5676     set_bit_field(bit_field() | (1 << kHasNamedInterceptor));
   5677   }
   5678 
   5679   inline bool has_named_interceptor() {
   5680     return ((1 << kHasNamedInterceptor) & bit_field()) != 0;
   5681   }
   5682 
   5683   // Records and queries whether the instance has an indexed interceptor.
   5684   inline void set_has_indexed_interceptor() {
   5685     set_bit_field(bit_field() | (1 << kHasIndexedInterceptor));
   5686   }
   5687 
   5688   inline bool has_indexed_interceptor() {
   5689     return ((1 << kHasIndexedInterceptor) & bit_field()) != 0;
   5690   }
   5691 
   5692   // Tells whether the instance is undetectable.
   5693   // An undetectable object is a special class of JSObject: 'typeof' operator
   5694   // returns undefined, ToBoolean returns false. Otherwise it behaves like
   5695   // a normal JS object.  It is useful for implementing undetectable
   5696   // document.all in Firefox & Safari.
   5697   // See https://bugzilla.mozilla.org/show_bug.cgi?id=248549.
   5698   inline void set_is_undetectable() {
   5699     set_bit_field(bit_field() | (1 << kIsUndetectable));
   5700   }
   5701 
   5702   inline bool is_undetectable() {
   5703     return ((1 << kIsUndetectable) & bit_field()) != 0;
   5704   }
   5705 
   5706   // Tells whether the instance has a call-as-function handler.
   5707   inline void set_is_observed() {
   5708     set_bit_field(bit_field() | (1 << kIsObserved));
   5709   }
   5710 
   5711   inline bool is_observed() {
   5712     return ((1 << kIsObserved) & bit_field()) != 0;
   5713   }
   5714 
   5715   inline void set_is_extensible(bool value);
   5716   inline bool is_extensible();
   5717   inline void set_is_prototype_map(bool value);
   5718   inline bool is_prototype_map();
   5719 
   5720   inline void set_elements_kind(ElementsKind elements_kind) {
   5721     DCHECK(elements_kind < kElementsKindCount);
   5722     DCHECK(kElementsKindCount <= (1 << Map::ElementsKindBits::kSize));
   5723     set_bit_field2(Map::ElementsKindBits::update(bit_field2(), elements_kind));
   5724     DCHECK(this->elements_kind() == elements_kind);
   5725   }
   5726 
   5727   inline ElementsKind elements_kind() {
   5728     return Map::ElementsKindBits::decode(bit_field2());
   5729   }
   5730 
   5731   // Tells whether the instance has fast elements that are only Smis.
   5732   inline bool has_fast_smi_elements() {
   5733     return IsFastSmiElementsKind(elements_kind());
   5734   }
   5735 
   5736   // Tells whether the instance has fast elements.
   5737   inline bool has_fast_object_elements() {
   5738     return IsFastObjectElementsKind(elements_kind());
   5739   }
   5740 
   5741   inline bool has_fast_smi_or_object_elements() {
   5742     return IsFastSmiOrObjectElementsKind(elements_kind());
   5743   }
   5744 
   5745   inline bool has_fast_double_elements() {
   5746     return IsFastDoubleElementsKind(elements_kind());
   5747   }
   5748 
   5749   inline bool has_fast_elements() {
   5750     return IsFastElementsKind(elements_kind());
   5751   }
   5752 
   5753   inline bool has_sloppy_arguments_elements() {
   5754     return elements_kind() == SLOPPY_ARGUMENTS_ELEMENTS;
   5755   }
   5756 
   5757   inline bool has_external_array_elements() {
   5758     return IsExternalArrayElementsKind(elements_kind());
   5759   }
   5760 
   5761   inline bool has_fixed_typed_array_elements() {
   5762     return IsFixedTypedArrayElementsKind(elements_kind());
   5763   }
   5764 
   5765   inline bool has_dictionary_elements() {
   5766     return IsDictionaryElementsKind(elements_kind());
   5767   }
   5768 
   5769   inline bool has_slow_elements_kind() {
   5770     return elements_kind() == DICTIONARY_ELEMENTS
   5771         || elements_kind() == SLOPPY_ARGUMENTS_ELEMENTS;
   5772   }
   5773 
   5774   static bool IsValidElementsTransition(ElementsKind from_kind,
   5775                                         ElementsKind to_kind);
   5776 
   5777   // Returns true if the current map doesn't have DICTIONARY_ELEMENTS but if a
   5778   // map with DICTIONARY_ELEMENTS was found in the prototype chain.
   5779   bool DictionaryElementsInPrototypeChainOnly();
   5780 
   5781   inline bool HasTransitionArray() const;
   5782   inline bool HasElementsTransition();
   5783   inline Map* elements_transition_map();
   5784 
   5785   inline Map* GetTransition(int transition_index);
   5786   inline int SearchTransition(Name* name);
   5787   inline FixedArrayBase* GetInitialElements();
   5788 
   5789   DECL_ACCESSORS(transitions, TransitionArray)
   5790 
   5791   static inline Handle<String> ExpectedTransitionKey(Handle<Map> map);
   5792   static inline Handle<Map> ExpectedTransitionTarget(Handle<Map> map);
   5793 
   5794   // Try to follow an existing transition to a field with attributes NONE. The
   5795   // return value indicates whether the transition was successful.
   5796   static inline Handle<Map> FindTransitionToField(Handle<Map> map,
   5797                                                   Handle<Name> key);
   5798 
   5799   Map* FindRootMap();
   5800   Map* FindFieldOwner(int descriptor);
   5801 
   5802   inline int GetInObjectPropertyOffset(int index);
   5803 
   5804   int NumberOfFields();
   5805 
   5806   // TODO(ishell): candidate with JSObject::MigrateToMap().
   5807   bool InstancesNeedRewriting(Map* target, int target_number_of_fields,
   5808                               int target_inobject, int target_unused,
   5809                               int* old_number_of_fields);
   5810   // TODO(ishell): moveit!
   5811   static Handle<Map> GeneralizeAllFieldRepresentations(Handle<Map> map);
   5812   MUST_USE_RESULT static Handle<HeapType> GeneralizeFieldType(
   5813       Handle<HeapType> type1,
   5814       Handle<HeapType> type2,
   5815       Isolate* isolate);
   5816   static void GeneralizeFieldType(Handle<Map> map,
   5817                                   int modify_index,
   5818                                   Handle<HeapType> new_field_type);
   5819   static Handle<Map> GeneralizeRepresentation(
   5820       Handle<Map> map,
   5821       int modify_index,
   5822       Representation new_representation,
   5823       Handle<HeapType> new_field_type,
   5824       StoreMode store_mode);
   5825   static Handle<Map> CopyGeneralizeAllRepresentations(
   5826       Handle<Map> map,
   5827       int modify_index,
   5828       StoreMode store_mode,
   5829       PropertyAttributes attributes,
   5830       const char* reason);
   5831   static Handle<Map> CopyGeneralizeAllRepresentations(
   5832       Handle<Map> map,
   5833       int modify_index,
   5834       StoreMode store_mode,
   5835       const char* reason);
   5836 
   5837   static Handle<Map> PrepareForDataProperty(Handle<Map> old_map,
   5838                                             int descriptor_number,
   5839                                             Handle<Object> value);
   5840 
   5841   static Handle<Map> Normalize(Handle<Map> map, PropertyNormalizationMode mode);
   5842 
   5843   // Returns the constructor name (the name (possibly, inferred name) of the
   5844   // function that was used to instantiate the object).
   5845   String* constructor_name();
   5846 
   5847   // Tells whether the map is used for JSObjects in dictionary mode (ie
   5848   // normalized objects, ie objects for which HasFastProperties returns false).
   5849   // A map can never be used for both dictionary mode and fast mode JSObjects.
   5850   // False by default and for HeapObjects that are not JSObjects.
   5851   inline void set_dictionary_map(bool value);
   5852   inline bool is_dictionary_map();
   5853 
   5854   // Tells whether the instance needs security checks when accessing its
   5855   // properties.
   5856   inline void set_is_access_check_needed(bool access_check_needed);
   5857   inline bool is_access_check_needed();
   5858 
   5859   // Returns true if map has a non-empty stub code cache.
   5860   inline bool has_code_cache();
   5861 
   5862   // [prototype]: implicit prototype object.
   5863   DECL_ACCESSORS(prototype, Object)
   5864 
   5865   // [constructor]: points back to the function responsible for this map.
   5866   DECL_ACCESSORS(constructor, Object)
   5867 
   5868   // [instance descriptors]: describes the object.
   5869   DECL_ACCESSORS(instance_descriptors, DescriptorArray)
   5870   inline void InitializeDescriptors(DescriptorArray* descriptors);
   5871 
   5872   // [stub cache]: contains stubs compiled for this map.
   5873   DECL_ACCESSORS(code_cache, Object)
   5874 
   5875   // [dependent code]: list of optimized codes that weakly embed this map.
   5876   DECL_ACCESSORS(dependent_code, DependentCode)
   5877 
   5878   // [back pointer]: points back to the parent map from which a transition
   5879   // leads to this map. The field overlaps with prototype transitions and the
   5880   // back pointer will be moved into the prototype transitions array if
   5881   // required.
   5882   inline Object* GetBackPointer();
   5883   inline void SetBackPointer(Object* value,
   5884                              WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
   5885   inline void init_back_pointer(Object* undefined);
   5886 
   5887   // [prototype transitions]: cache of prototype transitions.
   5888   // Prototype transition is a transition that happens
   5889   // when we change object's prototype to a new one.
   5890   // Cache format:
   5891   //    0: finger - index of the first free cell in the cache
   5892   //    1: back pointer that overlaps with prototype transitions field.
   5893   //    2 + 2 * i: prototype
   5894   //    3 + 2 * i: target map
   5895   inline FixedArray* GetPrototypeTransitions();
   5896   inline bool HasPrototypeTransitions();
   5897 
   5898   static const int kProtoTransitionHeaderSize = 1;
   5899   static const int kProtoTransitionNumberOfEntriesOffset = 0;
   5900   static const int kProtoTransitionElementsPerEntry = 2;
   5901   static const int kProtoTransitionPrototypeOffset = 0;
   5902   static const int kProtoTransitionMapOffset = 1;
   5903 
   5904   inline int NumberOfProtoTransitions() {
   5905     FixedArray* cache = GetPrototypeTransitions();
   5906     if (cache->length() == 0) return 0;
   5907     return
   5908         Smi::cast(cache->get(kProtoTransitionNumberOfEntriesOffset))->value();
   5909   }
   5910 
   5911   inline void SetNumberOfProtoTransitions(int value) {
   5912     FixedArray* cache = GetPrototypeTransitions();
   5913     DCHECK(cache->length() != 0);
   5914     cache->set(kProtoTransitionNumberOfEntriesOffset, Smi::FromInt(value));
   5915   }
   5916 
   5917   // Lookup in the map's instance descriptors and fill out the result
   5918   // with the given holder if the name is found. The holder may be
   5919   // NULL when this function is used from the compiler.
   5920   inline void LookupDescriptor(JSObject* holder,
   5921                                Name* name,
   5922                                LookupResult* result);
   5923 
   5924   inline void LookupTransition(JSObject* holder,
   5925                                Name* name,
   5926                                LookupResult* result);
   5927 
   5928   inline PropertyDetails GetLastDescriptorDetails();
   5929 
   5930   // The size of transition arrays are limited so they do not end up in large
   5931   // object space. Otherwise ClearNonLiveTransitions would leak memory while
   5932   // applying in-place right trimming.
   5933   inline bool CanHaveMoreTransitions();
   5934 
   5935   int LastAdded() {
   5936     int number_of_own_descriptors = NumberOfOwnDescriptors();
   5937     DCHECK(number_of_own_descriptors > 0);
   5938     return number_of_own_descriptors - 1;
   5939   }
   5940 
   5941   int NumberOfOwnDescriptors() {
   5942     return NumberOfOwnDescriptorsBits::decode(bit_field3());
   5943   }
   5944 
   5945   void SetNumberOfOwnDescriptors(int number) {
   5946     DCHECK(number <= instance_descriptors()->number_of_descriptors());
   5947     set_bit_field3(NumberOfOwnDescriptorsBits::update(bit_field3(), number));
   5948   }
   5949 
   5950   inline Cell* RetrieveDescriptorsPointer();
   5951 
   5952   int EnumLength() {
   5953     return EnumLengthBits::decode(bit_field3());
   5954   }
   5955 
   5956   void SetEnumLength(int length) {
   5957     if (length != kInvalidEnumCacheSentinel) {
   5958       DCHECK(length >= 0);
   5959       DCHECK(length == 0 || instance_descriptors()->HasEnumCache());
   5960       DCHECK(length <= NumberOfOwnDescriptors());
   5961     }
   5962     set_bit_field3(EnumLengthBits::update(bit_field3(), length));
   5963   }
   5964 
   5965   inline bool owns_descriptors();
   5966   inline void set_owns_descriptors(bool owns_descriptors);
   5967   inline bool has_instance_call_handler();
   5968   inline void set_has_instance_call_handler();
   5969   inline void freeze();
   5970   inline bool is_frozen();
   5971   inline void mark_unstable();
   5972   inline bool is_stable();
   5973   inline void set_migration_target(bool value);
   5974   inline bool is_migration_target();
   5975   inline void set_done_inobject_slack_tracking(bool value);
   5976   inline bool done_inobject_slack_tracking();
   5977   inline void set_construction_count(int value);
   5978   inline int construction_count();
   5979   inline void deprecate();
   5980   inline bool is_deprecated();
   5981   inline bool CanBeDeprecated();
   5982   // Returns a non-deprecated version of the input. If the input was not
   5983   // deprecated, it is directly returned. Otherwise, the non-deprecated version
   5984   // is found by re-transitioning from the root of the transition tree using the
   5985   // descriptor array of the map. Returns NULL if no updated map is found.
   5986   // This method also applies any pending migrations along the prototype chain.
   5987   static MaybeHandle<Map> TryUpdate(Handle<Map> map) WARN_UNUSED_RESULT;
   5988   // Same as above, but does not touch the prototype chain.
   5989   static MaybeHandle<Map> TryUpdateInternal(Handle<Map> map)
   5990       WARN_UNUSED_RESULT;
   5991 
   5992   // Returns a non-deprecated version of the input. This method may deprecate
   5993   // existing maps along the way if encodings conflict. Not for use while
   5994   // gathering type feedback. Use TryUpdate in those cases instead.
   5995   static Handle<Map> Update(Handle<Map> map);
   5996 
   5997   static Handle<Map> CopyDropDescriptors(Handle<Map> map);
   5998   static Handle<Map> CopyInsertDescriptor(Handle<Map> map,
   5999                                           Descriptor* descriptor,
   6000                                           TransitionFlag flag);
   6001 
   6002   MUST_USE_RESULT static MaybeHandle<Map> CopyWithField(
   6003       Handle<Map> map,
   6004       Handle<Name> name,
   6005       Handle<HeapType> type,
   6006       PropertyAttributes attributes,
   6007       Representation representation,
   6008       TransitionFlag flag);
   6009 
   6010   MUST_USE_RESULT static MaybeHandle<Map> CopyWithConstant(
   6011       Handle<Map> map,
   6012       Handle<Name> name,
   6013       Handle<Object> constant,
   6014       PropertyAttributes attributes,
   6015       TransitionFlag flag);
   6016 
   6017   // Returns a new map with all transitions dropped from the given map and
   6018   // the ElementsKind set.
   6019   static Handle<Map> TransitionElementsTo(Handle<Map> map,
   6020                                           ElementsKind to_kind);
   6021 
   6022   static Handle<Map> AsElementsKind(Handle<Map> map, ElementsKind kind);
   6023 
   6024   static Handle<Map> CopyAsElementsKind(Handle<Map> map,
   6025                                         ElementsKind kind,
   6026                                         TransitionFlag flag);
   6027 
   6028   static Handle<Map> CopyForObserved(Handle<Map> map);
   6029 
   6030   static Handle<Map> CopyForFreeze(Handle<Map> map);
   6031   // Maximal number of fast properties. Used to restrict the number of map
   6032   // transitions to avoid an explosion in the number of maps for objects used as
   6033   // dictionaries.
   6034   inline bool TooManyFastProperties(StoreFromKeyed store_mode);
   6035   static Handle<Map> TransitionToDataProperty(Handle<Map> map,
   6036                                               Handle<Name> name,
   6037                                               Handle<Object> value,
   6038                                               PropertyAttributes attributes,
   6039                                               StoreFromKeyed store_mode);
   6040   static Handle<Map> TransitionToAccessorProperty(
   6041       Handle<Map> map, Handle<Name> name, AccessorComponent component,
   6042       Handle<Object> accessor, PropertyAttributes attributes);
   6043   static Handle<Map> ReconfigureDataProperty(Handle<Map> map, int descriptor,
   6044                                              PropertyAttributes attributes);
   6045 
   6046   inline void AppendDescriptor(Descriptor* desc);
   6047 
   6048   // Returns a copy of the map, with all transitions dropped from the
   6049   // instance descriptors.
   6050   static Handle<Map> Copy(Handle<Map> map);
   6051   static Handle<Map> Create(Isolate* isolate, int inobject_properties);
   6052 
   6053   // Returns the next free property index (only valid for FAST MODE).
   6054   int NextFreePropertyIndex();
   6055 
   6056   // Returns the number of properties described in instance_descriptors
   6057   // filtering out properties with the specified attributes.
   6058   int NumberOfDescribedProperties(DescriptorFlag which = OWN_DESCRIPTORS,
   6059                                   PropertyAttributes filter = NONE);
   6060 
   6061   // Returns the number of slots allocated for the initial properties
   6062   // backing storage for instances of this map.
   6063   int InitialPropertiesLength() {
   6064     return pre_allocated_property_fields() + unused_property_fields() -
   6065         inobject_properties();
   6066   }
   6067 
   6068   DECLARE_CAST(Map)
   6069 
   6070   // Code cache operations.
   6071 
   6072   // Clears the code cache.
   6073   inline void ClearCodeCache(Heap* heap);
   6074 
   6075   // Update code cache.
   6076   static void UpdateCodeCache(Handle<Map> map,
   6077                               Handle<Name> name,
   6078                               Handle<Code> code);
   6079 
   6080   // Extend the descriptor array of the map with the list of descriptors.
   6081   // In case of duplicates, the latest descriptor is used.
   6082   static void AppendCallbackDescriptors(Handle<Map> map,
   6083                                         Handle<Object> descriptors);
   6084 
   6085   static void EnsureDescriptorSlack(Handle<Map> map, int slack);
   6086 
   6087   // Returns the found code or undefined if absent.
   6088   Object* FindInCodeCache(Name* name, Code::Flags flags);
   6089 
   6090   // Returns the non-negative index of the code object if it is in the
   6091   // cache and -1 otherwise.
   6092   int IndexInCodeCache(Object* name, Code* code);
   6093 
   6094   // Removes a code object from the code cache at the given index.
   6095   void RemoveFromCodeCache(Name* name, Code* code, int index);
   6096 
   6097   // Set all map transitions from this map to dead maps to null.  Also clear
   6098   // back pointers in transition targets so that we do not process this map
   6099   // again while following back pointers.
   6100   void ClearNonLiveTransitions(Heap* heap);
   6101 
   6102   // Computes a hash value for this map, to be used in HashTables and such.
   6103   int Hash();
   6104 
   6105   // Returns the map that this map transitions to if its elements_kind
   6106   // is changed to |elements_kind|, or NULL if no such map is cached yet.
   6107   // |safe_to_add_transitions| is set to false if adding transitions is not
   6108   // allowed.
   6109   Map* LookupElementsTransitionMap(ElementsKind elements_kind);
   6110 
   6111   // Returns the transitioned map for this map with the most generic
   6112   // elements_kind that's found in |candidates|, or null handle if no match is
   6113   // found at all.
   6114   Handle<Map> FindTransitionedMap(MapHandleList* candidates);
   6115 
   6116   bool CanTransition() {
   6117     // Only JSObject and subtypes have map transitions and back pointers.
   6118     STATIC_ASSERT(LAST_TYPE == LAST_JS_OBJECT_TYPE);
   6119     return instance_type() >= FIRST_JS_OBJECT_TYPE;
   6120   }
   6121 
   6122   bool IsJSObjectMap() {
   6123     return instance_type() >= FIRST_JS_OBJECT_TYPE;
   6124   }
   6125   bool IsJSProxyMap() {
   6126     InstanceType type = instance_type();
   6127     return FIRST_JS_PROXY_TYPE <= type && type <= LAST_JS_PROXY_TYPE;
   6128   }
   6129   bool IsJSGlobalProxyMap() {
   6130     return instance_type() == JS_GLOBAL_PROXY_TYPE;
   6131   }
   6132   bool IsJSGlobalObjectMap() {
   6133     return instance_type() == JS_GLOBAL_OBJECT_TYPE;
   6134   }
   6135   bool IsGlobalObjectMap() {
   6136     const InstanceType type = instance_type();
   6137     return type == JS_GLOBAL_OBJECT_TYPE || type == JS_BUILTINS_OBJECT_TYPE;
   6138   }
   6139 
   6140   inline bool CanOmitMapChecks();
   6141 
   6142   static void AddDependentCompilationInfo(Handle<Map> map,
   6143                                           DependentCode::DependencyGroup group,
   6144                                           CompilationInfo* info);
   6145 
   6146   static void AddDependentCode(Handle<Map> map,
   6147                                DependentCode::DependencyGroup group,
   6148                                Handle<Code> code);
   6149   static void AddDependentIC(Handle<Map> map,
   6150                              Handle<Code> stub);
   6151 
   6152   bool IsMapInArrayPrototypeChain();
   6153 
   6154   // Dispatched behavior.
   6155   DECLARE_PRINTER(Map)
   6156   DECLARE_VERIFIER(Map)
   6157 
   6158 #ifdef VERIFY_HEAP
   6159   void DictionaryMapVerify();
   6160   void VerifyOmittedMapChecks();
   6161 #endif
   6162 
   6163   inline int visitor_id();
   6164   inline void set_visitor_id(int visitor_id);
   6165 
   6166   typedef void (*TraverseCallback)(Map* map, void* data);
   6167 
   6168   void TraverseTransitionTree(TraverseCallback callback, void* data);
   6169 
   6170   // When you set the prototype of an object using the __proto__ accessor you
   6171   // need a new map for the object (the prototype is stored in the map).  In
   6172   // order not to multiply maps unnecessarily we store these as transitions in
   6173   // the original map.  That way we can transition to the same map if the same
   6174   // prototype is set, rather than creating a new map every time.  The
   6175   // transitions are in the form of a map where the keys are prototype objects
   6176   // and the values are the maps the are transitioned to.
   6177   static const int kMaxCachedPrototypeTransitions = 256;
   6178   static Handle<Map> TransitionToPrototype(Handle<Map> map,
   6179                                            Handle<Object> prototype);
   6180 
   6181   static const int kMaxPreAllocatedPropertyFields = 255;
   6182 
   6183   // Layout description.
   6184   static const int kInstanceSizesOffset = HeapObject::kHeaderSize;
   6185   static const int kInstanceAttributesOffset = kInstanceSizesOffset + kIntSize;
   6186   static const int kBitField3Offset = kInstanceAttributesOffset + kIntSize;
   6187   static const int kPrototypeOffset = kBitField3Offset + kPointerSize;
   6188   static const int kConstructorOffset = kPrototypeOffset + kPointerSize;
   6189   // Storage for the transition array is overloaded to directly contain a back
   6190   // pointer if unused. When the map has transitions, the back pointer is
   6191   // transferred to the transition array and accessed through an extra
   6192   // indirection.
   6193   static const int kTransitionsOrBackPointerOffset =
   6194       kConstructorOffset + kPointerSize;
   6195   static const int kDescriptorsOffset =
   6196       kTransitionsOrBackPointerOffset + kPointerSize;
   6197   static const int kCodeCacheOffset = kDescriptorsOffset + kPointerSize;
   6198   static const int kDependentCodeOffset = kCodeCacheOffset + kPointerSize;
   6199   static const int kSize = kDependentCodeOffset + kPointerSize;
   6200 
   6201   // Layout of pointer fields. Heap iteration code relies on them
   6202   // being continuously allocated.
   6203   static const int kPointerFieldsBeginOffset = Map::kPrototypeOffset;
   6204   static const int kPointerFieldsEndOffset = kSize;
   6205 
   6206   // Byte offsets within kInstanceSizesOffset.
   6207   static const int kInstanceSizeOffset = kInstanceSizesOffset + 0;
   6208   static const int kInObjectPropertiesByte = 1;
   6209   static const int kInObjectPropertiesOffset =
   6210       kInstanceSizesOffset + kInObjectPropertiesByte;
   6211   static const int kPreAllocatedPropertyFieldsByte = 2;
   6212   static const int kPreAllocatedPropertyFieldsOffset =
   6213       kInstanceSizesOffset + kPreAllocatedPropertyFieldsByte;
   6214   static const int kVisitorIdByte = 3;
   6215   static const int kVisitorIdOffset = kInstanceSizesOffset + kVisitorIdByte;
   6216 
   6217   // Byte offsets within kInstanceAttributesOffset attributes.
   6218 #if V8_TARGET_LITTLE_ENDIAN
   6219   // Order instance type and bit field together such that they can be loaded
   6220   // together as a 16-bit word with instance type in the lower 8 bits regardless
   6221   // of endianess. Also provide endian-independent offset to that 16-bit word.
   6222   static const int kInstanceTypeOffset = kInstanceAttributesOffset + 0;
   6223   static const int kBitFieldOffset = kInstanceAttributesOffset + 1;
   6224 #else
   6225   static const int kBitFieldOffset = kInstanceAttributesOffset + 0;
   6226   static const int kInstanceTypeOffset = kInstanceAttributesOffset + 1;
   6227 #endif
   6228   static const int kInstanceTypeAndBitFieldOffset =
   6229       kInstanceAttributesOffset + 0;
   6230   static const int kBitField2Offset = kInstanceAttributesOffset + 2;
   6231   static const int kUnusedPropertyFieldsOffset = kInstanceAttributesOffset + 3;
   6232 
   6233   STATIC_ASSERT(kInstanceTypeAndBitFieldOffset ==
   6234                 Internals::kMapInstanceTypeAndBitFieldOffset);
   6235 
   6236   // Bit positions for bit field.
   6237   static const int kHasNonInstancePrototype = 0;
   6238   static const int kIsHiddenPrototype = 1;
   6239   static const int kHasNamedInterceptor = 2;
   6240   static const int kHasIndexedInterceptor = 3;
   6241   static const int kIsUndetectable = 4;
   6242   static const int kIsObserved = 5;
   6243   static const int kIsAccessCheckNeeded = 6;
   6244   class FunctionWithPrototype: public BitField<bool, 7,  1> {};
   6245 
   6246   // Bit positions for bit field 2
   6247   static const int kIsExtensible = 0;
   6248   static const int kStringWrapperSafeForDefaultValueOf = 1;
   6249   class IsPrototypeMapBits : public BitField<bool, 2, 1> {};
   6250   class ElementsKindBits: public BitField<ElementsKind, 3, 5> {};
   6251 
   6252   // Derived values from bit field 2
   6253   static const int8_t kMaximumBitField2FastElementValue = static_cast<int8_t>(
   6254       (FAST_ELEMENTS + 1) << Map::ElementsKindBits::kShift) - 1;
   6255   static const int8_t kMaximumBitField2FastSmiElementValue =
   6256       static_cast<int8_t>((FAST_SMI_ELEMENTS + 1) <<
   6257                           Map::ElementsKindBits::kShift) - 1;
   6258   static const int8_t kMaximumBitField2FastHoleyElementValue =
   6259       static_cast<int8_t>((FAST_HOLEY_ELEMENTS + 1) <<
   6260                           Map::ElementsKindBits::kShift) - 1;
   6261   static const int8_t kMaximumBitField2FastHoleySmiElementValue =
   6262       static_cast<int8_t>((FAST_HOLEY_SMI_ELEMENTS + 1) <<
   6263                           Map::ElementsKindBits::kShift) - 1;
   6264 
   6265   typedef FixedBodyDescriptor<kPointerFieldsBeginOffset,
   6266                               kPointerFieldsEndOffset,
   6267                               kSize> BodyDescriptor;
   6268 
   6269   // Compares this map to another to see if they describe equivalent objects.
   6270   // If |mode| is set to CLEAR_INOBJECT_PROPERTIES, |other| is treated as if
   6271   // it had exactly zero inobject properties.
   6272   // The "shared" flags of both this map and |other| are ignored.
   6273   bool EquivalentToForNormalization(Map* other, PropertyNormalizationMode mode);
   6274 
   6275  private:
   6276   static void ConnectElementsTransition(Handle<Map> parent, Handle<Map> child);
   6277   static void ConnectTransition(Handle<Map> parent, Handle<Map> child,
   6278                                 Handle<Name> name, SimpleTransitionFlag flag);
   6279 
   6280   bool EquivalentToForTransition(Map* other);
   6281   static Handle<Map> RawCopy(Handle<Map> map, int instance_size);
   6282   static Handle<Map> ShareDescriptor(Handle<Map> map,
   6283                                      Handle<DescriptorArray> descriptors,
   6284                                      Descriptor* descriptor);
   6285   static Handle<Map> CopyInstallDescriptors(
   6286       Handle<Map> map,
   6287       int new_descriptor,
   6288       Handle<DescriptorArray> descriptors);
   6289   static Handle<Map> CopyAddDescriptor(Handle<Map> map,
   6290                                        Descriptor* descriptor,
   6291                                        TransitionFlag flag);
   6292   static Handle<Map> CopyReplaceDescriptors(
   6293       Handle<Map> map,
   6294       Handle<DescriptorArray> descriptors,
   6295       TransitionFlag flag,
   6296       MaybeHandle<Name> maybe_name,
   6297       SimpleTransitionFlag simple_flag = FULL_TRANSITION);
   6298   static Handle<Map> CopyReplaceDescriptor(Handle<Map> map,
   6299                                            Handle<DescriptorArray> descriptors,
   6300                                            Descriptor* descriptor,
   6301                                            int index,
   6302                                            TransitionFlag flag);
   6303 
   6304   static Handle<Map> CopyNormalized(Handle<Map> map,
   6305                                     PropertyNormalizationMode mode);
   6306 
   6307   // Fires when the layout of an object with a leaf map changes.
   6308   // This includes adding transitions to the leaf map or changing
   6309   // the descriptor array.
   6310   inline void NotifyLeafMapLayoutChange();
   6311 
   6312   static Handle<Map> TransitionElementsToSlow(Handle<Map> object,
   6313                                               ElementsKind to_kind);
   6314 
   6315   // Zaps the contents of backing data structures. Note that the
   6316   // heap verifier (i.e. VerifyMarkingVisitor) relies on zapping of objects
   6317   // holding weak references when incremental marking is used, because it also
   6318   // iterates over objects that are otherwise unreachable.
   6319   // In general we only want to call these functions in release mode when
   6320   // heap verification is turned on.
   6321   void ZapPrototypeTransitions();
   6322   void ZapTransitions();
   6323 
   6324   void DeprecateTransitionTree();
   6325   void DeprecateTarget(Name* key, DescriptorArray* new_descriptors);
   6326 
   6327   Map* FindLastMatchMap(int verbatim, int length, DescriptorArray* descriptors);
   6328 
   6329   void UpdateFieldType(int descriptor_number, Handle<Name> name,
   6330                        Handle<HeapType> new_type);
   6331 
   6332   void PrintGeneralization(FILE* file,
   6333                            const char* reason,
   6334                            int modify_index,
   6335                            int split,
   6336                            int descriptors,
   6337                            bool constant_to_field,
   6338                            Representation old_representation,
   6339                            Representation new_representation,
   6340                            HeapType* old_field_type,
   6341                            HeapType* new_field_type);
   6342 
   6343   static inline void SetPrototypeTransitions(
   6344       Handle<Map> map,
   6345       Handle<FixedArray> prototype_transitions);
   6346 
   6347   static Handle<Map> GetPrototypeTransition(Handle<Map> map,
   6348                                             Handle<Object> prototype);
   6349   static Handle<Map> PutPrototypeTransition(Handle<Map> map,
   6350                                             Handle<Object> prototype,
   6351                                             Handle<Map> target_map);
   6352 
   6353   static const int kFastPropertiesSoftLimit = 12;
   6354   static const int kMaxFastProperties = 128;
   6355 
   6356   DISALLOW_IMPLICIT_CONSTRUCTORS(Map);
   6357 };
   6358 
   6359 
   6360 // An abstract superclass, a marker class really, for simple structure classes.
   6361 // It doesn't carry much functionality but allows struct classes to be
   6362 // identified in the type system.
   6363 class Struct: public HeapObject {
   6364  public:
   6365   inline void InitializeBody(int object_size);
   6366   DECLARE_CAST(Struct)
   6367 };
   6368 
   6369 
   6370 // A simple one-element struct, useful where smis need to be boxed.
   6371 class Box : public Struct {
   6372  public:
   6373   // [value]: the boxed contents.
   6374   DECL_ACCESSORS(value, Object)
   6375 
   6376   DECLARE_CAST(Box)
   6377 
   6378   // Dispatched behavior.
   6379   DECLARE_PRINTER(Box)
   6380   DECLARE_VERIFIER(Box)
   6381 
   6382   static const int kValueOffset = HeapObject::kHeaderSize;
   6383   static const int kSize = kValueOffset + kPointerSize;
   6384 
   6385  private:
   6386   DISALLOW_IMPLICIT_CONSTRUCTORS(Box);
   6387 };
   6388 
   6389 
   6390 // Script describes a script which has been added to the VM.
   6391 class Script: public Struct {
   6392  public:
   6393   // Script types.
   6394   enum Type {
   6395     TYPE_NATIVE = 0,
   6396     TYPE_EXTENSION = 1,
   6397     TYPE_NORMAL = 2
   6398   };
   6399 
   6400   // Script compilation types.
   6401   enum CompilationType {
   6402     COMPILATION_TYPE_HOST = 0,
   6403     COMPILATION_TYPE_EVAL = 1
   6404   };
   6405 
   6406   // Script compilation state.
   6407   enum CompilationState {
   6408     COMPILATION_STATE_INITIAL = 0,
   6409     COMPILATION_STATE_COMPILED = 1
   6410   };
   6411 
   6412   // [source]: the script source.
   6413   DECL_ACCESSORS(source, Object)
   6414 
   6415   // [name]: the script name.
   6416   DECL_ACCESSORS(name, Object)
   6417 
   6418   // [id]: the script id.
   6419   DECL_ACCESSORS(id, Smi)
   6420 
   6421   // [line_offset]: script line offset in resource from where it was extracted.
   6422   DECL_ACCESSORS(line_offset, Smi)
   6423 
   6424   // [column_offset]: script column offset in resource from where it was
   6425   // extracted.
   6426   DECL_ACCESSORS(column_offset, Smi)
   6427 
   6428   // [context_data]: context data for the context this script was compiled in.
   6429   DECL_ACCESSORS(context_data, Object)
   6430 
   6431   // [wrapper]: the wrapper cache.
   6432   DECL_ACCESSORS(wrapper, Foreign)
   6433 
   6434   // [type]: the script type.
   6435   DECL_ACCESSORS(type, Smi)
   6436 
   6437   // [line_ends]: FixedArray of line ends positions.
   6438   DECL_ACCESSORS(line_ends, Object)
   6439 
   6440   // [eval_from_shared]: for eval scripts the shared funcion info for the
   6441   // function from which eval was called.
   6442   DECL_ACCESSORS(eval_from_shared, Object)
   6443 
   6444   // [eval_from_instructions_offset]: the instruction offset in the code for the
   6445   // function from which eval was called where eval was called.
   6446   DECL_ACCESSORS(eval_from_instructions_offset, Smi)
   6447 
   6448   // [flags]: Holds an exciting bitfield.
   6449   DECL_ACCESSORS(flags, Smi)
   6450 
   6451   // [source_url]: sourceURL from magic comment
   6452   DECL_ACCESSORS(source_url, Object)
   6453 
   6454   // [source_url]: sourceMappingURL magic comment
   6455   DECL_ACCESSORS(source_mapping_url, Object)
   6456 
   6457   // [compilation_type]: how the the script was compiled. Encoded in the
   6458   // 'flags' field.
   6459   inline CompilationType compilation_type();
   6460   inline void set_compilation_type(CompilationType type);
   6461 
   6462   // [compilation_state]: determines whether the script has already been
   6463   // compiled. Encoded in the 'flags' field.
   6464   inline CompilationState compilation_state();
   6465   inline void set_compilation_state(CompilationState state);
   6466 
   6467   // [is_shared_cross_origin]: An opaque boolean set by the embedder via
   6468   // ScriptOrigin, and used by the embedder to make decisions about the
   6469   // script's level of privilege. V8 just passes this through. Encoded in
   6470   // the 'flags' field.
   6471   DECL_BOOLEAN_ACCESSORS(is_shared_cross_origin)
   6472 
   6473   DECLARE_CAST(Script)
   6474 
   6475   // If script source is an external string, check that the underlying
   6476   // resource is accessible. Otherwise, always return true.
   6477   inline bool HasValidSource();
   6478 
   6479   // Convert code position into column number.
   6480   static int GetColumnNumber(Handle<Script> script, int code_pos);
   6481 
   6482   // Convert code position into (zero-based) line number.
   6483   // The non-handlified version does not allocate, but may be much slower.
   6484   static int GetLineNumber(Handle<Script> script, int code_pos);
   6485   int GetLineNumber(int code_pos);
   6486 
   6487   static Handle<Object> GetNameOrSourceURL(Handle<Script> script);
   6488 
   6489   // Init line_ends array with code positions of line ends inside script source.
   6490   static void InitLineEnds(Handle<Script> script);
   6491 
   6492   // Get the JS object wrapping the given script; create it if none exists.
   6493   static Handle<JSObject> GetWrapper(Handle<Script> script);
   6494   void ClearWrapperCache();
   6495 
   6496   // Dispatched behavior.
   6497   DECLARE_PRINTER(Script)
   6498   DECLARE_VERIFIER(Script)
   6499 
   6500   static const int kSourceOffset = HeapObject::kHeaderSize;
   6501   static const int kNameOffset = kSourceOffset + kPointerSize;
   6502   static const int kLineOffsetOffset = kNameOffset + kPointerSize;
   6503   static const int kColumnOffsetOffset = kLineOffsetOffset + kPointerSize;
   6504   static const int kContextOffset = kColumnOffsetOffset + kPointerSize;
   6505   static const int kWrapperOffset = kContextOffset + kPointerSize;
   6506   static const int kTypeOffset = kWrapperOffset + kPointerSize;
   6507   static const int kLineEndsOffset = kTypeOffset + kPointerSize;
   6508   static const int kIdOffset = kLineEndsOffset + kPointerSize;
   6509   static const int kEvalFromSharedOffset = kIdOffset + kPointerSize;
   6510   static const int kEvalFrominstructionsOffsetOffset =
   6511       kEvalFromSharedOffset + kPointerSize;
   6512   static const int kFlagsOffset =
   6513       kEvalFrominstructionsOffsetOffset + kPointerSize;
   6514   static const int kSourceUrlOffset = kFlagsOffset + kPointerSize;
   6515   static const int kSourceMappingUrlOffset = kSourceUrlOffset + kPointerSize;
   6516   static const int kSize = kSourceMappingUrlOffset + kPointerSize;
   6517 
   6518  private:
   6519   int GetLineNumberWithArray(int code_pos);
   6520 
   6521   // Bit positions in the flags field.
   6522   static const int kCompilationTypeBit = 0;
   6523   static const int kCompilationStateBit = 1;
   6524   static const int kIsSharedCrossOriginBit = 2;
   6525 
   6526   DISALLOW_IMPLICIT_CONSTRUCTORS(Script);
   6527 };
   6528 
   6529 
   6530 // List of builtin functions we want to identify to improve code
   6531 // generation.
   6532 //
   6533 // Each entry has a name of a global object property holding an object
   6534 // optionally followed by ".prototype", a name of a builtin function
   6535 // on the object (the one the id is set for), and a label.
   6536 //
   6537 // Installation of ids for the selected builtin functions is handled
   6538 // by the bootstrapper.
   6539 #define FUNCTIONS_WITH_ID_LIST(V)                   \
   6540   V(Array.prototype, indexOf, ArrayIndexOf)         \
   6541   V(Array.prototype, lastIndexOf, ArrayLastIndexOf) \
   6542   V(Array.prototype, push, ArrayPush)               \
   6543   V(Array.prototype, pop, ArrayPop)                 \
   6544   V(Array.prototype, shift, ArrayShift)             \
   6545   V(Function.prototype, apply, FunctionApply)       \
   6546   V(String.prototype, charCodeAt, StringCharCodeAt) \
   6547   V(String.prototype, charAt, StringCharAt)         \
   6548   V(String, fromCharCode, StringFromCharCode)       \
   6549   V(Math, floor, MathFloor)                         \
   6550   V(Math, round, MathRound)                         \
   6551   V(Math, ceil, MathCeil)                           \
   6552   V(Math, abs, MathAbs)                             \
   6553   V(Math, log, MathLog)                             \
   6554   V(Math, exp, MathExp)                             \
   6555   V(Math, sqrt, MathSqrt)                           \
   6556   V(Math, pow, MathPow)                             \
   6557   V(Math, max, MathMax)                             \
   6558   V(Math, min, MathMin)                             \
   6559   V(Math, imul, MathImul)                           \
   6560   V(Math, clz32, MathClz32)                         \
   6561   V(Math, fround, MathFround)
   6562 
   6563 enum BuiltinFunctionId {
   6564   kArrayCode,
   6565 #define DECLARE_FUNCTION_ID(ignored1, ignore2, name)    \
   6566   k##name,
   6567   FUNCTIONS_WITH_ID_LIST(DECLARE_FUNCTION_ID)
   6568 #undef DECLARE_FUNCTION_ID
   6569   // Fake id for a special case of Math.pow. Note, it continues the
   6570   // list of math functions.
   6571   kMathPowHalf
   6572 };
   6573 
   6574 
   6575 // SharedFunctionInfo describes the JSFunction information that can be
   6576 // shared by multiple instances of the function.
   6577 class SharedFunctionInfo: public HeapObject {
   6578  public:
   6579   // [name]: Function name.
   6580   DECL_ACCESSORS(name, Object)
   6581 
   6582   // [code]: Function code.
   6583   DECL_ACCESSORS(code, Code)
   6584   inline void ReplaceCode(Code* code);
   6585 
   6586   // [optimized_code_map]: Map from native context to optimized code
   6587   // and a shared literals array or Smi(0) if none.
   6588   DECL_ACCESSORS(optimized_code_map, Object)
   6589 
   6590   // Returns index i of the entry with the specified context and OSR entry.
   6591   // At position i - 1 is the context, position i the code, and i + 1 the
   6592   // literals array.  Returns -1 when no matching entry is found.
   6593   int SearchOptimizedCodeMap(Context* native_context, BailoutId osr_ast_id);
   6594 
   6595   // Installs optimized code from the code map on the given closure. The
   6596   // index has to be consistent with a search result as defined above.
   6597   FixedArray* GetLiteralsFromOptimizedCodeMap(int index);
   6598 
   6599   Code* GetCodeFromOptimizedCodeMap(int index);
   6600 
   6601   // Clear optimized code map.
   6602   void ClearOptimizedCodeMap();
   6603 
   6604   // Removed a specific optimized code object from the optimized code map.
   6605   void EvictFromOptimizedCodeMap(Code* optimized_code, const char* reason);
   6606 
   6607   void ClearTypeFeedbackInfo();
   6608 
   6609   // Trims the optimized code map after entries have been removed.
   6610   void TrimOptimizedCodeMap(int shrink_by);
   6611 
   6612   // Add a new entry to the optimized code map.
   6613   static void AddToOptimizedCodeMap(Handle<SharedFunctionInfo> shared,
   6614                                     Handle<Context> native_context,
   6615                                     Handle<Code> code,
   6616                                     Handle<FixedArray> literals,
   6617                                     BailoutId osr_ast_id);
   6618 
   6619   // Layout description of the optimized code map.
   6620   static const int kNextMapIndex = 0;
   6621   static const int kEntriesStart = 1;
   6622   static const int kContextOffset = 0;
   6623   static const int kCachedCodeOffset = 1;
   6624   static const int kLiteralsOffset = 2;
   6625   static const int kOsrAstIdOffset = 3;
   6626   static const int kEntryLength = 4;
   6627   static const int kInitialLength = kEntriesStart + kEntryLength;
   6628 
   6629   // [scope_info]: Scope info.
   6630   DECL_ACCESSORS(scope_info, ScopeInfo)
   6631 
   6632   // [construct stub]: Code stub for constructing instances of this function.
   6633   DECL_ACCESSORS(construct_stub, Code)
   6634 
   6635   // Returns if this function has been compiled to native code yet.
   6636   inline bool is_compiled();
   6637 
   6638   // [length]: The function length - usually the number of declared parameters.
   6639   // Use up to 2^30 parameters.
   6640   inline int length() const;
   6641   inline void set_length(int value);
   6642 
   6643   // [formal parameter count]: The declared number of parameters.
   6644   inline int formal_parameter_count() const;
   6645   inline void set_formal_parameter_count(int value);
   6646 
   6647   // Set the formal parameter count so the function code will be
   6648   // called without using argument adaptor frames.
   6649   inline void DontAdaptArguments();
   6650 
   6651   // [expected_nof_properties]: Expected number of properties for the function.
   6652   inline int expected_nof_properties() const;
   6653   inline void set_expected_nof_properties(int value);
   6654 
   6655   // [feedback_vector] - accumulates ast node feedback from full-codegen and
   6656   // (increasingly) from crankshafted code where sufficient feedback isn't
   6657   // available.
   6658   DECL_ACCESSORS(feedback_vector, TypeFeedbackVector)
   6659 
   6660   // [instance class name]: class name for instances.
   6661   DECL_ACCESSORS(instance_class_name, Object)
   6662 
   6663   // [function data]: This field holds some additional data for function.
   6664   // Currently it either has FunctionTemplateInfo to make benefit the API
   6665   // or Smi identifying a builtin function.
   6666   // In the long run we don't want all functions to have this field but
   6667   // we can fix that when we have a better model for storing hidden data
   6668   // on objects.
   6669   DECL_ACCESSORS(function_data, Object)
   6670 
   6671   inline bool IsApiFunction();
   6672   inline FunctionTemplateInfo* get_api_func_data();
   6673   inline bool HasBuiltinFunctionId();
   6674   inline BuiltinFunctionId builtin_function_id();
   6675 
   6676   // [script info]: Script from which the function originates.
   6677   DECL_ACCESSORS(script, Object)
   6678 
   6679   // [num_literals]: Number of literals used by this function.
   6680   inline int num_literals() const;
   6681   inline void set_num_literals(int value);
   6682 
   6683   // [start_position_and_type]: Field used to store both the source code
   6684   // position, whether or not the function is a function expression,
   6685   // and whether or not the function is a toplevel function. The two
   6686   // least significants bit indicates whether the function is an
   6687   // expression and the rest contains the source code position.
   6688   inline int start_position_and_type() const;
   6689   inline void set_start_position_and_type(int value);
   6690 
   6691   // [debug info]: Debug information.
   6692   DECL_ACCESSORS(debug_info, Object)
   6693 
   6694   // [inferred name]: Name inferred from variable or property
   6695   // assignment of this function. Used to facilitate debugging and
   6696   // profiling of JavaScript code written in OO style, where almost
   6697   // all functions are anonymous but are assigned to object
   6698   // properties.
   6699   DECL_ACCESSORS(inferred_name, String)
   6700 
   6701   // The function's name if it is non-empty, otherwise the inferred name.
   6702   String* DebugName();
   6703 
   6704   // Position of the 'function' token in the script source.
   6705   inline int function_token_position() const;
   6706   inline void set_function_token_position(int function_token_position);
   6707 
   6708   // Position of this function in the script source.
   6709   inline int start_position() const;
   6710   inline void set_start_position(int start_position);
   6711 
   6712   // End position of this function in the script source.
   6713   inline int end_position() const;
   6714   inline void set_end_position(int end_position);
   6715 
   6716   // Is this function a function expression in the source code.
   6717   DECL_BOOLEAN_ACCESSORS(is_expression)
   6718 
   6719   // Is this function a top-level function (scripts, evals).
   6720   DECL_BOOLEAN_ACCESSORS(is_toplevel)
   6721 
   6722   // Bit field containing various information collected by the compiler to
   6723   // drive optimization.
   6724   inline int compiler_hints() const;
   6725   inline void set_compiler_hints(int value);
   6726 
   6727   inline int ast_node_count() const;
   6728   inline void set_ast_node_count(int count);
   6729 
   6730   inline int profiler_ticks() const;
   6731   inline void set_profiler_ticks(int ticks);
   6732 
   6733   // Inline cache age is used to infer whether the function survived a context
   6734   // disposal or not. In the former case we reset the opt_count.
   6735   inline int ic_age();
   6736   inline void set_ic_age(int age);
   6737 
   6738   // Indicates if this function can be lazy compiled.
   6739   // This is used to determine if we can safely flush code from a function
   6740   // when doing GC if we expect that the function will no longer be used.
   6741   DECL_BOOLEAN_ACCESSORS(allows_lazy_compilation)
   6742 
   6743   // Indicates if this function can be lazy compiled without a context.
   6744   // This is used to determine if we can force compilation without reaching
   6745   // the function through program execution but through other means (e.g. heap
   6746   // iteration by the debugger).
   6747   DECL_BOOLEAN_ACCESSORS(allows_lazy_compilation_without_context)
   6748 
   6749   // Indicates whether optimizations have been disabled for this
   6750   // shared function info. If a function is repeatedly optimized or if
   6751   // we cannot optimize the function we disable optimization to avoid
   6752   // spending time attempting to optimize it again.
   6753   DECL_BOOLEAN_ACCESSORS(optimization_disabled)
   6754 
   6755   // Indicates the language mode.
   6756   inline StrictMode strict_mode();
   6757   inline void set_strict_mode(StrictMode strict_mode);
   6758 
   6759   // False if the function definitely does not allocate an arguments object.
   6760   DECL_BOOLEAN_ACCESSORS(uses_arguments)
   6761 
   6762   // True if the function has any duplicated parameter names.
   6763   DECL_BOOLEAN_ACCESSORS(has_duplicate_parameters)
   6764 
   6765   // Indicates whether the function is a native function.
   6766   // These needs special treatment in .call and .apply since
   6767   // null passed as the receiver should not be translated to the
   6768   // global object.
   6769   DECL_BOOLEAN_ACCESSORS(native)
   6770 
   6771   // Indicate that this builtin needs to be inlined in crankshaft.
   6772   DECL_BOOLEAN_ACCESSORS(inline_builtin)
   6773 
   6774   // Indicates that the function was created by the Function function.
   6775   // Though it's anonymous, toString should treat it as if it had the name
   6776   // "anonymous".  We don't set the name itself so that the system does not
   6777   // see a binding for it.
   6778   DECL_BOOLEAN_ACCESSORS(name_should_print_as_anonymous)
   6779 
   6780   // Indicates whether the function is a bound function created using
   6781   // the bind function.
   6782   DECL_BOOLEAN_ACCESSORS(bound)
   6783 
   6784   // Indicates that the function is anonymous (the name field can be set
   6785   // through the API, which does not change this flag).
   6786   DECL_BOOLEAN_ACCESSORS(is_anonymous)
   6787 
   6788   // Is this a function or top-level/eval code.
   6789   DECL_BOOLEAN_ACCESSORS(is_function)
   6790 
   6791   // Indicates that code for this function cannot be cached.
   6792   DECL_BOOLEAN_ACCESSORS(dont_cache)
   6793 
   6794   // Indicates that code for this function cannot be flushed.
   6795   DECL_BOOLEAN_ACCESSORS(dont_flush)
   6796 
   6797   // Indicates that this function is a generator.
   6798   DECL_BOOLEAN_ACCESSORS(is_generator)
   6799 
   6800   // Indicates that this function is an arrow function.
   6801   DECL_BOOLEAN_ACCESSORS(is_arrow)
   6802 
   6803   // Indicates that this function is a concise method.
   6804   DECL_BOOLEAN_ACCESSORS(is_concise_method)
   6805 
   6806   // Indicates that this function is an asm function.
   6807   DECL_BOOLEAN_ACCESSORS(asm_function)
   6808 
   6809   inline FunctionKind kind();
   6810   inline void set_kind(FunctionKind kind);
   6811 
   6812   // Indicates whether or not the code in the shared function support
   6813   // deoptimization.
   6814   inline bool has_deoptimization_support();
   6815 
   6816   // Enable deoptimization support through recompiled code.
   6817   void EnableDeoptimizationSupport(Code* recompiled);
   6818 
   6819   // Disable (further) attempted optimization of all functions sharing this
   6820   // shared function info.
   6821   void DisableOptimization(BailoutReason reason);
   6822 
   6823   inline BailoutReason DisableOptimizationReason();
   6824 
   6825   // Lookup the bailout ID and DCHECK that it exists in the non-optimized
   6826   // code, returns whether it asserted (i.e., always true if assertions are
   6827   // disabled).
   6828   bool VerifyBailoutId(BailoutId id);
   6829 
   6830   // [source code]: Source code for the function.
   6831   bool HasSourceCode() const;
   6832   Handle<Object> GetSourceCode();
   6833 
   6834   // Number of times the function was optimized.
   6835   inline int opt_count();
   6836   inline void set_opt_count(int opt_count);
   6837 
   6838   // Number of times the function was deoptimized.
   6839   inline void set_deopt_count(int value);
   6840   inline int deopt_count();
   6841   inline void increment_deopt_count();
   6842 
   6843   // Number of time we tried to re-enable optimization after it
   6844   // was disabled due to high number of deoptimizations.
   6845   inline void set_opt_reenable_tries(int value);
   6846   inline int opt_reenable_tries();
   6847 
   6848   inline void TryReenableOptimization();
   6849 
   6850   // Stores deopt_count, opt_reenable_tries and ic_age as bit-fields.
   6851   inline void set_counters(int value);
   6852   inline int counters() const;
   6853 
   6854   // Stores opt_count and bailout_reason as bit-fields.
   6855   inline void set_opt_count_and_bailout_reason(int value);
   6856   inline int opt_count_and_bailout_reason() const;
   6857 
   6858   void set_bailout_reason(BailoutReason reason) {
   6859     set_opt_count_and_bailout_reason(
   6860         DisabledOptimizationReasonBits::update(opt_count_and_bailout_reason(),
   6861                                                reason));
   6862   }
   6863 
   6864   // Check whether or not this function is inlineable.
   6865   bool IsInlineable();
   6866 
   6867   // Source size of this function.
   6868   int SourceSize();
   6869 
   6870   // Calculate the instance size.
   6871   int CalculateInstanceSize();
   6872 
   6873   // Calculate the number of in-object properties.
   6874   int CalculateInObjectProperties();
   6875 
   6876   // Dispatched behavior.
   6877   DECLARE_PRINTER(SharedFunctionInfo)
   6878   DECLARE_VERIFIER(SharedFunctionInfo)
   6879 
   6880   void ResetForNewContext(int new_ic_age);
   6881 
   6882   DECLARE_CAST(SharedFunctionInfo)
   6883 
   6884   // Constants.
   6885   static const int kDontAdaptArgumentsSentinel = -1;
   6886 
   6887   // Layout description.
   6888   // Pointer fields.
   6889   static const int kNameOffset = HeapObject::kHeaderSize;
   6890   static const int kCodeOffset = kNameOffset + kPointerSize;
   6891   static const int kOptimizedCodeMapOffset = kCodeOffset + kPointerSize;
   6892   static const int kScopeInfoOffset = kOptimizedCodeMapOffset + kPointerSize;
   6893   static const int kConstructStubOffset = kScopeInfoOffset + kPointerSize;
   6894   static const int kInstanceClassNameOffset =
   6895       kConstructStubOffset + kPointerSize;
   6896   static const int kFunctionDataOffset =
   6897       kInstanceClassNameOffset + kPointerSize;
   6898   static const int kScriptOffset = kFunctionDataOffset + kPointerSize;
   6899   static const int kDebugInfoOffset = kScriptOffset + kPointerSize;
   6900   static const int kInferredNameOffset = kDebugInfoOffset + kPointerSize;
   6901   static const int kFeedbackVectorOffset =
   6902       kInferredNameOffset + kPointerSize;
   6903 #if V8_HOST_ARCH_32_BIT
   6904   // Smi fields.
   6905   static const int kLengthOffset =
   6906       kFeedbackVectorOffset + kPointerSize;
   6907   static const int kFormalParameterCountOffset = kLengthOffset + kPointerSize;
   6908   static const int kExpectedNofPropertiesOffset =
   6909       kFormalParameterCountOffset + kPointerSize;
   6910   static const int kNumLiteralsOffset =
   6911       kExpectedNofPropertiesOffset + kPointerSize;
   6912   static const int kStartPositionAndTypeOffset =
   6913       kNumLiteralsOffset + kPointerSize;
   6914   static const int kEndPositionOffset =
   6915       kStartPositionAndTypeOffset + kPointerSize;
   6916   static const int kFunctionTokenPositionOffset =
   6917       kEndPositionOffset + kPointerSize;
   6918   static const int kCompilerHintsOffset =
   6919       kFunctionTokenPositionOffset + kPointerSize;
   6920   static const int kOptCountAndBailoutReasonOffset =
   6921       kCompilerHintsOffset + kPointerSize;
   6922   static const int kCountersOffset =
   6923       kOptCountAndBailoutReasonOffset + kPointerSize;
   6924   static const int kAstNodeCountOffset =
   6925       kCountersOffset + kPointerSize;
   6926   static const int kProfilerTicksOffset =
   6927       kAstNodeCountOffset + kPointerSize;
   6928 
   6929   // Total size.
   6930   static const int kSize = kProfilerTicksOffset + kPointerSize;
   6931 #else
   6932   // The only reason to use smi fields instead of int fields
   6933   // is to allow iteration without maps decoding during
   6934   // garbage collections.
   6935   // To avoid wasting space on 64-bit architectures we use
   6936   // the following trick: we group integer fields into pairs
   6937   // First integer in each pair is shifted left by 1.
   6938   // By doing this we guarantee that LSB of each kPointerSize aligned
   6939   // word is not set and thus this word cannot be treated as pointer
   6940   // to HeapObject during old space traversal.
   6941   static const int kLengthOffset =
   6942       kFeedbackVectorOffset + kPointerSize;
   6943   static const int kFormalParameterCountOffset =
   6944       kLengthOffset + kIntSize;
   6945 
   6946   static const int kExpectedNofPropertiesOffset =
   6947       kFormalParameterCountOffset + kIntSize;
   6948   static const int kNumLiteralsOffset =
   6949       kExpectedNofPropertiesOffset + kIntSize;
   6950 
   6951   static const int kEndPositionOffset =
   6952       kNumLiteralsOffset + kIntSize;
   6953   static const int kStartPositionAndTypeOffset =
   6954       kEndPositionOffset + kIntSize;
   6955 
   6956   static const int kFunctionTokenPositionOffset =
   6957       kStartPositionAndTypeOffset + kIntSize;
   6958   static const int kCompilerHintsOffset =
   6959       kFunctionTokenPositionOffset + kIntSize;
   6960 
   6961   static const int kOptCountAndBailoutReasonOffset =
   6962       kCompilerHintsOffset + kIntSize;
   6963   static const int kCountersOffset =
   6964       kOptCountAndBailoutReasonOffset + kIntSize;
   6965 
   6966   static const int kAstNodeCountOffset =
   6967       kCountersOffset + kIntSize;
   6968   static const int kProfilerTicksOffset =
   6969       kAstNodeCountOffset + kIntSize;
   6970 
   6971   // Total size.
   6972   static const int kSize = kProfilerTicksOffset + kIntSize;
   6973 
   6974 #endif
   6975 
   6976   static const int kAlignedSize = POINTER_SIZE_ALIGN(kSize);
   6977 
   6978   typedef FixedBodyDescriptor<kNameOffset,
   6979                               kFeedbackVectorOffset + kPointerSize,
   6980                               kSize> BodyDescriptor;
   6981 
   6982   // Bit positions in start_position_and_type.
   6983   // The source code start position is in the 30 most significant bits of
   6984   // the start_position_and_type field.
   6985   static const int kIsExpressionBit    = 0;
   6986   static const int kIsTopLevelBit      = 1;
   6987   static const int kStartPositionShift = 2;
   6988   static const int kStartPositionMask  = ~((1 << kStartPositionShift) - 1);
   6989 
   6990   // Bit positions in compiler_hints.
   6991   enum CompilerHints {
   6992     kAllowLazyCompilation,
   6993     kAllowLazyCompilationWithoutContext,
   6994     kOptimizationDisabled,
   6995     kStrictModeFunction,
   6996     kUsesArguments,
   6997     kHasDuplicateParameters,
   6998     kNative,
   6999     kInlineBuiltin,
   7000     kBoundFunction,
   7001     kIsAnonymous,
   7002     kNameShouldPrintAsAnonymous,
   7003     kIsFunction,
   7004     kDontCache,
   7005     kDontFlush,
   7006     kIsArrow,
   7007     kIsGenerator,
   7008     kIsConciseMethod,
   7009     kIsAsmFunction,
   7010     kCompilerHintsCount  // Pseudo entry
   7011   };
   7012 
   7013   class FunctionKindBits : public BitField<FunctionKind, kIsArrow, 3> {};
   7014 
   7015   class DeoptCountBits : public BitField<int, 0, 4> {};
   7016   class OptReenableTriesBits : public BitField<int, 4, 18> {};
   7017   class ICAgeBits : public BitField<int, 22, 8> {};
   7018 
   7019   class OptCountBits : public BitField<int, 0, 22> {};
   7020   class DisabledOptimizationReasonBits : public BitField<int, 22, 8> {};
   7021 
   7022  private:
   7023 #if V8_HOST_ARCH_32_BIT
   7024   // On 32 bit platforms, compiler hints is a smi.
   7025   static const int kCompilerHintsSmiTagSize = kSmiTagSize;
   7026   static const int kCompilerHintsSize = kPointerSize;
   7027 #else
   7028   // On 64 bit platforms, compiler hints is not a smi, see comment above.
   7029   static const int kCompilerHintsSmiTagSize = 0;
   7030   static const int kCompilerHintsSize = kIntSize;
   7031 #endif
   7032 
   7033   STATIC_ASSERT(SharedFunctionInfo::kCompilerHintsCount <=
   7034                 SharedFunctionInfo::kCompilerHintsSize * kBitsPerByte);
   7035 
   7036  public:
   7037   // Constants for optimizing codegen for strict mode function and
   7038   // native tests.
   7039   // Allows to use byte-width instructions.
   7040   static const int kStrictModeBitWithinByte =
   7041       (kStrictModeFunction + kCompilerHintsSmiTagSize) % kBitsPerByte;
   7042 
   7043   static const int kNativeBitWithinByte =
   7044       (kNative + kCompilerHintsSmiTagSize) % kBitsPerByte;
   7045 
   7046 #if defined(V8_TARGET_LITTLE_ENDIAN)
   7047   static const int kStrictModeByteOffset = kCompilerHintsOffset +
   7048       (kStrictModeFunction + kCompilerHintsSmiTagSize) / kBitsPerByte;
   7049   static const int kNativeByteOffset = kCompilerHintsOffset +
   7050       (kNative + kCompilerHintsSmiTagSize) / kBitsPerByte;
   7051 #elif defined(V8_TARGET_BIG_ENDIAN)
   7052   static const int kStrictModeByteOffset = kCompilerHintsOffset +
   7053       (kCompilerHintsSize - 1) -
   7054       ((kStrictModeFunction + kCompilerHintsSmiTagSize) / kBitsPerByte);
   7055   static const int kNativeByteOffset = kCompilerHintsOffset +
   7056       (kCompilerHintsSize - 1) -
   7057       ((kNative + kCompilerHintsSmiTagSize) / kBitsPerByte);
   7058 #else
   7059 #error Unknown byte ordering
   7060 #endif
   7061 
   7062  private:
   7063   DISALLOW_IMPLICIT_CONSTRUCTORS(SharedFunctionInfo);
   7064 };
   7065 
   7066 
   7067 // Printing support.
   7068 struct SourceCodeOf {
   7069   explicit SourceCodeOf(SharedFunctionInfo* v, int max = -1)
   7070       : value(v), max_length(max) {}
   7071   const SharedFunctionInfo* value;
   7072   int max_length;
   7073 };
   7074 
   7075 
   7076 OStream& operator<<(OStream& os, const SourceCodeOf& v);
   7077 
   7078 
   7079 class JSGeneratorObject: public JSObject {
   7080  public:
   7081   // [function]: The function corresponding to this generator object.
   7082   DECL_ACCESSORS(function, JSFunction)
   7083 
   7084   // [context]: The context of the suspended computation.
   7085   DECL_ACCESSORS(context, Context)
   7086 
   7087   // [receiver]: The receiver of the suspended computation.
   7088   DECL_ACCESSORS(receiver, Object)
   7089 
   7090   // [continuation]: Offset into code of continuation.
   7091   //
   7092   // A positive offset indicates a suspended generator.  The special
   7093   // kGeneratorExecuting and kGeneratorClosed values indicate that a generator
   7094   // cannot be resumed.
   7095   inline int continuation() const;
   7096   inline void set_continuation(int continuation);
   7097   inline bool is_closed();
   7098   inline bool is_executing();
   7099   inline bool is_suspended();
   7100 
   7101   // [operand_stack]: Saved operand stack.
   7102   DECL_ACCESSORS(operand_stack, FixedArray)
   7103 
   7104   // [stack_handler_index]: Index of first stack handler in operand_stack, or -1
   7105   // if the captured activation had no stack handler.
   7106   inline int stack_handler_index() const;
   7107   inline void set_stack_handler_index(int stack_handler_index);
   7108 
   7109   DECLARE_CAST(JSGeneratorObject)
   7110 
   7111   // Dispatched behavior.
   7112   DECLARE_PRINTER(JSGeneratorObject)
   7113   DECLARE_VERIFIER(JSGeneratorObject)
   7114 
   7115   // Magic sentinel values for the continuation.
   7116   static const int kGeneratorExecuting = -1;
   7117   static const int kGeneratorClosed = 0;
   7118 
   7119   // Layout description.
   7120   static const int kFunctionOffset = JSObject::kHeaderSize;
   7121   static const int kContextOffset = kFunctionOffset + kPointerSize;
   7122   static const int kReceiverOffset = kContextOffset + kPointerSize;
   7123   static const int kContinuationOffset = kReceiverOffset + kPointerSize;
   7124   static const int kOperandStackOffset = kContinuationOffset + kPointerSize;
   7125   static const int kStackHandlerIndexOffset =
   7126       kOperandStackOffset + kPointerSize;
   7127   static const int kSize = kStackHandlerIndexOffset + kPointerSize;
   7128 
   7129   // Resume mode, for use by runtime functions.
   7130   enum ResumeMode { NEXT, THROW };
   7131 
   7132   // Yielding from a generator returns an object with the following inobject
   7133   // properties.  See Context::iterator_result_map() for the map.
   7134   static const int kResultValuePropertyIndex = 0;
   7135   static const int kResultDonePropertyIndex = 1;
   7136   static const int kResultPropertyCount = 2;
   7137 
   7138   static const int kResultValuePropertyOffset = JSObject::kHeaderSize;
   7139   static const int kResultDonePropertyOffset =
   7140       kResultValuePropertyOffset + kPointerSize;
   7141   static const int kResultSize = kResultDonePropertyOffset + kPointerSize;
   7142 
   7143  private:
   7144   DISALLOW_IMPLICIT_CONSTRUCTORS(JSGeneratorObject);
   7145 };
   7146 
   7147 
   7148 // Representation for module instance objects.
   7149 class JSModule: public JSObject {
   7150  public:
   7151   // [context]: the context holding the module's locals, or undefined if none.
   7152   DECL_ACCESSORS(context, Object)
   7153 
   7154   // [scope_info]: Scope info.
   7155   DECL_ACCESSORS(scope_info, ScopeInfo)
   7156 
   7157   DECLARE_CAST(JSModule)
   7158 
   7159   // Dispatched behavior.
   7160   DECLARE_PRINTER(JSModule)
   7161   DECLARE_VERIFIER(JSModule)
   7162 
   7163   // Layout description.
   7164   static const int kContextOffset = JSObject::kHeaderSize;
   7165   static const int kScopeInfoOffset = kContextOffset + kPointerSize;
   7166   static const int kSize = kScopeInfoOffset + kPointerSize;
   7167 
   7168  private:
   7169   DISALLOW_IMPLICIT_CONSTRUCTORS(JSModule);
   7170 };
   7171 
   7172 
   7173 // JSFunction describes JavaScript functions.
   7174 class JSFunction: public JSObject {
   7175  public:
   7176   // [prototype_or_initial_map]:
   7177   DECL_ACCESSORS(prototype_or_initial_map, Object)
   7178 
   7179   // [shared]: The information about the function that
   7180   // can be shared by instances.
   7181   DECL_ACCESSORS(shared, SharedFunctionInfo)
   7182 
   7183   // [context]: The context for this function.
   7184   inline Context* context();
   7185   inline void set_context(Object* context);
   7186   inline JSObject* global_proxy();
   7187 
   7188   // [code]: The generated code object for this function.  Executed
   7189   // when the function is invoked, e.g. foo() or new foo(). See
   7190   // [[Call]] and [[Construct]] description in ECMA-262, section
   7191   // 8.6.2, page 27.
   7192   inline Code* code();
   7193   inline void set_code(Code* code);
   7194   inline void set_code_no_write_barrier(Code* code);
   7195   inline void ReplaceCode(Code* code);
   7196 
   7197   // Tells whether this function is builtin.
   7198   inline bool IsBuiltin();
   7199 
   7200   // Tells whether this function is defined in a native script.
   7201   inline bool IsFromNativeScript();
   7202 
   7203   // Tells whether this function is defined in an extension script.
   7204   inline bool IsFromExtensionScript();
   7205 
   7206   // Tells whether or not the function needs arguments adaption.
   7207   inline bool NeedsArgumentsAdaption();
   7208 
   7209   // Tells whether or not this function has been optimized.
   7210   inline bool IsOptimized();
   7211 
   7212   // Tells whether or not this function can be optimized.
   7213   inline bool IsOptimizable();
   7214 
   7215   // Mark this function for lazy recompilation. The function will be
   7216   // recompiled the next time it is executed.
   7217   void MarkForOptimization();
   7218   void MarkForConcurrentOptimization();
   7219   void MarkInOptimizationQueue();
   7220 
   7221   // Tells whether or not the function is already marked for lazy
   7222   // recompilation.
   7223   inline bool IsMarkedForOptimization();
   7224   inline bool IsMarkedForConcurrentOptimization();
   7225 
   7226   // Tells whether or not the function is on the concurrent recompilation queue.
   7227   inline bool IsInOptimizationQueue();
   7228 
   7229   // Inobject slack tracking is the way to reclaim unused inobject space.
   7230   //
   7231   // The instance size is initially determined by adding some slack to
   7232   // expected_nof_properties (to allow for a few extra properties added
   7233   // after the constructor). There is no guarantee that the extra space
   7234   // will not be wasted.
   7235   //
   7236   // Here is the algorithm to reclaim the unused inobject space:
   7237   // - Detect the first constructor call for this JSFunction.
   7238   //   When it happens enter the "in progress" state: initialize construction
   7239   //   counter in the initial_map and set the |done_inobject_slack_tracking|
   7240   //   flag.
   7241   // - While the tracking is in progress create objects filled with
   7242   //   one_pointer_filler_map instead of undefined_value. This way they can be
   7243   //   resized quickly and safely.
   7244   // - Once enough (kGenerousAllocationCount) objects have been created
   7245   //   compute the 'slack' (traverse the map transition tree starting from the
   7246   //   initial_map and find the lowest value of unused_property_fields).
   7247   // - Traverse the transition tree again and decrease the instance size
   7248   //   of every map. Existing objects will resize automatically (they are
   7249   //   filled with one_pointer_filler_map). All further allocations will
   7250   //   use the adjusted instance size.
   7251   // - SharedFunctionInfo's expected_nof_properties left unmodified since
   7252   //   allocations made using different closures could actually create different
   7253   //   kind of objects (see prototype inheritance pattern).
   7254   //
   7255   //  Important: inobject slack tracking is not attempted during the snapshot
   7256   //  creation.
   7257 
   7258   static const int kGenerousAllocationCount = Map::ConstructionCount::kMax;
   7259   static const int kFinishSlackTracking     = 1;
   7260   static const int kNoSlackTracking         = 0;
   7261 
   7262   // True if the initial_map is set and the object constructions countdown
   7263   // counter is not zero.
   7264   inline bool IsInobjectSlackTrackingInProgress();
   7265 
   7266   // Starts the tracking.
   7267   // Initializes object constructions countdown counter in the initial map.
   7268   // IsInobjectSlackTrackingInProgress is normally true after this call,
   7269   // except when tracking have not been started (e.g. the map has no unused
   7270   // properties or the snapshot is being built).
   7271   void StartInobjectSlackTracking();
   7272 
   7273   // Completes the tracking.
   7274   // IsInobjectSlackTrackingInProgress is false after this call.
   7275   void CompleteInobjectSlackTracking();
   7276 
   7277   // [literals_or_bindings]: Fixed array holding either
   7278   // the materialized literals or the bindings of a bound function.
   7279   //
   7280   // If the function contains object, regexp or array literals, the
   7281   // literals array prefix contains the object, regexp, and array
   7282   // function to be used when creating these literals.  This is
   7283   // necessary so that we do not dynamically lookup the object, regexp
   7284   // or array functions.  Performing a dynamic lookup, we might end up
   7285   // using the functions from a new context that we should not have
   7286   // access to.
   7287   //
   7288   // On bound functions, the array is a (copy-on-write) fixed-array containing
   7289   // the function that was bound, bound this-value and any bound
   7290   // arguments. Bound functions never contain literals.
   7291   DECL_ACCESSORS(literals_or_bindings, FixedArray)
   7292 
   7293   inline FixedArray* literals();
   7294   inline void set_literals(FixedArray* literals);
   7295 
   7296   inline FixedArray* function_bindings();
   7297   inline void set_function_bindings(FixedArray* bindings);
   7298 
   7299   // The initial map for an object created by this constructor.
   7300   inline Map* initial_map();
   7301   static void SetInitialMap(Handle<JSFunction> function, Handle<Map> map,
   7302                             Handle<Object> prototype);
   7303   inline bool has_initial_map();
   7304   static void EnsureHasInitialMap(Handle<JSFunction> function);
   7305 
   7306   // Get and set the prototype property on a JSFunction. If the
   7307   // function has an initial map the prototype is set on the initial
   7308   // map. Otherwise, the prototype is put in the initial map field
   7309   // until an initial map is needed.
   7310   inline bool has_prototype();
   7311   inline bool has_instance_prototype();
   7312   inline Object* prototype();
   7313   inline Object* instance_prototype();
   7314   static void SetPrototype(Handle<JSFunction> function,
   7315                            Handle<Object> value);
   7316   static void SetInstancePrototype(Handle<JSFunction> function,
   7317                                    Handle<Object> value);
   7318 
   7319   // Creates a new closure for the fucntion with the same bindings,
   7320   // bound values, and prototype. An equivalent of spec operations
   7321   // ``CloneMethod`` and ``CloneBoundFunction``.
   7322   static Handle<JSFunction> CloneClosure(Handle<JSFunction> function);
   7323 
   7324   // After prototype is removed, it will not be created when accessed, and
   7325   // [[Construct]] from this function will not be allowed.
   7326   bool RemovePrototype();
   7327   inline bool should_have_prototype();
   7328 
   7329   // Accessor for this function's initial map's [[class]]
   7330   // property. This is primarily used by ECMA native functions.  This
   7331   // method sets the class_name field of this function's initial map
   7332   // to a given value. It creates an initial map if this function does
   7333   // not have one. Note that this method does not copy the initial map
   7334   // if it has one already, but simply replaces it with the new value.
   7335   // Instances created afterwards will have a map whose [[class]] is
   7336   // set to 'value', but there is no guarantees on instances created
   7337   // before.
   7338   void SetInstanceClassName(String* name);
   7339 
   7340   // Returns if this function has been compiled to native code yet.
   7341   inline bool is_compiled();
   7342 
   7343   // [next_function_link]: Links functions into various lists, e.g. the list
   7344   // of optimized functions hanging off the native_context. The CodeFlusher
   7345   // uses this link to chain together flushing candidates. Treated weakly
   7346   // by the garbage collector.
   7347   DECL_ACCESSORS(next_function_link, Object)
   7348 
   7349   // Prints the name of the function using PrintF.
   7350   void PrintName(FILE* out = stdout);
   7351 
   7352   DECLARE_CAST(JSFunction)
   7353 
   7354   // Iterates the objects, including code objects indirectly referenced
   7355   // through pointers to the first instruction in the code object.
   7356   void JSFunctionIterateBody(int object_size, ObjectVisitor* v);
   7357 
   7358   // Dispatched behavior.
   7359   DECLARE_PRINTER(JSFunction)
   7360   DECLARE_VERIFIER(JSFunction)
   7361 
   7362   // Returns the number of allocated literals.
   7363   inline int NumberOfLiterals();
   7364 
   7365   // Retrieve the native context from a function's literal array.
   7366   static Context* NativeContextFromLiterals(FixedArray* literals);
   7367 
   7368   // Used for flags such as --hydrogen-filter.
   7369   bool PassesFilter(const char* raw_filter);
   7370 
   7371   // Layout descriptors. The last property (from kNonWeakFieldsEndOffset to
   7372   // kSize) is weak and has special handling during garbage collection.
   7373   static const int kCodeEntryOffset = JSObject::kHeaderSize;
   7374   static const int kPrototypeOrInitialMapOffset =
   7375       kCodeEntryOffset + kPointerSize;
   7376   static const int kSharedFunctionInfoOffset =
   7377       kPrototypeOrInitialMapOffset + kPointerSize;
   7378   static const int kContextOffset = kSharedFunctionInfoOffset + kPointerSize;
   7379   static const int kLiteralsOffset = kContextOffset + kPointerSize;
   7380   static const int kNonWeakFieldsEndOffset = kLiteralsOffset + kPointerSize;
   7381   static const int kNextFunctionLinkOffset = kNonWeakFieldsEndOffset;
   7382   static const int kSize = kNextFunctionLinkOffset + kPointerSize;
   7383 
   7384   // Layout of the literals array.
   7385   static const int kLiteralsPrefixSize = 1;
   7386   static const int kLiteralNativeContextIndex = 0;
   7387 
   7388   // Layout of the bound-function binding array.
   7389   static const int kBoundFunctionIndex = 0;
   7390   static const int kBoundThisIndex = 1;
   7391   static const int kBoundArgumentsStartIndex = 2;
   7392 
   7393  private:
   7394   DISALLOW_IMPLICIT_CONSTRUCTORS(JSFunction);
   7395 };
   7396 
   7397 
   7398 // JSGlobalProxy's prototype must be a JSGlobalObject or null,
   7399 // and the prototype is hidden. JSGlobalProxy always delegates
   7400 // property accesses to its prototype if the prototype is not null.
   7401 //
   7402 // A JSGlobalProxy can be reinitialized which will preserve its identity.
   7403 //
   7404 // Accessing a JSGlobalProxy requires security check.
   7405 
   7406 class JSGlobalProxy : public JSObject {
   7407  public:
   7408   // [native_context]: the owner native context of this global proxy object.
   7409   // It is null value if this object is not used by any context.
   7410   DECL_ACCESSORS(native_context, Object)
   7411 
   7412   // [hash]: The hash code property (undefined if not initialized yet).
   7413   DECL_ACCESSORS(hash, Object)
   7414 
   7415   DECLARE_CAST(JSGlobalProxy)
   7416 
   7417   inline bool IsDetachedFrom(GlobalObject* global) const;
   7418 
   7419   // Dispatched behavior.
   7420   DECLARE_PRINTER(JSGlobalProxy)
   7421   DECLARE_VERIFIER(JSGlobalProxy)
   7422 
   7423   // Layout description.
   7424   static const int kNativeContextOffset = JSObject::kHeaderSize;
   7425   static const int kHashOffset = kNativeContextOffset + kPointerSize;
   7426   static const int kSize = kHashOffset + kPointerSize;
   7427 
   7428  private:
   7429   DISALLOW_IMPLICIT_CONSTRUCTORS(JSGlobalProxy);
   7430 };
   7431 
   7432 
   7433 // Forward declaration.
   7434 class JSBuiltinsObject;
   7435 
   7436 // Common super class for JavaScript global objects and the special
   7437 // builtins global objects.
   7438 class GlobalObject: public JSObject {
   7439  public:
   7440   // [builtins]: the object holding the runtime routines written in JS.
   7441   DECL_ACCESSORS(builtins, JSBuiltinsObject)
   7442 
   7443   // [native context]: the natives corresponding to this global object.
   7444   DECL_ACCESSORS(native_context, Context)
   7445 
   7446   // [global context]: the most recent (i.e. innermost) global context.
   7447   DECL_ACCESSORS(global_context, Context)
   7448 
   7449   // [global proxy]: the global proxy object of the context
   7450   DECL_ACCESSORS(global_proxy, JSObject)
   7451 
   7452   DECLARE_CAST(GlobalObject)
   7453 
   7454   // Layout description.
   7455   static const int kBuiltinsOffset = JSObject::kHeaderSize;
   7456   static const int kNativeContextOffset = kBuiltinsOffset + kPointerSize;
   7457   static const int kGlobalContextOffset = kNativeContextOffset + kPointerSize;
   7458   static const int kGlobalProxyOffset = kGlobalContextOffset + kPointerSize;
   7459   static const int kHeaderSize = kGlobalProxyOffset + kPointerSize;
   7460 
   7461  private:
   7462   DISALLOW_IMPLICIT_CONSTRUCTORS(GlobalObject);
   7463 };
   7464 
   7465 
   7466 // JavaScript global object.
   7467 class JSGlobalObject: public GlobalObject {
   7468  public:
   7469   DECLARE_CAST(JSGlobalObject)
   7470 
   7471   // Ensure that the global object has a cell for the given property name.
   7472   static Handle<PropertyCell> EnsurePropertyCell(Handle<JSGlobalObject> global,
   7473                                                  Handle<Name> name);
   7474 
   7475   inline bool IsDetached();
   7476 
   7477   // Dispatched behavior.
   7478   DECLARE_PRINTER(JSGlobalObject)
   7479   DECLARE_VERIFIER(JSGlobalObject)
   7480 
   7481   // Layout description.
   7482   static const int kSize = GlobalObject::kHeaderSize;
   7483 
   7484  private:
   7485   DISALLOW_IMPLICIT_CONSTRUCTORS(JSGlobalObject);
   7486 };
   7487 
   7488 
   7489 // Builtins global object which holds the runtime routines written in
   7490 // JavaScript.
   7491 class JSBuiltinsObject: public GlobalObject {
   7492  public:
   7493   // Accessors for the runtime routines written in JavaScript.
   7494   inline Object* javascript_builtin(Builtins::JavaScript id);
   7495   inline void set_javascript_builtin(Builtins::JavaScript id, Object* value);
   7496 
   7497   // Accessors for code of the runtime routines written in JavaScript.
   7498   inline Code* javascript_builtin_code(Builtins::JavaScript id);
   7499   inline void set_javascript_builtin_code(Builtins::JavaScript id, Code* value);
   7500 
   7501   DECLARE_CAST(JSBuiltinsObject)
   7502 
   7503   // Dispatched behavior.
   7504   DECLARE_PRINTER(JSBuiltinsObject)
   7505   DECLARE_VERIFIER(JSBuiltinsObject)
   7506 
   7507   // Layout description.  The size of the builtins object includes
   7508   // room for two pointers per runtime routine written in javascript
   7509   // (function and code object).
   7510   static const int kJSBuiltinsCount = Builtins::id_count;
   7511   static const int kJSBuiltinsOffset = GlobalObject::kHeaderSize;
   7512   static const int kJSBuiltinsCodeOffset =
   7513       GlobalObject::kHeaderSize + (kJSBuiltinsCount * kPointerSize);
   7514   static const int kSize =
   7515       kJSBuiltinsCodeOffset + (kJSBuiltinsCount * kPointerSize);
   7516 
   7517   static int OffsetOfFunctionWithId(Builtins::JavaScript id) {
   7518     return kJSBuiltinsOffset + id * kPointerSize;
   7519   }
   7520 
   7521   static int OffsetOfCodeWithId(Builtins::JavaScript id) {
   7522     return kJSBuiltinsCodeOffset + id * kPointerSize;
   7523   }
   7524 
   7525  private:
   7526   DISALLOW_IMPLICIT_CONSTRUCTORS(JSBuiltinsObject);
   7527 };
   7528 
   7529 
   7530 // Representation for JS Wrapper objects, String, Number, Boolean, etc.
   7531 class JSValue: public JSObject {
   7532  public:
   7533   // [value]: the object being wrapped.
   7534   DECL_ACCESSORS(value, Object)
   7535 
   7536   DECLARE_CAST(JSValue)
   7537 
   7538   // Dispatched behavior.
   7539   DECLARE_PRINTER(JSValue)
   7540   DECLARE_VERIFIER(JSValue)
   7541 
   7542   // Layout description.
   7543   static const int kValueOffset = JSObject::kHeaderSize;
   7544   static const int kSize = kValueOffset + kPointerSize;
   7545 
   7546  private:
   7547   DISALLOW_IMPLICIT_CONSTRUCTORS(JSValue);
   7548 };
   7549 
   7550 
   7551 class DateCache;
   7552 
   7553 // Representation for JS date objects.
   7554 class JSDate: public JSObject {
   7555  public:
   7556   // If one component is NaN, all of them are, indicating a NaN time value.
   7557   // [value]: the time value.
   7558   DECL_ACCESSORS(value, Object)
   7559   // [year]: caches year. Either undefined, smi, or NaN.
   7560   DECL_ACCESSORS(year, Object)
   7561   // [month]: caches month. Either undefined, smi, or NaN.
   7562   DECL_ACCESSORS(month, Object)
   7563   // [day]: caches day. Either undefined, smi, or NaN.
   7564   DECL_ACCESSORS(day, Object)
   7565   // [weekday]: caches day of week. Either undefined, smi, or NaN.
   7566   DECL_ACCESSORS(weekday, Object)
   7567   // [hour]: caches hours. Either undefined, smi, or NaN.
   7568   DECL_ACCESSORS(hour, Object)
   7569   // [min]: caches minutes. Either undefined, smi, or NaN.
   7570   DECL_ACCESSORS(min, Object)
   7571   // [sec]: caches seconds. Either undefined, smi, or NaN.
   7572   DECL_ACCESSORS(sec, Object)
   7573   // [cache stamp]: sample of the date cache stamp at the
   7574   // moment when chached fields were cached.
   7575   DECL_ACCESSORS(cache_stamp, Object)
   7576 
   7577   DECLARE_CAST(JSDate)
   7578 
   7579   // Returns the date field with the specified index.
   7580   // See FieldIndex for the list of date fields.
   7581   static Object* GetField(Object* date, Smi* index);
   7582 
   7583   void SetValue(Object* value, bool is_value_nan);
   7584 
   7585 
   7586   // Dispatched behavior.
   7587   DECLARE_PRINTER(JSDate)
   7588   DECLARE_VERIFIER(JSDate)
   7589 
   7590   // The order is important. It must be kept in sync with date macros
   7591   // in macros.py.
   7592   enum FieldIndex {
   7593     kDateValue,
   7594     kYear,
   7595     kMonth,
   7596     kDay,
   7597     kWeekday,
   7598     kHour,
   7599     kMinute,
   7600     kSecond,
   7601     kFirstUncachedField,
   7602     kMillisecond = kFirstUncachedField,
   7603     kDays,
   7604     kTimeInDay,
   7605     kFirstUTCField,
   7606     kYearUTC = kFirstUTCField,
   7607     kMonthUTC,
   7608     kDayUTC,
   7609     kWeekdayUTC,
   7610     kHourUTC,
   7611     kMinuteUTC,
   7612     kSecondUTC,
   7613     kMillisecondUTC,
   7614     kDaysUTC,
   7615     kTimeInDayUTC,
   7616     kTimezoneOffset
   7617   };
   7618 
   7619   // Layout description.
   7620   static const int kValueOffset = JSObject::kHeaderSize;
   7621   static const int kYearOffset = kValueOffset + kPointerSize;
   7622   static const int kMonthOffset = kYearOffset + kPointerSize;
   7623   static const int kDayOffset = kMonthOffset + kPointerSize;
   7624   static const int kWeekdayOffset = kDayOffset + kPointerSize;
   7625   static const int kHourOffset = kWeekdayOffset  + kPointerSize;
   7626   static const int kMinOffset = kHourOffset + kPointerSize;
   7627   static const int kSecOffset = kMinOffset + kPointerSize;
   7628   static const int kCacheStampOffset = kSecOffset + kPointerSize;
   7629   static const int kSize = kCacheStampOffset + kPointerSize;
   7630 
   7631  private:
   7632   inline Object* DoGetField(FieldIndex index);
   7633 
   7634   Object* GetUTCField(FieldIndex index, double value, DateCache* date_cache);
   7635 
   7636   // Computes and caches the cacheable fields of the date.
   7637   inline void SetCachedFields(int64_t local_time_ms, DateCache* date_cache);
   7638 
   7639 
   7640   DISALLOW_IMPLICIT_CONSTRUCTORS(JSDate);
   7641 };
   7642 
   7643 
   7644 // Representation of message objects used for error reporting through
   7645 // the API. The messages are formatted in JavaScript so this object is
   7646 // a real JavaScript object. The information used for formatting the
   7647 // error messages are not directly accessible from JavaScript to
   7648 // prevent leaking information to user code called during error
   7649 // formatting.
   7650 class JSMessageObject: public JSObject {
   7651  public:
   7652   // [type]: the type of error message.
   7653   DECL_ACCESSORS(type, String)
   7654 
   7655   // [arguments]: the arguments for formatting the error message.
   7656   DECL_ACCESSORS(arguments, JSArray)
   7657 
   7658   // [script]: the script from which the error message originated.
   7659   DECL_ACCESSORS(script, Object)
   7660 
   7661   // [stack_frames]: an array of stack frames for this error object.
   7662   DECL_ACCESSORS(stack_frames, Object)
   7663 
   7664   // [start_position]: the start position in the script for the error message.
   7665   inline int start_position() const;
   7666   inline void set_start_position(int value);
   7667 
   7668   // [end_position]: the end position in the script for the error message.
   7669   inline int end_position() const;
   7670   inline void set_end_position(int value);
   7671 
   7672   DECLARE_CAST(JSMessageObject)
   7673 
   7674   // Dispatched behavior.
   7675   DECLARE_PRINTER(JSMessageObject)
   7676   DECLARE_VERIFIER(JSMessageObject)
   7677 
   7678   // Layout description.
   7679   static const int kTypeOffset = JSObject::kHeaderSize;
   7680   static const int kArgumentsOffset = kTypeOffset + kPointerSize;
   7681   static const int kScriptOffset = kArgumentsOffset + kPointerSize;
   7682   static const int kStackFramesOffset = kScriptOffset + kPointerSize;
   7683   static const int kStartPositionOffset = kStackFramesOffset + kPointerSize;
   7684   static const int kEndPositionOffset = kStartPositionOffset + kPointerSize;
   7685   static const int kSize = kEndPositionOffset + kPointerSize;
   7686 
   7687   typedef FixedBodyDescriptor<HeapObject::kMapOffset,
   7688                               kStackFramesOffset + kPointerSize,
   7689                               kSize> BodyDescriptor;
   7690 };
   7691 
   7692 
   7693 // Regular expressions
   7694 // The regular expression holds a single reference to a FixedArray in
   7695 // the kDataOffset field.
   7696 // The FixedArray contains the following data:
   7697 // - tag : type of regexp implementation (not compiled yet, atom or irregexp)
   7698 // - reference to the original source string
   7699 // - reference to the original flag string
   7700 // If it is an atom regexp
   7701 // - a reference to a literal string to search for
   7702 // If it is an irregexp regexp:
   7703 // - a reference to code for Latin1 inputs (bytecode or compiled), or a smi
   7704 // used for tracking the last usage (used for code flushing).
   7705 // - a reference to code for UC16 inputs (bytecode or compiled), or a smi
   7706 // used for tracking the last usage (used for code flushing)..
   7707 // - max number of registers used by irregexp implementations.
   7708 // - number of capture registers (output values) of the regexp.
   7709 class JSRegExp: public JSObject {
   7710  public:
   7711   // Meaning of Type:
   7712   // NOT_COMPILED: Initial value. No data has been stored in the JSRegExp yet.
   7713   // ATOM: A simple string to match against using an indexOf operation.
   7714   // IRREGEXP: Compiled with Irregexp.
   7715   // IRREGEXP_NATIVE: Compiled to native code with Irregexp.
   7716   enum Type { NOT_COMPILED, ATOM, IRREGEXP };
   7717   enum Flag {
   7718     NONE = 0,
   7719     GLOBAL = 1,
   7720     IGNORE_CASE = 2,
   7721     MULTILINE = 4,
   7722     STICKY = 8
   7723   };
   7724 
   7725   class Flags {
   7726    public:
   7727     explicit Flags(uint32_t value) : value_(value) { }
   7728     bool is_global() { return (value_ & GLOBAL) != 0; }
   7729     bool is_ignore_case() { return (value_ & IGNORE_CASE) != 0; }
   7730     bool is_multiline() { return (value_ & MULTILINE) != 0; }
   7731     bool is_sticky() { return (value_ & STICKY) != 0; }
   7732     uint32_t value() { return value_; }
   7733    private:
   7734     uint32_t value_;
   7735   };
   7736 
   7737   DECL_ACCESSORS(data, Object)
   7738 
   7739   inline Type TypeTag();
   7740   inline int CaptureCount();
   7741   inline Flags GetFlags();
   7742   inline String* Pattern();
   7743   inline Object* DataAt(int index);
   7744   // Set implementation data after the object has been prepared.
   7745   inline void SetDataAt(int index, Object* value);
   7746 
   7747   static int code_index(bool is_latin1) {
   7748     if (is_latin1) {
   7749       return kIrregexpLatin1CodeIndex;
   7750     } else {
   7751       return kIrregexpUC16CodeIndex;
   7752     }
   7753   }
   7754 
   7755   static int saved_code_index(bool is_latin1) {
   7756     if (is_latin1) {
   7757       return kIrregexpLatin1CodeSavedIndex;
   7758     } else {
   7759       return kIrregexpUC16CodeSavedIndex;
   7760     }
   7761   }
   7762 
   7763   DECLARE_CAST(JSRegExp)
   7764 
   7765   // Dispatched behavior.
   7766   DECLARE_VERIFIER(JSRegExp)
   7767 
   7768   static const int kDataOffset = JSObject::kHeaderSize;
   7769   static const int kSize = kDataOffset + kPointerSize;
   7770 
   7771   // Indices in the data array.
   7772   static const int kTagIndex = 0;
   7773   static const int kSourceIndex = kTagIndex + 1;
   7774   static const int kFlagsIndex = kSourceIndex + 1;
   7775   static const int kDataIndex = kFlagsIndex + 1;
   7776   // The data fields are used in different ways depending on the
   7777   // value of the tag.
   7778   // Atom regexps (literal strings).
   7779   static const int kAtomPatternIndex = kDataIndex;
   7780 
   7781   static const int kAtomDataSize = kAtomPatternIndex + 1;
   7782 
   7783   // Irregexp compiled code or bytecode for Latin1. If compilation
   7784   // fails, this fields hold an exception object that should be
   7785   // thrown if the regexp is used again.
   7786   static const int kIrregexpLatin1CodeIndex = kDataIndex;
   7787   // Irregexp compiled code or bytecode for UC16.  If compilation
   7788   // fails, this fields hold an exception object that should be
   7789   // thrown if the regexp is used again.
   7790   static const int kIrregexpUC16CodeIndex = kDataIndex + 1;
   7791 
   7792   // Saved instance of Irregexp compiled code or bytecode for Latin1 that
   7793   // is a potential candidate for flushing.
   7794   static const int kIrregexpLatin1CodeSavedIndex = kDataIndex + 2;
   7795   // Saved instance of Irregexp compiled code or bytecode for UC16 that is
   7796   // a potential candidate for flushing.
   7797   static const int kIrregexpUC16CodeSavedIndex = kDataIndex + 3;
   7798 
   7799   // Maximal number of registers used by either Latin1 or UC16.
   7800   // Only used to check that there is enough stack space
   7801   static const int kIrregexpMaxRegisterCountIndex = kDataIndex + 4;
   7802   // Number of captures in the compiled regexp.
   7803   static const int kIrregexpCaptureCountIndex = kDataIndex + 5;
   7804 
   7805   static const int kIrregexpDataSize = kIrregexpCaptureCountIndex + 1;
   7806 
   7807   // Offsets directly into the data fixed array.
   7808   static const int kDataTagOffset =
   7809       FixedArray::kHeaderSize + kTagIndex * kPointerSize;
   7810   static const int kDataOneByteCodeOffset =
   7811       FixedArray::kHeaderSize + kIrregexpLatin1CodeIndex * kPointerSize;
   7812   static const int kDataUC16CodeOffset =
   7813       FixedArray::kHeaderSize + kIrregexpUC16CodeIndex * kPointerSize;
   7814   static const int kIrregexpCaptureCountOffset =
   7815       FixedArray::kHeaderSize + kIrregexpCaptureCountIndex * kPointerSize;
   7816 
   7817   // In-object fields.
   7818   static const int kSourceFieldIndex = 0;
   7819   static const int kGlobalFieldIndex = 1;
   7820   static const int kIgnoreCaseFieldIndex = 2;
   7821   static const int kMultilineFieldIndex = 3;
   7822   static const int kLastIndexFieldIndex = 4;
   7823   static const int kInObjectFieldCount = 5;
   7824 
   7825   // The uninitialized value for a regexp code object.
   7826   static const int kUninitializedValue = -1;
   7827 
   7828   // The compilation error value for the regexp code object. The real error
   7829   // object is in the saved code field.
   7830   static const int kCompilationErrorValue = -2;
   7831 
   7832   // When we store the sweep generation at which we moved the code from the
   7833   // code index to the saved code index we mask it of to be in the [0:255]
   7834   // range.
   7835   static const int kCodeAgeMask = 0xff;
   7836 };
   7837 
   7838 
   7839 class CompilationCacheShape : public BaseShape<HashTableKey*> {
   7840  public:
   7841   static inline bool IsMatch(HashTableKey* key, Object* value) {
   7842     return key->IsMatch(value);
   7843   }
   7844 
   7845   static inline uint32_t Hash(HashTableKey* key) {
   7846     return key->Hash();
   7847   }
   7848 
   7849   static inline uint32_t HashForObject(HashTableKey* key, Object* object) {
   7850     return key->HashForObject(object);
   7851   }
   7852 
   7853   static inline Handle<Object> AsHandle(Isolate* isolate, HashTableKey* key);
   7854 
   7855   static const int kPrefixSize = 0;
   7856   static const int kEntrySize = 2;
   7857 };
   7858 
   7859 
   7860 class CompilationCacheTable: public HashTable<CompilationCacheTable,
   7861                                               CompilationCacheShape,
   7862                                               HashTableKey*> {
   7863  public:
   7864   // Find cached value for a string key, otherwise return null.
   7865   Handle<Object> Lookup(Handle<String> src, Handle<Context> context);
   7866   Handle<Object> LookupEval(Handle<String> src,
   7867                             Handle<SharedFunctionInfo> shared,
   7868                             StrictMode strict_mode, int scope_position);
   7869   Handle<Object> LookupRegExp(Handle<String> source, JSRegExp::Flags flags);
   7870   static Handle<CompilationCacheTable> Put(
   7871       Handle<CompilationCacheTable> cache, Handle<String> src,
   7872       Handle<Context> context, Handle<Object> value);
   7873   static Handle<CompilationCacheTable> PutEval(
   7874       Handle<CompilationCacheTable> cache, Handle<String> src,
   7875       Handle<SharedFunctionInfo> context, Handle<SharedFunctionInfo> value,
   7876       int scope_position);
   7877   static Handle<CompilationCacheTable> PutRegExp(
   7878       Handle<CompilationCacheTable> cache, Handle<String> src,
   7879       JSRegExp::Flags flags, Handle<FixedArray> value);
   7880   void Remove(Object* value);
   7881 
   7882   DECLARE_CAST(CompilationCacheTable)
   7883 
   7884  private:
   7885   DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationCacheTable);
   7886 };
   7887 
   7888 
   7889 class CodeCache: public Struct {
   7890  public:
   7891   DECL_ACCESSORS(default_cache, FixedArray)
   7892   DECL_ACCESSORS(normal_type_cache, Object)
   7893 
   7894   // Add the code object to the cache.
   7895   static void Update(
   7896       Handle<CodeCache> cache, Handle<Name> name, Handle<Code> code);
   7897 
   7898   // Lookup code object in the cache. Returns code object if found and undefined
   7899   // if not.
   7900   Object* Lookup(Name* name, Code::Flags flags);
   7901 
   7902   // Get the internal index of a code object in the cache. Returns -1 if the
   7903   // code object is not in that cache. This index can be used to later call
   7904   // RemoveByIndex. The cache cannot be modified between a call to GetIndex and
   7905   // RemoveByIndex.
   7906   int GetIndex(Object* name, Code* code);
   7907 
   7908   // Remove an object from the cache with the provided internal index.
   7909   void RemoveByIndex(Object* name, Code* code, int index);
   7910 
   7911   DECLARE_CAST(CodeCache)
   7912 
   7913   // Dispatched behavior.
   7914   DECLARE_PRINTER(CodeCache)
   7915   DECLARE_VERIFIER(CodeCache)
   7916 
   7917   static const int kDefaultCacheOffset = HeapObject::kHeaderSize;
   7918   static const int kNormalTypeCacheOffset =
   7919       kDefaultCacheOffset + kPointerSize;
   7920   static const int kSize = kNormalTypeCacheOffset + kPointerSize;
   7921 
   7922  private:
   7923   static void UpdateDefaultCache(
   7924       Handle<CodeCache> code_cache, Handle<Name> name, Handle<Code> code);
   7925   static void UpdateNormalTypeCache(
   7926       Handle<CodeCache> code_cache, Handle<Name> name, Handle<Code> code);
   7927   Object* LookupDefaultCache(Name* name, Code::Flags flags);
   7928   Object* LookupNormalTypeCache(Name* name, Code::Flags flags);
   7929 
   7930   // Code cache layout of the default cache. Elements are alternating name and
   7931   // code objects for non normal load/store/call IC's.
   7932   static const int kCodeCacheEntrySize = 2;
   7933   static const int kCodeCacheEntryNameOffset = 0;
   7934   static const int kCodeCacheEntryCodeOffset = 1;
   7935 
   7936   DISALLOW_IMPLICIT_CONSTRUCTORS(CodeCache);
   7937 };
   7938 
   7939 
   7940 class CodeCacheHashTableShape : public BaseShape<HashTableKey*> {
   7941  public:
   7942   static inline bool IsMatch(HashTableKey* key, Object* value) {
   7943     return key->IsMatch(value);
   7944   }
   7945 
   7946   static inline uint32_t Hash(HashTableKey* key) {
   7947     return key->Hash();
   7948   }
   7949 
   7950   static inline uint32_t HashForObject(HashTableKey* key, Object* object) {
   7951     return key->HashForObject(object);
   7952   }
   7953 
   7954   static inline Handle<Object> AsHandle(Isolate* isolate, HashTableKey* key);
   7955 
   7956   static const int kPrefixSize = 0;
   7957   static const int kEntrySize = 2;
   7958 };
   7959 
   7960 
   7961 class CodeCacheHashTable: public HashTable<CodeCacheHashTable,
   7962                                            CodeCacheHashTableShape,
   7963                                            HashTableKey*> {
   7964  public:
   7965   Object* Lookup(Name* name, Code::Flags flags);
   7966   static Handle<CodeCacheHashTable> Put(
   7967       Handle<CodeCacheHashTable> table,
   7968       Handle<Name> name,
   7969       Handle<Code> code);
   7970 
   7971   int GetIndex(Name* name, Code::Flags flags);
   7972   void RemoveByIndex(int index);
   7973 
   7974   DECLARE_CAST(CodeCacheHashTable)
   7975 
   7976   // Initial size of the fixed array backing the hash table.
   7977   static const int kInitialSize = 64;
   7978 
   7979  private:
   7980   DISALLOW_IMPLICIT_CONSTRUCTORS(CodeCacheHashTable);
   7981 };
   7982 
   7983 
   7984 class PolymorphicCodeCache: public Struct {
   7985  public:
   7986   DECL_ACCESSORS(cache, Object)
   7987 
   7988   static void Update(Handle<PolymorphicCodeCache> cache,
   7989                      MapHandleList* maps,
   7990                      Code::Flags flags,
   7991                      Handle<Code> code);
   7992 
   7993 
   7994   // Returns an undefined value if the entry is not found.
   7995   Handle<Object> Lookup(MapHandleList* maps, Code::Flags flags);
   7996 
   7997   DECLARE_CAST(PolymorphicCodeCache)
   7998 
   7999   // Dispatched behavior.
   8000   DECLARE_PRINTER(PolymorphicCodeCache)
   8001   DECLARE_VERIFIER(PolymorphicCodeCache)
   8002 
   8003   static const int kCacheOffset = HeapObject::kHeaderSize;
   8004   static const int kSize = kCacheOffset + kPointerSize;
   8005 
   8006  private:
   8007   DISALLOW_IMPLICIT_CONSTRUCTORS(PolymorphicCodeCache);
   8008 };
   8009 
   8010 
   8011 class PolymorphicCodeCacheHashTable
   8012     : public HashTable<PolymorphicCodeCacheHashTable,
   8013                        CodeCacheHashTableShape,
   8014                        HashTableKey*> {
   8015  public:
   8016   Object* Lookup(MapHandleList* maps, int code_kind);
   8017 
   8018   static Handle<PolymorphicCodeCacheHashTable> Put(
   8019       Handle<PolymorphicCodeCacheHashTable> hash_table,
   8020       MapHandleList* maps,
   8021       int code_kind,
   8022       Handle<Code> code);
   8023 
   8024   DECLARE_CAST(PolymorphicCodeCacheHashTable)
   8025 
   8026   static const int kInitialSize = 64;
   8027  private:
   8028   DISALLOW_IMPLICIT_CONSTRUCTORS(PolymorphicCodeCacheHashTable);
   8029 };
   8030 
   8031 
   8032 class TypeFeedbackInfo: public Struct {
   8033  public:
   8034   inline int ic_total_count();
   8035   inline void set_ic_total_count(int count);
   8036 
   8037   inline int ic_with_type_info_count();
   8038   inline void change_ic_with_type_info_count(int delta);
   8039 
   8040   inline int ic_generic_count();
   8041   inline void change_ic_generic_count(int delta);
   8042 
   8043   inline void initialize_storage();
   8044 
   8045   inline void change_own_type_change_checksum();
   8046   inline int own_type_change_checksum();
   8047 
   8048   inline void set_inlined_type_change_checksum(int checksum);
   8049   inline bool matches_inlined_type_change_checksum(int checksum);
   8050 
   8051 
   8052   DECLARE_CAST(TypeFeedbackInfo)
   8053 
   8054   // Dispatched behavior.
   8055   DECLARE_PRINTER(TypeFeedbackInfo)
   8056   DECLARE_VERIFIER(TypeFeedbackInfo)
   8057 
   8058   static const int kStorage1Offset = HeapObject::kHeaderSize;
   8059   static const int kStorage2Offset = kStorage1Offset + kPointerSize;
   8060   static const int kStorage3Offset = kStorage2Offset + kPointerSize;
   8061   static const int kSize = kStorage3Offset + kPointerSize;
   8062 
   8063  private:
   8064   static const int kTypeChangeChecksumBits = 7;
   8065 
   8066   class ICTotalCountField: public BitField<int, 0,
   8067       kSmiValueSize - kTypeChangeChecksumBits> {};  // NOLINT
   8068   class OwnTypeChangeChecksum: public BitField<int,
   8069       kSmiValueSize - kTypeChangeChecksumBits,
   8070       kTypeChangeChecksumBits> {};  // NOLINT
   8071   class ICsWithTypeInfoCountField: public BitField<int, 0,
   8072       kSmiValueSize - kTypeChangeChecksumBits> {};  // NOLINT
   8073   class InlinedTypeChangeChecksum: public BitField<int,
   8074       kSmiValueSize - kTypeChangeChecksumBits,
   8075       kTypeChangeChecksumBits> {};  // NOLINT
   8076 
   8077   DISALLOW_IMPLICIT_CONSTRUCTORS(TypeFeedbackInfo);
   8078 };
   8079 
   8080 
   8081 enum AllocationSiteMode {
   8082   DONT_TRACK_ALLOCATION_SITE,
   8083   TRACK_ALLOCATION_SITE,
   8084   LAST_ALLOCATION_SITE_MODE = TRACK_ALLOCATION_SITE
   8085 };
   8086 
   8087 
   8088 class AllocationSite: public Struct {
   8089  public:
   8090   static const uint32_t kMaximumArrayBytesToPretransition = 8 * 1024;
   8091   static const double kPretenureRatio;
   8092   static const int kPretenureMinimumCreated = 100;
   8093 
   8094   // Values for pretenure decision field.
   8095   enum PretenureDecision {
   8096     kUndecided = 0,
   8097     kDontTenure = 1,
   8098     kMaybeTenure = 2,
   8099     kTenure = 3,
   8100     kZombie = 4,
   8101     kLastPretenureDecisionValue = kZombie
   8102   };
   8103 
   8104   const char* PretenureDecisionName(PretenureDecision decision);
   8105 
   8106   DECL_ACCESSORS(transition_info, Object)
   8107   // nested_site threads a list of sites that represent nested literals
   8108   // walked in a particular order. So [[1, 2], 1, 2] will have one
   8109   // nested_site, but [[1, 2], 3, [4]] will have a list of two.
   8110   DECL_ACCESSORS(nested_site, Object)
   8111   DECL_ACCESSORS(pretenure_data, Smi)
   8112   DECL_ACCESSORS(pretenure_create_count, Smi)
   8113   DECL_ACCESSORS(dependent_code, DependentCode)
   8114   DECL_ACCESSORS(weak_next, Object)
   8115 
   8116   inline void Initialize();
   8117 
   8118   // This method is expensive, it should only be called for reporting.
   8119   bool IsNestedSite();
   8120 
   8121   // transition_info bitfields, for constructed array transition info.
   8122   class ElementsKindBits:       public BitField<ElementsKind, 0,  15> {};
   8123   class UnusedBits:             public BitField<int,          15, 14> {};
   8124   class DoNotInlineBit:         public BitField<bool,         29,  1> {};
   8125 
   8126   // Bitfields for pretenure_data
   8127   class MementoFoundCountBits:  public BitField<int,               0, 26> {};
   8128   class PretenureDecisionBits:  public BitField<PretenureDecision, 26, 3> {};
   8129   class DeoptDependentCodeBit:  public BitField<bool,              29, 1> {};
   8130   STATIC_ASSERT(PretenureDecisionBits::kMax >= kLastPretenureDecisionValue);
   8131 
   8132   // Increments the mementos found counter and returns true when the first
   8133   // memento was found for a given allocation site.
   8134   inline bool IncrementMementoFoundCount();
   8135 
   8136   inline void IncrementMementoCreateCount();
   8137 
   8138   PretenureFlag GetPretenureMode();
   8139 
   8140   void ResetPretenureDecision();
   8141 
   8142   PretenureDecision pretenure_decision() {
   8143     int value = pretenure_data()->value();
   8144     return PretenureDecisionBits::decode(value);
   8145   }
   8146 
   8147   void set_pretenure_decision(PretenureDecision decision) {
   8148     int value = pretenure_data()->value();
   8149     set_pretenure_data(
   8150         Smi::FromInt(PretenureDecisionBits::update(value, decision)),
   8151         SKIP_WRITE_BARRIER);
   8152   }
   8153 
   8154   bool deopt_dependent_code() {
   8155     int value = pretenure_data()->value();
   8156     return DeoptDependentCodeBit::decode(value);
   8157   }
   8158 
   8159   void set_deopt_dependent_code(bool deopt) {
   8160     int value = pretenure_data()->value();
   8161     set_pretenure_data(
   8162         Smi::FromInt(DeoptDependentCodeBit::update(value, deopt)),
   8163         SKIP_WRITE_BARRIER);
   8164   }
   8165 
   8166   int memento_found_count() {
   8167     int value = pretenure_data()->value();
   8168     return MementoFoundCountBits::decode(value);
   8169   }
   8170 
   8171   inline void set_memento_found_count(int count);
   8172 
   8173   int memento_create_count() {
   8174     return pretenure_create_count()->value();
   8175   }
   8176 
   8177   void set_memento_create_count(int count) {
   8178     set_pretenure_create_count(Smi::FromInt(count), SKIP_WRITE_BARRIER);
   8179   }
   8180 
   8181   // The pretenuring decision is made during gc, and the zombie state allows
   8182   // us to recognize when an allocation site is just being kept alive because
   8183   // a later traversal of new space may discover AllocationMementos that point
   8184   // to this AllocationSite.
   8185   bool IsZombie() {
   8186     return pretenure_decision() == kZombie;
   8187   }
   8188 
   8189   bool IsMaybeTenure() {
   8190     return pretenure_decision() == kMaybeTenure;
   8191   }
   8192 
   8193   inline void MarkZombie();
   8194 
   8195   inline bool MakePretenureDecision(PretenureDecision current_decision,
   8196                                     double ratio,
   8197                                     bool maximum_size_scavenge);
   8198 
   8199   inline bool DigestPretenuringFeedback(bool maximum_size_scavenge);
   8200 
   8201   ElementsKind GetElementsKind() {
   8202     DCHECK(!SitePointsToLiteral());
   8203     int value = Smi::cast(transition_info())->value();
   8204     return ElementsKindBits::decode(value);
   8205   }
   8206 
   8207   void SetElementsKind(ElementsKind kind) {
   8208     int value = Smi::cast(transition_info())->value();
   8209     set_transition_info(Smi::FromInt(ElementsKindBits::update(value, kind)),
   8210                         SKIP_WRITE_BARRIER);
   8211   }
   8212 
   8213   bool CanInlineCall() {
   8214     int value = Smi::cast(transition_info())->value();
   8215     return DoNotInlineBit::decode(value) == 0;
   8216   }
   8217 
   8218   void SetDoNotInlineCall() {
   8219     int value = Smi::cast(transition_info())->value();
   8220     set_transition_info(Smi::FromInt(DoNotInlineBit::update(value, true)),
   8221                         SKIP_WRITE_BARRIER);
   8222   }
   8223 
   8224   bool SitePointsToLiteral() {
   8225     // If transition_info is a smi, then it represents an ElementsKind
   8226     // for a constructed array. Otherwise, it must be a boilerplate
   8227     // for an object or array literal.
   8228     return transition_info()->IsJSArray() || transition_info()->IsJSObject();
   8229   }
   8230 
   8231   static void DigestTransitionFeedback(Handle<AllocationSite> site,
   8232                                        ElementsKind to_kind);
   8233 
   8234   enum Reason {
   8235     TENURING,
   8236     TRANSITIONS
   8237   };
   8238 
   8239   static void AddDependentCompilationInfo(Handle<AllocationSite> site,
   8240                                           Reason reason,
   8241                                           CompilationInfo* info);
   8242 
   8243   DECLARE_PRINTER(AllocationSite)
   8244   DECLARE_VERIFIER(AllocationSite)
   8245 
   8246   DECLARE_CAST(AllocationSite)
   8247   static inline AllocationSiteMode GetMode(
   8248       ElementsKind boilerplate_elements_kind);
   8249   static inline AllocationSiteMode GetMode(ElementsKind from, ElementsKind to);
   8250   static inline bool CanTrack(InstanceType type);
   8251 
   8252   static const int kTransitionInfoOffset = HeapObject::kHeaderSize;
   8253   static const int kNestedSiteOffset = kTransitionInfoOffset + kPointerSize;
   8254   static const int kPretenureDataOffset = kNestedSiteOffset + kPointerSize;
   8255   static const int kPretenureCreateCountOffset =
   8256       kPretenureDataOffset + kPointerSize;
   8257   static const int kDependentCodeOffset =
   8258       kPretenureCreateCountOffset + kPointerSize;
   8259   static const int kWeakNextOffset = kDependentCodeOffset + kPointerSize;
   8260   static const int kSize = kWeakNextOffset + kPointerSize;
   8261 
   8262   // During mark compact we need to take special care for the dependent code
   8263   // field.
   8264   static const int kPointerFieldsBeginOffset = kTransitionInfoOffset;
   8265   static const int kPointerFieldsEndOffset = kDependentCodeOffset;
   8266 
   8267   // For other visitors, use the fixed body descriptor below.
   8268   typedef FixedBodyDescriptor<HeapObject::kHeaderSize,
   8269                               kDependentCodeOffset + kPointerSize,
   8270                               kSize> BodyDescriptor;
   8271 
   8272  private:
   8273   inline DependentCode::DependencyGroup ToDependencyGroup(Reason reason);
   8274   bool PretenuringDecisionMade() {
   8275     return pretenure_decision() != kUndecided;
   8276   }
   8277 
   8278   DISALLOW_IMPLICIT_CONSTRUCTORS(AllocationSite);
   8279 };
   8280 
   8281 
   8282 class AllocationMemento: public Struct {
   8283  public:
   8284   static const int kAllocationSiteOffset = HeapObject::kHeaderSize;
   8285   static const int kSize = kAllocationSiteOffset + kPointerSize;
   8286 
   8287   DECL_ACCESSORS(allocation_site, Object)
   8288 
   8289   bool IsValid() {
   8290     return allocation_site()->IsAllocationSite() &&
   8291         !AllocationSite::cast(allocation_site())->IsZombie();
   8292   }
   8293   AllocationSite* GetAllocationSite() {
   8294     DCHECK(IsValid());
   8295     return AllocationSite::cast(allocation_site());
   8296   }
   8297 
   8298   DECLARE_PRINTER(AllocationMemento)
   8299   DECLARE_VERIFIER(AllocationMemento)
   8300 
   8301   DECLARE_CAST(AllocationMemento)
   8302 
   8303  private:
   8304   DISALLOW_IMPLICIT_CONSTRUCTORS(AllocationMemento);
   8305 };
   8306 
   8307 
   8308 // Representation of a slow alias as part of a sloppy arguments objects.
   8309 // For fast aliases (if HasSloppyArgumentsElements()):
   8310 // - the parameter map contains an index into the context
   8311 // - all attributes of the element have default values
   8312 // For slow aliases (if HasDictionaryArgumentsElements()):
   8313 // - the parameter map contains no fast alias mapping (i.e. the hole)
   8314 // - this struct (in the slow backing store) contains an index into the context
   8315 // - all attributes are available as part if the property details
   8316 class AliasedArgumentsEntry: public Struct {
   8317  public:
   8318   inline int aliased_context_slot() const;
   8319   inline void set_aliased_context_slot(int count);
   8320 
   8321   DECLARE_CAST(AliasedArgumentsEntry)
   8322 
   8323   // Dispatched behavior.
   8324   DECLARE_PRINTER(AliasedArgumentsEntry)
   8325   DECLARE_VERIFIER(AliasedArgumentsEntry)
   8326 
   8327   static const int kAliasedContextSlot = HeapObject::kHeaderSize;
   8328   static const int kSize = kAliasedContextSlot + kPointerSize;
   8329 
   8330  private:
   8331   DISALLOW_IMPLICIT_CONSTRUCTORS(AliasedArgumentsEntry);
   8332 };
   8333 
   8334 
   8335 enum AllowNullsFlag {ALLOW_NULLS, DISALLOW_NULLS};
   8336 enum RobustnessFlag {ROBUST_STRING_TRAVERSAL, FAST_STRING_TRAVERSAL};
   8337 
   8338 
   8339 class StringHasher {
   8340  public:
   8341   explicit inline StringHasher(int length, uint32_t seed);
   8342 
   8343   template <typename schar>
   8344   static inline uint32_t HashSequentialString(const schar* chars,
   8345                                               int length,
   8346                                               uint32_t seed);
   8347 
   8348   // Reads all the data, even for long strings and computes the utf16 length.
   8349   static uint32_t ComputeUtf8Hash(Vector<const char> chars,
   8350                                   uint32_t seed,
   8351                                   int* utf16_length_out);
   8352 
   8353   // Calculated hash value for a string consisting of 1 to
   8354   // String::kMaxArrayIndexSize digits with no leading zeros (except "0").
   8355   // value is represented decimal value.
   8356   static uint32_t MakeArrayIndexHash(uint32_t value, int length);
   8357 
   8358   // No string is allowed to have a hash of zero.  That value is reserved
   8359   // for internal properties.  If the hash calculation yields zero then we
   8360   // use 27 instead.
   8361   static const int kZeroHash = 27;
   8362 
   8363   // Reusable parts of the hashing algorithm.
   8364   INLINE(static uint32_t AddCharacterCore(uint32_t running_hash, uint16_t c));
   8365   INLINE(static uint32_t GetHashCore(uint32_t running_hash));
   8366 
   8367  protected:
   8368   // Returns the value to store in the hash field of a string with
   8369   // the given length and contents.
   8370   uint32_t GetHashField();
   8371   // Returns true if the hash of this string can be computed without
   8372   // looking at the contents.
   8373   inline bool has_trivial_hash();
   8374   // Adds a block of characters to the hash.
   8375   template<typename Char>
   8376   inline void AddCharacters(const Char* chars, int len);
   8377 
   8378  private:
   8379   // Add a character to the hash.
   8380   inline void AddCharacter(uint16_t c);
   8381   // Update index. Returns true if string is still an index.
   8382   inline bool UpdateIndex(uint16_t c);
   8383 
   8384   int length_;
   8385   uint32_t raw_running_hash_;
   8386   uint32_t array_index_;
   8387   bool is_array_index_;
   8388   bool is_first_char_;
   8389   DISALLOW_COPY_AND_ASSIGN(StringHasher);
   8390 };
   8391 
   8392 
   8393 class IteratingStringHasher : public StringHasher {
   8394  public:
   8395   static inline uint32_t Hash(String* string, uint32_t seed);
   8396   inline void VisitOneByteString(const uint8_t* chars, int length);
   8397   inline void VisitTwoByteString(const uint16_t* chars, int length);
   8398 
   8399  private:
   8400   inline IteratingStringHasher(int len, uint32_t seed)
   8401       : StringHasher(len, seed) {}
   8402   DISALLOW_COPY_AND_ASSIGN(IteratingStringHasher);
   8403 };
   8404 
   8405 
   8406 // The characteristics of a string are stored in its map.  Retrieving these
   8407 // few bits of information is moderately expensive, involving two memory
   8408 // loads where the second is dependent on the first.  To improve efficiency
   8409 // the shape of the string is given its own class so that it can be retrieved
   8410 // once and used for several string operations.  A StringShape is small enough
   8411 // to be passed by value and is immutable, but be aware that flattening a
   8412 // string can potentially alter its shape.  Also be aware that a GC caused by
   8413 // something else can alter the shape of a string due to ConsString
   8414 // shortcutting.  Keeping these restrictions in mind has proven to be error-
   8415 // prone and so we no longer put StringShapes in variables unless there is a
   8416 // concrete performance benefit at that particular point in the code.
   8417 class StringShape BASE_EMBEDDED {
   8418  public:
   8419   inline explicit StringShape(const String* s);
   8420   inline explicit StringShape(Map* s);
   8421   inline explicit StringShape(InstanceType t);
   8422   inline bool IsSequential();
   8423   inline bool IsExternal();
   8424   inline bool IsCons();
   8425   inline bool IsSliced();
   8426   inline bool IsIndirect();
   8427   inline bool IsExternalOneByte();
   8428   inline bool IsExternalTwoByte();
   8429   inline bool IsSequentialOneByte();
   8430   inline bool IsSequentialTwoByte();
   8431   inline bool IsInternalized();
   8432   inline StringRepresentationTag representation_tag();
   8433   inline uint32_t encoding_tag();
   8434   inline uint32_t full_representation_tag();
   8435   inline uint32_t size_tag();
   8436 #ifdef DEBUG
   8437   inline uint32_t type() { return type_; }
   8438   inline void invalidate() { valid_ = false; }
   8439   inline bool valid() { return valid_; }
   8440 #else
   8441   inline void invalidate() { }
   8442 #endif
   8443 
   8444  private:
   8445   uint32_t type_;
   8446 #ifdef DEBUG
   8447   inline void set_valid() { valid_ = true; }
   8448   bool valid_;
   8449 #else
   8450   inline void set_valid() { }
   8451 #endif
   8452 };
   8453 
   8454 
   8455 // The Name abstract class captures anything that can be used as a property
   8456 // name, i.e., strings and symbols.  All names store a hash value.
   8457 class Name: public HeapObject {
   8458  public:
   8459   // Get and set the hash field of the name.
   8460   inline uint32_t hash_field();
   8461   inline void set_hash_field(uint32_t value);
   8462 
   8463   // Tells whether the hash code has been computed.
   8464   inline bool HasHashCode();
   8465 
   8466   // Returns a hash value used for the property table
   8467   inline uint32_t Hash();
   8468 
   8469   // Equality operations.
   8470   inline bool Equals(Name* other);
   8471   inline static bool Equals(Handle<Name> one, Handle<Name> two);
   8472 
   8473   // Conversion.
   8474   inline bool AsArrayIndex(uint32_t* index);
   8475 
   8476   // Whether name can only name own properties.
   8477   inline bool IsOwn();
   8478 
   8479   DECLARE_CAST(Name)
   8480 
   8481   DECLARE_PRINTER(Name)
   8482 
   8483   // Layout description.
   8484   static const int kHashFieldOffset = HeapObject::kHeaderSize;
   8485   static const int kSize = kHashFieldOffset + kPointerSize;
   8486 
   8487   // Mask constant for checking if a name has a computed hash code
   8488   // and if it is a string that is an array index.  The least significant bit
   8489   // indicates whether a hash code has been computed.  If the hash code has
   8490   // been computed the 2nd bit tells whether the string can be used as an
   8491   // array index.
   8492   static const int kHashNotComputedMask = 1;
   8493   static const int kIsNotArrayIndexMask = 1 << 1;
   8494   static const int kNofHashBitFields = 2;
   8495 
   8496   // Shift constant retrieving hash code from hash field.
   8497   static const int kHashShift = kNofHashBitFields;
   8498 
   8499   // Only these bits are relevant in the hash, since the top two are shifted
   8500   // out.
   8501   static const uint32_t kHashBitMask = 0xffffffffu >> kHashShift;
   8502 
   8503   // Array index strings this short can keep their index in the hash field.
   8504   static const int kMaxCachedArrayIndexLength = 7;
   8505 
   8506   // For strings which are array indexes the hash value has the string length
   8507   // mixed into the hash, mainly to avoid a hash value of zero which would be
   8508   // the case for the string '0'. 24 bits are used for the array index value.
   8509   static const int kArrayIndexValueBits = 24;
   8510   static const int kArrayIndexLengthBits =
   8511       kBitsPerInt - kArrayIndexValueBits - kNofHashBitFields;
   8512 
   8513   STATIC_ASSERT((kArrayIndexLengthBits > 0));
   8514 
   8515   class ArrayIndexValueBits : public BitField<unsigned int, kNofHashBitFields,
   8516       kArrayIndexValueBits> {};  // NOLINT
   8517   class ArrayIndexLengthBits : public BitField<unsigned int,
   8518       kNofHashBitFields + kArrayIndexValueBits,
   8519       kArrayIndexLengthBits> {};  // NOLINT
   8520 
   8521   // Check that kMaxCachedArrayIndexLength + 1 is a power of two so we
   8522   // could use a mask to test if the length of string is less than or equal to
   8523   // kMaxCachedArrayIndexLength.
   8524   STATIC_ASSERT(IS_POWER_OF_TWO(kMaxCachedArrayIndexLength + 1));
   8525 
   8526   static const unsigned int kContainsCachedArrayIndexMask =
   8527       (~static_cast<unsigned>(kMaxCachedArrayIndexLength)
   8528        << ArrayIndexLengthBits::kShift) |
   8529       kIsNotArrayIndexMask;
   8530 
   8531   // Value of empty hash field indicating that the hash is not computed.
   8532   static const int kEmptyHashField =
   8533       kIsNotArrayIndexMask | kHashNotComputedMask;
   8534 
   8535  protected:
   8536   static inline bool IsHashFieldComputed(uint32_t field);
   8537 
   8538  private:
   8539   DISALLOW_IMPLICIT_CONSTRUCTORS(Name);
   8540 };
   8541 
   8542 
   8543 // ES6 symbols.
   8544 class Symbol: public Name {
   8545  public:
   8546   // [name]: the print name of a symbol, or undefined if none.
   8547   DECL_ACCESSORS(name, Object)
   8548 
   8549   DECL_ACCESSORS(flags, Smi)
   8550 
   8551   // [is_private]: whether this is a private symbol.
   8552   DECL_BOOLEAN_ACCESSORS(is_private)
   8553 
   8554   // [is_own]: whether this is an own symbol, that is, only used to designate
   8555   // own properties of objects.
   8556   DECL_BOOLEAN_ACCESSORS(is_own)
   8557 
   8558   DECLARE_CAST(Symbol)
   8559 
   8560   // Dispatched behavior.
   8561   DECLARE_PRINTER(Symbol)
   8562   DECLARE_VERIFIER(Symbol)
   8563 
   8564   // Layout description.
   8565   static const int kNameOffset = Name::kSize;
   8566   static const int kFlagsOffset = kNameOffset + kPointerSize;
   8567   static const int kSize = kFlagsOffset + kPointerSize;
   8568 
   8569   typedef FixedBodyDescriptor<kNameOffset, kFlagsOffset, kSize> BodyDescriptor;
   8570 
   8571  private:
   8572   static const int kPrivateBit = 0;
   8573   static const int kOwnBit = 1;
   8574 
   8575   DISALLOW_IMPLICIT_CONSTRUCTORS(Symbol);
   8576 };
   8577 
   8578 
   8579 class ConsString;
   8580 
   8581 // The String abstract class captures JavaScript string values:
   8582 //
   8583 // Ecma-262:
   8584 //  4.3.16 String Value
   8585 //    A string value is a member of the type String and is a finite
   8586 //    ordered sequence of zero or more 16-bit unsigned integer values.
   8587 //
   8588 // All string values have a length field.
   8589 class String: public Name {
   8590  public:
   8591   enum Encoding { ONE_BYTE_ENCODING, TWO_BYTE_ENCODING };
   8592 
   8593   // Array index strings this short can keep their index in the hash field.
   8594   static const int kMaxCachedArrayIndexLength = 7;
   8595 
   8596   // For strings which are array indexes the hash value has the string length
   8597   // mixed into the hash, mainly to avoid a hash value of zero which would be
   8598   // the case for the string '0'. 24 bits are used for the array index value.
   8599   static const int kArrayIndexValueBits = 24;
   8600   static const int kArrayIndexLengthBits =
   8601       kBitsPerInt - kArrayIndexValueBits - kNofHashBitFields;
   8602 
   8603   STATIC_ASSERT((kArrayIndexLengthBits > 0));
   8604 
   8605   class ArrayIndexValueBits : public BitField<unsigned int, kNofHashBitFields,
   8606       kArrayIndexValueBits> {};  // NOLINT
   8607   class ArrayIndexLengthBits : public BitField<unsigned int,
   8608       kNofHashBitFields + kArrayIndexValueBits,
   8609       kArrayIndexLengthBits> {};  // NOLINT
   8610 
   8611   // Check that kMaxCachedArrayIndexLength + 1 is a power of two so we
   8612   // could use a mask to test if the length of string is less than or equal to
   8613   // kMaxCachedArrayIndexLength.
   8614   STATIC_ASSERT(IS_POWER_OF_TWO(kMaxCachedArrayIndexLength + 1));
   8615 
   8616   static const unsigned int kContainsCachedArrayIndexMask =
   8617       (~static_cast<unsigned>(kMaxCachedArrayIndexLength)
   8618        << ArrayIndexLengthBits::kShift) |
   8619       kIsNotArrayIndexMask;
   8620 
   8621   // Representation of the flat content of a String.
   8622   // A non-flat string doesn't have flat content.
   8623   // A flat string has content that's encoded as a sequence of either
   8624   // one-byte chars or two-byte UC16.
   8625   // Returned by String::GetFlatContent().
   8626   class FlatContent {
   8627    public:
   8628     // Returns true if the string is flat and this structure contains content.
   8629     bool IsFlat() { return state_ != NON_FLAT; }
   8630     // Returns true if the structure contains one-byte content.
   8631     bool IsOneByte() { return state_ == ONE_BYTE; }
   8632     // Returns true if the structure contains two-byte content.
   8633     bool IsTwoByte() { return state_ == TWO_BYTE; }
   8634 
   8635     // Return the one byte content of the string. Only use if IsOneByte()
   8636     // returns true.
   8637     Vector<const uint8_t> ToOneByteVector() {
   8638       DCHECK_EQ(ONE_BYTE, state_);
   8639       return Vector<const uint8_t>(onebyte_start, length_);
   8640     }
   8641     // Return the two-byte content of the string. Only use if IsTwoByte()
   8642     // returns true.
   8643     Vector<const uc16> ToUC16Vector() {
   8644       DCHECK_EQ(TWO_BYTE, state_);
   8645       return Vector<const uc16>(twobyte_start, length_);
   8646     }
   8647 
   8648     uc16 Get(int i) {
   8649       DCHECK(i < length_);
   8650       DCHECK(state_ != NON_FLAT);
   8651       if (state_ == ONE_BYTE) return onebyte_start[i];
   8652       return twobyte_start[i];
   8653     }
   8654 
   8655    private:
   8656     enum State { NON_FLAT, ONE_BYTE, TWO_BYTE };
   8657 
   8658     // Constructors only used by String::GetFlatContent().
   8659     explicit FlatContent(const uint8_t* start, int length)
   8660         : onebyte_start(start), length_(length), state_(ONE_BYTE) {}
   8661     explicit FlatContent(const uc16* start, int length)
   8662         : twobyte_start(start), length_(length), state_(TWO_BYTE) { }
   8663     FlatContent() : onebyte_start(NULL), length_(0), state_(NON_FLAT) { }
   8664 
   8665     union {
   8666       const uint8_t* onebyte_start;
   8667       const uc16* twobyte_start;
   8668     };
   8669     int length_;
   8670     State state_;
   8671 
   8672     friend class String;
   8673   };
   8674 
   8675   // Get and set the length of the string.
   8676   inline int length() const;
   8677   inline void set_length(int value);
   8678 
   8679   // Get and set the length of the string using acquire loads and release
   8680   // stores.
   8681   inline int synchronized_length() const;
   8682   inline void synchronized_set_length(int value);
   8683 
   8684   // Returns whether this string has only one-byte chars, i.e. all of them can
   8685   // be one-byte encoded.  This might be the case even if the string is
   8686   // two-byte.  Such strings may appear when the embedder prefers
   8687   // two-byte external representations even for one-byte data.
   8688   inline bool IsOneByteRepresentation() const;
   8689   inline bool IsTwoByteRepresentation() const;
   8690 
   8691   // Cons and slices have an encoding flag that may not represent the actual
   8692   // encoding of the underlying string.  This is taken into account here.
   8693   // Requires: this->IsFlat()
   8694   inline bool IsOneByteRepresentationUnderneath();
   8695   inline bool IsTwoByteRepresentationUnderneath();
   8696 
   8697   // NOTE: this should be considered only a hint.  False negatives are
   8698   // possible.
   8699   inline bool HasOnlyOneByteChars();
   8700 
   8701   // Get and set individual two byte chars in the string.
   8702   inline void Set(int index, uint16_t value);
   8703   // Get individual two byte char in the string.  Repeated calls
   8704   // to this method are not efficient unless the string is flat.
   8705   INLINE(uint16_t Get(int index));
   8706 
   8707   // Flattens the string.  Checks first inline to see if it is
   8708   // necessary.  Does nothing if the string is not a cons string.
   8709   // Flattening allocates a sequential string with the same data as
   8710   // the given string and mutates the cons string to a degenerate
   8711   // form, where the first component is the new sequential string and
   8712   // the second component is the empty string.  If allocation fails,
   8713   // this function returns a failure.  If flattening succeeds, this
   8714   // function returns the sequential string that is now the first
   8715   // component of the cons string.
   8716   //
   8717   // Degenerate cons strings are handled specially by the garbage
   8718   // collector (see IsShortcutCandidate).
   8719 
   8720   static inline Handle<String> Flatten(Handle<String> string,
   8721                                        PretenureFlag pretenure = NOT_TENURED);
   8722 
   8723   // Tries to return the content of a flat string as a structure holding either
   8724   // a flat vector of char or of uc16.
   8725   // If the string isn't flat, and therefore doesn't have flat content, the
   8726   // returned structure will report so, and can't provide a vector of either
   8727   // kind.
   8728   FlatContent GetFlatContent();
   8729 
   8730   // Returns the parent of a sliced string or first part of a flat cons string.
   8731   // Requires: StringShape(this).IsIndirect() && this->IsFlat()
   8732   inline String* GetUnderlying();
   8733 
   8734   // Mark the string as an undetectable object. It only applies to
   8735   // one-byte and two-byte string types.
   8736   bool MarkAsUndetectable();
   8737 
   8738   // String equality operations.
   8739   inline bool Equals(String* other);
   8740   inline static bool Equals(Handle<String> one, Handle<String> two);
   8741   bool IsUtf8EqualTo(Vector<const char> str, bool allow_prefix_match = false);
   8742   bool IsOneByteEqualTo(Vector<const uint8_t> str);
   8743   bool IsTwoByteEqualTo(Vector<const uc16> str);
   8744 
   8745   // Return a UTF8 representation of the string.  The string is null
   8746   // terminated but may optionally contain nulls.  Length is returned
   8747   // in length_output if length_output is not a null pointer  The string
   8748   // should be nearly flat, otherwise the performance of this method may
   8749   // be very slow (quadratic in the length).  Setting robustness_flag to
   8750   // ROBUST_STRING_TRAVERSAL invokes behaviour that is robust  This means it
   8751   // handles unexpected data without causing assert failures and it does not
   8752   // do any heap allocations.  This is useful when printing stack traces.
   8753   SmartArrayPointer<char> ToCString(AllowNullsFlag allow_nulls,
   8754                                     RobustnessFlag robustness_flag,
   8755                                     int offset,
   8756                                     int length,
   8757                                     int* length_output = 0);
   8758   SmartArrayPointer<char> ToCString(
   8759       AllowNullsFlag allow_nulls = DISALLOW_NULLS,
   8760       RobustnessFlag robustness_flag = FAST_STRING_TRAVERSAL,
   8761       int* length_output = 0);
   8762 
   8763   // Return a 16 bit Unicode representation of the string.
   8764   // The string should be nearly flat, otherwise the performance of
   8765   // of this method may be very bad.  Setting robustness_flag to
   8766   // ROBUST_STRING_TRAVERSAL invokes behaviour that is robust  This means it
   8767   // handles unexpected data without causing assert failures and it does not
   8768   // do any heap allocations.  This is useful when printing stack traces.
   8769   SmartArrayPointer<uc16> ToWideCString(
   8770       RobustnessFlag robustness_flag = FAST_STRING_TRAVERSAL);
   8771 
   8772   bool ComputeArrayIndex(uint32_t* index);
   8773 
   8774   // Externalization.
   8775   bool MakeExternal(v8::String::ExternalStringResource* resource);
   8776   bool MakeExternal(v8::String::ExternalOneByteStringResource* resource);
   8777 
   8778   // Conversion.
   8779   inline bool AsArrayIndex(uint32_t* index);
   8780 
   8781   DECLARE_CAST(String)
   8782 
   8783   void PrintOn(FILE* out);
   8784 
   8785   // For use during stack traces.  Performs rudimentary sanity check.
   8786   bool LooksValid();
   8787 
   8788   // Dispatched behavior.
   8789   void StringShortPrint(StringStream* accumulator);
   8790   void PrintUC16(OStream& os, int start = 0, int end = -1);  // NOLINT
   8791 #ifdef OBJECT_PRINT
   8792   char* ToAsciiArray();
   8793 #endif
   8794   DECLARE_PRINTER(String)
   8795   DECLARE_VERIFIER(String)
   8796 
   8797   inline bool IsFlat();
   8798 
   8799   // Layout description.
   8800   static const int kLengthOffset = Name::kSize;
   8801   static const int kSize = kLengthOffset + kPointerSize;
   8802 
   8803   // Maximum number of characters to consider when trying to convert a string
   8804   // value into an array index.
   8805   static const int kMaxArrayIndexSize = 10;
   8806   STATIC_ASSERT(kMaxArrayIndexSize < (1 << kArrayIndexLengthBits));
   8807 
   8808   // Max char codes.
   8809   static const int32_t kMaxOneByteCharCode = unibrow::Latin1::kMaxChar;
   8810   static const uint32_t kMaxOneByteCharCodeU = unibrow::Latin1::kMaxChar;
   8811   static const int kMaxUtf16CodeUnit = 0xffff;
   8812   static const uint32_t kMaxUtf16CodeUnitU = kMaxUtf16CodeUnit;
   8813 
   8814   // Value of hash field containing computed hash equal to zero.
   8815   static const int kEmptyStringHash = kIsNotArrayIndexMask;
   8816 
   8817   // Maximal string length.
   8818   static const int kMaxLength = (1 << 28) - 16;
   8819 
   8820   // Max length for computing hash. For strings longer than this limit the
   8821   // string length is used as the hash value.
   8822   static const int kMaxHashCalcLength = 16383;
   8823 
   8824   // Limit for truncation in short printing.
   8825   static const int kMaxShortPrintLength = 1024;
   8826 
   8827   // Support for regular expressions.
   8828   const uc16* GetTwoByteData(unsigned start);
   8829 
   8830   // Helper function for flattening strings.
   8831   template <typename sinkchar>
   8832   static void WriteToFlat(String* source,
   8833                           sinkchar* sink,
   8834                           int from,
   8835                           int to);
   8836 
   8837   // The return value may point to the first aligned word containing the first
   8838   // non-one-byte character, rather than directly to the non-one-byte character.
   8839   // If the return value is >= the passed length, the entire string was
   8840   // one-byte.
   8841   static inline int NonAsciiStart(const char* chars, int length) {
   8842     const char* start = chars;
   8843     const char* limit = chars + length;
   8844 
   8845     if (length >= kIntptrSize) {
   8846       // Check unaligned bytes.
   8847       while (!IsAligned(reinterpret_cast<intptr_t>(chars), sizeof(uintptr_t))) {
   8848         if (static_cast<uint8_t>(*chars) > unibrow::Utf8::kMaxOneByteChar) {
   8849           return static_cast<int>(chars - start);
   8850         }
   8851         ++chars;
   8852       }
   8853       // Check aligned words.
   8854       DCHECK(unibrow::Utf8::kMaxOneByteChar == 0x7F);
   8855       const uintptr_t non_one_byte_mask = kUintptrAllBitsSet / 0xFF * 0x80;
   8856       while (chars + sizeof(uintptr_t) <= limit) {
   8857         if (*reinterpret_cast<const uintptr_t*>(chars) & non_one_byte_mask) {
   8858           return static_cast<int>(chars - start);
   8859         }
   8860         chars += sizeof(uintptr_t);
   8861       }
   8862     }
   8863     // Check remaining unaligned bytes.
   8864     while (chars < limit) {
   8865       if (static_cast<uint8_t>(*chars) > unibrow::Utf8::kMaxOneByteChar) {
   8866         return static_cast<int>(chars - start);
   8867       }
   8868       ++chars;
   8869     }
   8870 
   8871     return static_cast<int>(chars - start);
   8872   }
   8873 
   8874   static inline bool IsAscii(const char* chars, int length) {
   8875     return NonAsciiStart(chars, length) >= length;
   8876   }
   8877 
   8878   static inline bool IsAscii(const uint8_t* chars, int length) {
   8879     return
   8880         NonAsciiStart(reinterpret_cast<const char*>(chars), length) >= length;
   8881   }
   8882 
   8883   static inline int NonOneByteStart(const uc16* chars, int length) {
   8884     const uc16* limit = chars + length;
   8885     const uc16* start = chars;
   8886     while (chars < limit) {
   8887       if (*chars > kMaxOneByteCharCodeU) return static_cast<int>(chars - start);
   8888       ++chars;
   8889     }
   8890     return static_cast<int>(chars - start);
   8891   }
   8892 
   8893   static inline bool IsOneByte(const uc16* chars, int length) {
   8894     return NonOneByteStart(chars, length) >= length;
   8895   }
   8896 
   8897   template<class Visitor>
   8898   static inline ConsString* VisitFlat(Visitor* visitor,
   8899                                       String* string,
   8900                                       int offset = 0);
   8901 
   8902   static Handle<FixedArray> CalculateLineEnds(Handle<String> string,
   8903                                               bool include_ending_line);
   8904 
   8905   // Use the hash field to forward to the canonical internalized string
   8906   // when deserializing an internalized string.
   8907   inline void SetForwardedInternalizedString(String* string);
   8908   inline String* GetForwardedInternalizedString();
   8909 
   8910  private:
   8911   friend class Name;
   8912   friend class StringTableInsertionKey;
   8913 
   8914   static Handle<String> SlowFlatten(Handle<ConsString> cons,
   8915                                     PretenureFlag tenure);
   8916 
   8917   // Slow case of String::Equals.  This implementation works on any strings
   8918   // but it is most efficient on strings that are almost flat.
   8919   bool SlowEquals(String* other);
   8920 
   8921   static bool SlowEquals(Handle<String> one, Handle<String> two);
   8922 
   8923   // Slow case of AsArrayIndex.
   8924   bool SlowAsArrayIndex(uint32_t* index);
   8925 
   8926   // Compute and set the hash code.
   8927   uint32_t ComputeAndSetHash();
   8928 
   8929   DISALLOW_IMPLICIT_CONSTRUCTORS(String);
   8930 };
   8931 
   8932 
   8933 // The SeqString abstract class captures sequential string values.
   8934 class SeqString: public String {
   8935  public:
   8936   DECLARE_CAST(SeqString)
   8937 
   8938   // Layout description.
   8939   static const int kHeaderSize = String::kSize;
   8940 
   8941   // Truncate the string in-place if possible and return the result.
   8942   // In case of new_length == 0, the empty string is returned without
   8943   // truncating the original string.
   8944   MUST_USE_RESULT static Handle<String> Truncate(Handle<SeqString> string,
   8945                                                  int new_length);
   8946  private:
   8947   DISALLOW_IMPLICIT_CONSTRUCTORS(SeqString);
   8948 };
   8949 
   8950 
   8951 // The OneByteString class captures sequential one-byte string objects.
   8952 // Each character in the OneByteString is an one-byte character.
   8953 class SeqOneByteString: public SeqString {
   8954  public:
   8955   static const bool kHasOneByteEncoding = true;
   8956 
   8957   // Dispatched behavior.
   8958   inline uint16_t SeqOneByteStringGet(int index);
   8959   inline void SeqOneByteStringSet(int index, uint16_t value);
   8960 
   8961   // Get the address of the characters in this string.
   8962   inline Address GetCharsAddress();
   8963 
   8964   inline uint8_t* GetChars();
   8965 
   8966   DECLARE_CAST(SeqOneByteString)
   8967 
   8968   // Garbage collection support.  This method is called by the
   8969   // garbage collector to compute the actual size of an OneByteString
   8970   // instance.
   8971   inline int SeqOneByteStringSize(InstanceType instance_type);
   8972 
   8973   // Computes the size for an OneByteString instance of a given length.
   8974   static int SizeFor(int length) {
   8975     return OBJECT_POINTER_ALIGN(kHeaderSize + length * kCharSize);
   8976   }
   8977 
   8978   // Maximal memory usage for a single sequential one-byte string.
   8979   static const int kMaxSize = 512 * MB - 1;
   8980   STATIC_ASSERT((kMaxSize - kHeaderSize) >= String::kMaxLength);
   8981 
   8982  private:
   8983   DISALLOW_IMPLICIT_CONSTRUCTORS(SeqOneByteString);
   8984 };
   8985 
   8986 
   8987 // The TwoByteString class captures sequential unicode string objects.
   8988 // Each character in the TwoByteString is a two-byte uint16_t.
   8989 class SeqTwoByteString: public SeqString {
   8990  public:
   8991   static const bool kHasOneByteEncoding = false;
   8992 
   8993   // Dispatched behavior.
   8994   inline uint16_t SeqTwoByteStringGet(int index);
   8995   inline void SeqTwoByteStringSet(int index, uint16_t value);
   8996 
   8997   // Get the address of the characters in this string.
   8998   inline Address GetCharsAddress();
   8999 
   9000   inline uc16* GetChars();
   9001 
   9002   // For regexp code.
   9003   const uint16_t* SeqTwoByteStringGetData(unsigned start);
   9004 
   9005   DECLARE_CAST(SeqTwoByteString)
   9006 
   9007   // Garbage collection support.  This method is called by the
   9008   // garbage collector to compute the actual size of a TwoByteString
   9009   // instance.
   9010   inline int SeqTwoByteStringSize(InstanceType instance_type);
   9011 
   9012   // Computes the size for a TwoByteString instance of a given length.
   9013   static int SizeFor(int length) {
   9014     return OBJECT_POINTER_ALIGN(kHeaderSize + length * kShortSize);
   9015   }
   9016 
   9017   // Maximal memory usage for a single sequential two-byte string.
   9018   static const int kMaxSize = 512 * MB - 1;
   9019   STATIC_ASSERT(static_cast<int>((kMaxSize - kHeaderSize)/sizeof(uint16_t)) >=
   9020                String::kMaxLength);
   9021 
   9022  private:
   9023   DISALLOW_IMPLICIT_CONSTRUCTORS(SeqTwoByteString);
   9024 };
   9025 
   9026 
   9027 // The ConsString class describes string values built by using the
   9028 // addition operator on strings.  A ConsString is a pair where the
   9029 // first and second components are pointers to other string values.
   9030 // One or both components of a ConsString can be pointers to other
   9031 // ConsStrings, creating a binary tree of ConsStrings where the leaves
   9032 // are non-ConsString string values.  The string value represented by
   9033 // a ConsString can be obtained by concatenating the leaf string
   9034 // values in a left-to-right depth-first traversal of the tree.
   9035 class ConsString: public String {
   9036  public:
   9037   // First string of the cons cell.
   9038   inline String* first();
   9039   // Doesn't check that the result is a string, even in debug mode.  This is
   9040   // useful during GC where the mark bits confuse the checks.
   9041   inline Object* unchecked_first();
   9042   inline void set_first(String* first,
   9043                         WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
   9044 
   9045   // Second string of the cons cell.
   9046   inline String* second();
   9047   // Doesn't check that the result is a string, even in debug mode.  This is
   9048   // useful during GC where the mark bits confuse the checks.
   9049   inline Object* unchecked_second();
   9050   inline void set_second(String* second,
   9051                          WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
   9052 
   9053   // Dispatched behavior.
   9054   uint16_t ConsStringGet(int index);
   9055 
   9056   DECLARE_CAST(ConsString)
   9057 
   9058   // Layout description.
   9059   static const int kFirstOffset = POINTER_SIZE_ALIGN(String::kSize);
   9060   static const int kSecondOffset = kFirstOffset + kPointerSize;
   9061   static const int kSize = kSecondOffset + kPointerSize;
   9062 
   9063   // Minimum length for a cons string.
   9064   static const int kMinLength = 13;
   9065 
   9066   typedef FixedBodyDescriptor<kFirstOffset, kSecondOffset + kPointerSize, kSize>
   9067           BodyDescriptor;
   9068 
   9069   DECLARE_VERIFIER(ConsString)
   9070 
   9071  private:
   9072   DISALLOW_IMPLICIT_CONSTRUCTORS(ConsString);
   9073 };
   9074 
   9075 
   9076 // The Sliced String class describes strings that are substrings of another
   9077 // sequential string.  The motivation is to save time and memory when creating
   9078 // a substring.  A Sliced String is described as a pointer to the parent,
   9079 // the offset from the start of the parent string and the length.  Using
   9080 // a Sliced String therefore requires unpacking of the parent string and
   9081 // adding the offset to the start address.  A substring of a Sliced String
   9082 // are not nested since the double indirection is simplified when creating
   9083 // such a substring.
   9084 // Currently missing features are:
   9085 //  - handling externalized parent strings
   9086 //  - external strings as parent
   9087 //  - truncating sliced string to enable otherwise unneeded parent to be GC'ed.
   9088 class SlicedString: public String {
   9089  public:
   9090   inline String* parent();
   9091   inline void set_parent(String* parent,
   9092                          WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
   9093   inline int offset() const;
   9094   inline void set_offset(int offset);
   9095 
   9096   // Dispatched behavior.
   9097   uint16_t SlicedStringGet(int index);
   9098 
   9099   DECLARE_CAST(SlicedString)
   9100 
   9101   // Layout description.
   9102   static const int kParentOffset = POINTER_SIZE_ALIGN(String::kSize);
   9103   static const int kOffsetOffset = kParentOffset + kPointerSize;
   9104   static const int kSize = kOffsetOffset + kPointerSize;
   9105 
   9106   // Minimum length for a sliced string.
   9107   static const int kMinLength = 13;
   9108 
   9109   typedef FixedBodyDescriptor<kParentOffset,
   9110                               kOffsetOffset + kPointerSize, kSize>
   9111           BodyDescriptor;
   9112 
   9113   DECLARE_VERIFIER(SlicedString)
   9114 
   9115  private:
   9116   DISALLOW_IMPLICIT_CONSTRUCTORS(SlicedString);
   9117 };
   9118 
   9119 
   9120 // The ExternalString class describes string values that are backed by
   9121 // a string resource that lies outside the V8 heap.  ExternalStrings
   9122 // consist of the length field common to all strings, a pointer to the
   9123 // external resource.  It is important to ensure (externally) that the
   9124 // resource is not deallocated while the ExternalString is live in the
   9125 // V8 heap.
   9126 //
   9127 // The API expects that all ExternalStrings are created through the
   9128 // API.  Therefore, ExternalStrings should not be used internally.
   9129 class ExternalString: public String {
   9130  public:
   9131   DECLARE_CAST(ExternalString)
   9132 
   9133   // Layout description.
   9134   static const int kResourceOffset = POINTER_SIZE_ALIGN(String::kSize);
   9135   static const int kShortSize = kResourceOffset + kPointerSize;
   9136   static const int kResourceDataOffset = kResourceOffset + kPointerSize;
   9137   static const int kSize = kResourceDataOffset + kPointerSize;
   9138 
   9139   static const int kMaxShortLength =
   9140       (kShortSize - SeqString::kHeaderSize) / kCharSize;
   9141 
   9142   // Return whether external string is short (data pointer is not cached).
   9143   inline bool is_short();
   9144 
   9145   STATIC_ASSERT(kResourceOffset == Internals::kStringResourceOffset);
   9146 
   9147  private:
   9148   DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalString);
   9149 };
   9150 
   9151 
   9152 // The ExternalOneByteString class is an external string backed by an
   9153 // one-byte string.
   9154 class ExternalOneByteString : public ExternalString {
   9155  public:
   9156   static const bool kHasOneByteEncoding = true;
   9157 
   9158   typedef v8::String::ExternalOneByteStringResource Resource;
   9159 
   9160   // The underlying resource.
   9161   inline const Resource* resource();
   9162   inline void set_resource(const Resource* buffer);
   9163 
   9164   // Update the pointer cache to the external character array.
   9165   // The cached pointer is always valid, as the external character array does =
   9166   // not move during lifetime.  Deserialization is the only exception, after
   9167   // which the pointer cache has to be refreshed.
   9168   inline void update_data_cache();
   9169 
   9170   inline const uint8_t* GetChars();
   9171 
   9172   // Dispatched behavior.
   9173   inline uint16_t ExternalOneByteStringGet(int index);
   9174 
   9175   DECLARE_CAST(ExternalOneByteString)
   9176 
   9177   // Garbage collection support.
   9178   inline void ExternalOneByteStringIterateBody(ObjectVisitor* v);
   9179 
   9180   template <typename StaticVisitor>
   9181   inline void ExternalOneByteStringIterateBody();
   9182 
   9183  private:
   9184   DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalOneByteString);
   9185 };
   9186 
   9187 
   9188 // The ExternalTwoByteString class is an external string backed by a UTF-16
   9189 // encoded string.
   9190 class ExternalTwoByteString: public ExternalString {
   9191  public:
   9192   static const bool kHasOneByteEncoding = false;
   9193 
   9194   typedef v8::String::ExternalStringResource Resource;
   9195 
   9196   // The underlying string resource.
   9197   inline const Resource* resource();
   9198   inline void set_resource(const Resource* buffer);
   9199 
   9200   // Update the pointer cache to the external character array.
   9201   // The cached pointer is always valid, as the external character array does =
   9202   // not move during lifetime.  Deserialization is the only exception, after
   9203   // which the pointer cache has to be refreshed.
   9204   inline void update_data_cache();
   9205 
   9206   inline const uint16_t* GetChars();
   9207 
   9208   // Dispatched behavior.
   9209   inline uint16_t ExternalTwoByteStringGet(int index);
   9210 
   9211   // For regexp code.
   9212   inline const uint16_t* ExternalTwoByteStringGetData(unsigned start);
   9213 
   9214   DECLARE_CAST(ExternalTwoByteString)
   9215 
   9216   // Garbage collection support.
   9217   inline void ExternalTwoByteStringIterateBody(ObjectVisitor* v);
   9218 
   9219   template<typename StaticVisitor>
   9220   inline void ExternalTwoByteStringIterateBody();
   9221 
   9222  private:
   9223   DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalTwoByteString);
   9224 };
   9225 
   9226 
   9227 // Utility superclass for stack-allocated objects that must be updated
   9228 // on gc.  It provides two ways for the gc to update instances, either
   9229 // iterating or updating after gc.
   9230 class Relocatable BASE_EMBEDDED {
   9231  public:
   9232   explicit inline Relocatable(Isolate* isolate);
   9233   inline virtual ~Relocatable();
   9234   virtual void IterateInstance(ObjectVisitor* v) { }
   9235   virtual void PostGarbageCollection() { }
   9236 
   9237   static void PostGarbageCollectionProcessing(Isolate* isolate);
   9238   static int ArchiveSpacePerThread();
   9239   static char* ArchiveState(Isolate* isolate, char* to);
   9240   static char* RestoreState(Isolate* isolate, char* from);
   9241   static void Iterate(Isolate* isolate, ObjectVisitor* v);
   9242   static void Iterate(ObjectVisitor* v, Relocatable* top);
   9243   static char* Iterate(ObjectVisitor* v, char* t);
   9244 
   9245  private:
   9246   Isolate* isolate_;
   9247   Relocatable* prev_;
   9248 };
   9249 
   9250 
   9251 // A flat string reader provides random access to the contents of a
   9252 // string independent of the character width of the string.  The handle
   9253 // must be valid as long as the reader is being used.
   9254 class FlatStringReader : public Relocatable {
   9255  public:
   9256   FlatStringReader(Isolate* isolate, Handle<String> str);
   9257   FlatStringReader(Isolate* isolate, Vector<const char> input);
   9258   void PostGarbageCollection();
   9259   inline uc32 Get(int index);
   9260   int length() { return length_; }
   9261  private:
   9262   String** str_;
   9263   bool is_one_byte_;
   9264   int length_;
   9265   const void* start_;
   9266 };
   9267 
   9268 
   9269 // A ConsStringOp that returns null.
   9270 // Useful when the operation to apply on a ConsString
   9271 // requires an expensive data structure.
   9272 class ConsStringNullOp {
   9273  public:
   9274   inline ConsStringNullOp() {}
   9275   static inline String* Operate(String*, unsigned*, int32_t*, unsigned*);
   9276  private:
   9277   DISALLOW_COPY_AND_ASSIGN(ConsStringNullOp);
   9278 };
   9279 
   9280 
   9281 // This maintains an off-stack representation of the stack frames required
   9282 // to traverse a ConsString, allowing an entirely iterative and restartable
   9283 // traversal of the entire string
   9284 class ConsStringIteratorOp {
   9285  public:
   9286   inline ConsStringIteratorOp() {}
   9287   inline explicit ConsStringIteratorOp(ConsString* cons_string,
   9288                                        int offset = 0) {
   9289     Reset(cons_string, offset);
   9290   }
   9291   inline void Reset(ConsString* cons_string, int offset = 0) {
   9292     depth_ = 0;
   9293     // Next will always return NULL.
   9294     if (cons_string == NULL) return;
   9295     Initialize(cons_string, offset);
   9296   }
   9297   // Returns NULL when complete.
   9298   inline String* Next(int* offset_out) {
   9299     *offset_out = 0;
   9300     if (depth_ == 0) return NULL;
   9301     return Continue(offset_out);
   9302   }
   9303 
   9304  private:
   9305   static const int kStackSize = 32;
   9306   // Use a mask instead of doing modulo operations for stack wrapping.
   9307   static const int kDepthMask = kStackSize-1;
   9308   STATIC_ASSERT(IS_POWER_OF_TWO(kStackSize));
   9309   static inline int OffsetForDepth(int depth);
   9310 
   9311   inline void PushLeft(ConsString* string);
   9312   inline void PushRight(ConsString* string);
   9313   inline void AdjustMaximumDepth();
   9314   inline void Pop();
   9315   inline bool StackBlown() { return maximum_depth_ - depth_ == kStackSize; }
   9316   void Initialize(ConsString* cons_string, int offset);
   9317   String* Continue(int* offset_out);
   9318   String* NextLeaf(bool* blew_stack);
   9319   String* Search(int* offset_out);
   9320 
   9321   // Stack must always contain only frames for which right traversal
   9322   // has not yet been performed.
   9323   ConsString* frames_[kStackSize];
   9324   ConsString* root_;
   9325   int depth_;
   9326   int maximum_depth_;
   9327   int consumed_;
   9328   DISALLOW_COPY_AND_ASSIGN(ConsStringIteratorOp);
   9329 };
   9330 
   9331 
   9332 class StringCharacterStream {
   9333  public:
   9334   inline StringCharacterStream(String* string,
   9335                                ConsStringIteratorOp* op,
   9336                                int offset = 0);
   9337   inline uint16_t GetNext();
   9338   inline bool HasMore();
   9339   inline void Reset(String* string, int offset = 0);
   9340   inline void VisitOneByteString(const uint8_t* chars, int length);
   9341   inline void VisitTwoByteString(const uint16_t* chars, int length);
   9342 
   9343  private:
   9344   bool is_one_byte_;
   9345   union {
   9346     const uint8_t* buffer8_;
   9347     const uint16_t* buffer16_;
   9348   };
   9349   const uint8_t* end_;
   9350   ConsStringIteratorOp* op_;
   9351   DISALLOW_COPY_AND_ASSIGN(StringCharacterStream);
   9352 };
   9353 
   9354 
   9355 template <typename T>
   9356 class VectorIterator {
   9357  public:
   9358   VectorIterator(T* d, int l) : data_(Vector<const T>(d, l)), index_(0) { }
   9359   explicit VectorIterator(Vector<const T> data) : data_(data), index_(0) { }
   9360   T GetNext() { return data_[index_++]; }
   9361   bool has_more() { return index_ < data_.length(); }
   9362  private:
   9363   Vector<const T> data_;
   9364   int index_;
   9365 };
   9366 
   9367 
   9368 // The Oddball describes objects null, undefined, true, and false.
   9369 class Oddball: public HeapObject {
   9370  public:
   9371   // [to_string]: Cached to_string computed at startup.
   9372   DECL_ACCESSORS(to_string, String)
   9373 
   9374   // [to_number]: Cached to_number computed at startup.
   9375   DECL_ACCESSORS(to_number, Object)
   9376 
   9377   inline byte kind() const;
   9378   inline void set_kind(byte kind);
   9379 
   9380   DECLARE_CAST(Oddball)
   9381 
   9382   // Dispatched behavior.
   9383   DECLARE_VERIFIER(Oddball)
   9384 
   9385   // Initialize the fields.
   9386   static void Initialize(Isolate* isolate,
   9387                          Handle<Oddball> oddball,
   9388                          const char* to_string,
   9389                          Handle<Object> to_number,
   9390                          byte kind);
   9391 
   9392   // Layout description.
   9393   static const int kToStringOffset = HeapObject::kHeaderSize;
   9394   static const int kToNumberOffset = kToStringOffset + kPointerSize;
   9395   static const int kKindOffset = kToNumberOffset + kPointerSize;
   9396   static const int kSize = kKindOffset + kPointerSize;
   9397 
   9398   static const byte kFalse = 0;
   9399   static const byte kTrue = 1;
   9400   static const byte kNotBooleanMask = ~1;
   9401   static const byte kTheHole = 2;
   9402   static const byte kNull = 3;
   9403   static const byte kArgumentMarker = 4;
   9404   static const byte kUndefined = 5;
   9405   static const byte kUninitialized = 6;
   9406   static const byte kOther = 7;
   9407   static const byte kException = 8;
   9408 
   9409   typedef FixedBodyDescriptor<kToStringOffset,
   9410                               kToNumberOffset + kPointerSize,
   9411                               kSize> BodyDescriptor;
   9412 
   9413   STATIC_ASSERT(kKindOffset == Internals::kOddballKindOffset);
   9414   STATIC_ASSERT(kNull == Internals::kNullOddballKind);
   9415   STATIC_ASSERT(kUndefined == Internals::kUndefinedOddballKind);
   9416 
   9417  private:
   9418   DISALLOW_IMPLICIT_CONSTRUCTORS(Oddball);
   9419 };
   9420 
   9421 
   9422 class Cell: public HeapObject {
   9423  public:
   9424   // [value]: value of the global property.
   9425   DECL_ACCESSORS(value, Object)
   9426 
   9427   DECLARE_CAST(Cell)
   9428 
   9429   static inline Cell* FromValueAddress(Address value) {
   9430     Object* result = FromAddress(value - kValueOffset);
   9431     DCHECK(result->IsCell() || result->IsPropertyCell());
   9432     return static_cast<Cell*>(result);
   9433   }
   9434 
   9435   inline Address ValueAddress() {
   9436     return address() + kValueOffset;
   9437   }
   9438 
   9439   // Dispatched behavior.
   9440   DECLARE_PRINTER(Cell)
   9441   DECLARE_VERIFIER(Cell)
   9442 
   9443   // Layout description.
   9444   static const int kValueOffset = HeapObject::kHeaderSize;
   9445   static const int kSize = kValueOffset + kPointerSize;
   9446 
   9447   typedef FixedBodyDescriptor<kValueOffset,
   9448                               kValueOffset + kPointerSize,
   9449                               kSize> BodyDescriptor;
   9450 
   9451  private:
   9452   DISALLOW_IMPLICIT_CONSTRUCTORS(Cell);
   9453 };
   9454 
   9455 
   9456 class PropertyCell: public Cell {
   9457  public:
   9458   // [type]: type of the global property.
   9459   HeapType* type();
   9460   void set_type(HeapType* value, WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
   9461 
   9462   // [dependent_code]: dependent code that depends on the type of the global
   9463   // property.
   9464   DECL_ACCESSORS(dependent_code, DependentCode)
   9465 
   9466   // Sets the value of the cell and updates the type field to be the union
   9467   // of the cell's current type and the value's type. If the change causes
   9468   // a change of the type of the cell's contents, code dependent on the cell
   9469   // will be deoptimized.
   9470   static void SetValueInferType(Handle<PropertyCell> cell,
   9471                                 Handle<Object> value);
   9472 
   9473   // Computes the new type of the cell's contents for the given value, but
   9474   // without actually modifying the 'type' field.
   9475   static Handle<HeapType> UpdatedType(Handle<PropertyCell> cell,
   9476                                       Handle<Object> value);
   9477 
   9478   static void AddDependentCompilationInfo(Handle<PropertyCell> cell,
   9479                                           CompilationInfo* info);
   9480 
   9481   DECLARE_CAST(PropertyCell)
   9482 
   9483   inline Address TypeAddress() {
   9484     return address() + kTypeOffset;
   9485   }
   9486 
   9487   // Dispatched behavior.
   9488   DECLARE_PRINTER(PropertyCell)
   9489   DECLARE_VERIFIER(PropertyCell)
   9490 
   9491   // Layout description.
   9492   static const int kTypeOffset = kValueOffset + kPointerSize;
   9493   static const int kDependentCodeOffset = kTypeOffset + kPointerSize;
   9494   static const int kSize = kDependentCodeOffset + kPointerSize;
   9495 
   9496   static const int kPointerFieldsBeginOffset = kValueOffset;
   9497   static const int kPointerFieldsEndOffset = kDependentCodeOffset;
   9498 
   9499   typedef FixedBodyDescriptor<kValueOffset,
   9500                               kSize,
   9501                               kSize> BodyDescriptor;
   9502 
   9503  private:
   9504   DECL_ACCESSORS(type_raw, Object)
   9505   DISALLOW_IMPLICIT_CONSTRUCTORS(PropertyCell);
   9506 };
   9507 
   9508 
   9509 // The JSProxy describes EcmaScript Harmony proxies
   9510 class JSProxy: public JSReceiver {
   9511  public:
   9512   // [handler]: The handler property.
   9513   DECL_ACCESSORS(handler, Object)
   9514 
   9515   // [hash]: The hash code property (undefined if not initialized yet).
   9516   DECL_ACCESSORS(hash, Object)
   9517 
   9518   DECLARE_CAST(JSProxy)
   9519 
   9520   MUST_USE_RESULT static MaybeHandle<Object> GetPropertyWithHandler(
   9521       Handle<JSProxy> proxy,
   9522       Handle<Object> receiver,
   9523       Handle<Name> name);
   9524   MUST_USE_RESULT static inline MaybeHandle<Object> GetElementWithHandler(
   9525       Handle<JSProxy> proxy,
   9526       Handle<Object> receiver,
   9527       uint32_t index);
   9528 
   9529   // If the handler defines an accessor property with a setter, invoke it.
   9530   // If it defines an accessor property without a setter, or a data property
   9531   // that is read-only, throw. In all these cases set '*done' to true,
   9532   // otherwise set it to false.
   9533   MUST_USE_RESULT
   9534   static MaybeHandle<Object> SetPropertyViaPrototypesWithHandler(
   9535       Handle<JSProxy> proxy, Handle<Object> receiver, Handle<Name> name,
   9536       Handle<Object> value, StrictMode strict_mode, bool* done);
   9537 
   9538   MUST_USE_RESULT static Maybe<PropertyAttributes>
   9539       GetPropertyAttributesWithHandler(Handle<JSProxy> proxy,
   9540                                        Handle<Object> receiver,
   9541                                        Handle<Name> name);
   9542   MUST_USE_RESULT static Maybe<PropertyAttributes>
   9543       GetElementAttributeWithHandler(Handle<JSProxy> proxy,
   9544                                      Handle<JSReceiver> receiver,
   9545                                      uint32_t index);
   9546   MUST_USE_RESULT static MaybeHandle<Object> SetPropertyWithHandler(
   9547       Handle<JSProxy> proxy, Handle<Object> receiver, Handle<Name> name,
   9548       Handle<Object> value, StrictMode strict_mode);
   9549 
   9550   // Turn the proxy into an (empty) JSObject.
   9551   static void Fix(Handle<JSProxy> proxy);
   9552 
   9553   // Initializes the body after the handler slot.
   9554   inline void InitializeBody(int object_size, Object* value);
   9555 
   9556   // Invoke a trap by name. If the trap does not exist on this's handler,
   9557   // but derived_trap is non-NULL, invoke that instead.  May cause GC.
   9558   MUST_USE_RESULT static MaybeHandle<Object> CallTrap(
   9559       Handle<JSProxy> proxy,
   9560       const char* name,
   9561       Handle<Object> derived_trap,
   9562       int argc,
   9563       Handle<Object> args[]);
   9564 
   9565   // Dispatched behavior.
   9566   DECLARE_PRINTER(JSProxy)
   9567   DECLARE_VERIFIER(JSProxy)
   9568 
   9569   // Layout description. We add padding so that a proxy has the same
   9570   // size as a virgin JSObject. This is essential for becoming a JSObject
   9571   // upon freeze.
   9572   static const int kHandlerOffset = HeapObject::kHeaderSize;
   9573   static const int kHashOffset = kHandlerOffset + kPointerSize;
   9574   static const int kPaddingOffset = kHashOffset + kPointerSize;
   9575   static const int kSize = JSObject::kHeaderSize;
   9576   static const int kHeaderSize = kPaddingOffset;
   9577   static const int kPaddingSize = kSize - kPaddingOffset;
   9578 
   9579   STATIC_ASSERT(kPaddingSize >= 0);
   9580 
   9581   typedef FixedBodyDescriptor<kHandlerOffset,
   9582                               kPaddingOffset,
   9583                               kSize> BodyDescriptor;
   9584 
   9585  private:
   9586   friend class JSReceiver;
   9587 
   9588   MUST_USE_RESULT static inline MaybeHandle<Object> SetElementWithHandler(
   9589       Handle<JSProxy> proxy,
   9590       Handle<JSReceiver> receiver,
   9591       uint32_t index,
   9592       Handle<Object> value,
   9593       StrictMode strict_mode);
   9594 
   9595   MUST_USE_RESULT static Maybe<bool> HasPropertyWithHandler(
   9596       Handle<JSProxy> proxy, Handle<Name> name);
   9597   MUST_USE_RESULT static inline Maybe<bool> HasElementWithHandler(
   9598       Handle<JSProxy> proxy, uint32_t index);
   9599 
   9600   MUST_USE_RESULT static MaybeHandle<Object> DeletePropertyWithHandler(
   9601       Handle<JSProxy> proxy,
   9602       Handle<Name> name,
   9603       DeleteMode mode);
   9604   MUST_USE_RESULT static MaybeHandle<Object> DeleteElementWithHandler(
   9605       Handle<JSProxy> proxy,
   9606       uint32_t index,
   9607       DeleteMode mode);
   9608 
   9609   MUST_USE_RESULT Object* GetIdentityHash();
   9610 
   9611   static Handle<Smi> GetOrCreateIdentityHash(Handle<JSProxy> proxy);
   9612 
   9613   DISALLOW_IMPLICIT_CONSTRUCTORS(JSProxy);
   9614 };
   9615 
   9616 
   9617 class JSFunctionProxy: public JSProxy {
   9618  public:
   9619   // [call_trap]: The call trap.
   9620   DECL_ACCESSORS(call_trap, Object)
   9621 
   9622   // [construct_trap]: The construct trap.
   9623   DECL_ACCESSORS(construct_trap, Object)
   9624 
   9625   DECLARE_CAST(JSFunctionProxy)
   9626 
   9627   // Dispatched behavior.
   9628   DECLARE_PRINTER(JSFunctionProxy)
   9629   DECLARE_VERIFIER(JSFunctionProxy)
   9630 
   9631   // Layout description.
   9632   static const int kCallTrapOffset = JSProxy::kPaddingOffset;
   9633   static const int kConstructTrapOffset = kCallTrapOffset + kPointerSize;
   9634   static const int kPaddingOffset = kConstructTrapOffset + kPointerSize;
   9635   static const int kSize = JSFunction::kSize;
   9636   static const int kPaddingSize = kSize - kPaddingOffset;
   9637 
   9638   STATIC_ASSERT(kPaddingSize >= 0);
   9639 
   9640   typedef FixedBodyDescriptor<kHandlerOffset,
   9641                               kConstructTrapOffset + kPointerSize,
   9642                               kSize> BodyDescriptor;
   9643 
   9644  private:
   9645   DISALLOW_IMPLICIT_CONSTRUCTORS(JSFunctionProxy);
   9646 };
   9647 
   9648 
   9649 class JSCollection : public JSObject {
   9650  public:
   9651   // [table]: the backing hash table
   9652   DECL_ACCESSORS(table, Object)
   9653 
   9654   static const int kTableOffset = JSObject::kHeaderSize;
   9655   static const int kSize = kTableOffset + kPointerSize;
   9656 
   9657  private:
   9658   DISALLOW_IMPLICIT_CONSTRUCTORS(JSCollection);
   9659 };
   9660 
   9661 
   9662 // The JSSet describes EcmaScript Harmony sets
   9663 class JSSet : public JSCollection {
   9664  public:
   9665   DECLARE_CAST(JSSet)
   9666 
   9667   // Dispatched behavior.
   9668   DECLARE_PRINTER(JSSet)
   9669   DECLARE_VERIFIER(JSSet)
   9670 
   9671  private:
   9672   DISALLOW_IMPLICIT_CONSTRUCTORS(JSSet);
   9673 };
   9674 
   9675 
   9676 // The JSMap describes EcmaScript Harmony maps
   9677 class JSMap : public JSCollection {
   9678  public:
   9679   DECLARE_CAST(JSMap)
   9680 
   9681   // Dispatched behavior.
   9682   DECLARE_PRINTER(JSMap)
   9683   DECLARE_VERIFIER(JSMap)
   9684 
   9685  private:
   9686   DISALLOW_IMPLICIT_CONSTRUCTORS(JSMap);
   9687 };
   9688 
   9689 
   9690 // OrderedHashTableIterator is an iterator that iterates over the keys and
   9691 // values of an OrderedHashTable.
   9692 //
   9693 // The iterator has a reference to the underlying OrderedHashTable data,
   9694 // [table], as well as the current [index] the iterator is at.
   9695 //
   9696 // When the OrderedHashTable is rehashed it adds a reference from the old table
   9697 // to the new table as well as storing enough data about the changes so that the
   9698 // iterator [index] can be adjusted accordingly.
   9699 //
   9700 // When the [Next] result from the iterator is requested, the iterator checks if
   9701 // there is a newer table that it needs to transition to.
   9702 template<class Derived, class TableType>
   9703 class OrderedHashTableIterator: public JSObject {
   9704  public:
   9705   // [table]: the backing hash table mapping keys to values.
   9706   DECL_ACCESSORS(table, Object)
   9707 
   9708   // [index]: The index into the data table.
   9709   DECL_ACCESSORS(index, Object)
   9710 
   9711   // [kind]: The kind of iteration this is. One of the [Kind] enum values.
   9712   DECL_ACCESSORS(kind, Object)
   9713 
   9714 #ifdef OBJECT_PRINT
   9715   void OrderedHashTableIteratorPrint(OStream& os);  // NOLINT
   9716 #endif
   9717 
   9718   static const int kTableOffset = JSObject::kHeaderSize;
   9719   static const int kIndexOffset = kTableOffset + kPointerSize;
   9720   static const int kKindOffset = kIndexOffset + kPointerSize;
   9721   static const int kSize = kKindOffset + kPointerSize;
   9722 
   9723   enum Kind {
   9724     kKindKeys = 1,
   9725     kKindValues = 2,
   9726     kKindEntries = 3
   9727   };
   9728 
   9729   // Whether the iterator has more elements. This needs to be called before
   9730   // calling |CurrentKey| and/or |CurrentValue|.
   9731   bool HasMore();
   9732 
   9733   // Move the index forward one.
   9734   void MoveNext() {
   9735     set_index(Smi::FromInt(Smi::cast(index())->value() + 1));
   9736   }
   9737 
   9738   // Populates the array with the next key and value and then moves the iterator
   9739   // forward.
   9740   // This returns the |kind| or 0 if the iterator is already at the end.
   9741   Smi* Next(JSArray* value_array);
   9742 
   9743   // Returns the current key of the iterator. This should only be called when
   9744   // |HasMore| returns true.
   9745   inline Object* CurrentKey();
   9746 
   9747  private:
   9748   // Transitions the iterator to the non obsolete backing store. This is a NOP
   9749   // if the [table] is not obsolete.
   9750   void Transition();
   9751 
   9752   DISALLOW_IMPLICIT_CONSTRUCTORS(OrderedHashTableIterator);
   9753 };
   9754 
   9755 
   9756 class JSSetIterator: public OrderedHashTableIterator<JSSetIterator,
   9757                                                      OrderedHashSet> {
   9758  public:
   9759   // Dispatched behavior.
   9760   DECLARE_PRINTER(JSSetIterator)
   9761   DECLARE_VERIFIER(JSSetIterator)
   9762 
   9763   DECLARE_CAST(JSSetIterator)
   9764 
   9765   // Called by |Next| to populate the array. This allows the subclasses to
   9766   // populate the array differently.
   9767   inline void PopulateValueArray(FixedArray* array);
   9768 
   9769  private:
   9770   DISALLOW_IMPLICIT_CONSTRUCTORS(JSSetIterator);
   9771 };
   9772 
   9773 
   9774 class JSMapIterator: public OrderedHashTableIterator<JSMapIterator,
   9775                                                      OrderedHashMap> {
   9776  public:
   9777   // Dispatched behavior.
   9778   DECLARE_PRINTER(JSMapIterator)
   9779   DECLARE_VERIFIER(JSMapIterator)
   9780 
   9781   DECLARE_CAST(JSMapIterator)
   9782 
   9783   // Called by |Next| to populate the array. This allows the subclasses to
   9784   // populate the array differently.
   9785   inline void PopulateValueArray(FixedArray* array);
   9786 
   9787  private:
   9788   // Returns the current value of the iterator. This should only be called when
   9789   // |HasMore| returns true.
   9790   inline Object* CurrentValue();
   9791 
   9792   DISALLOW_IMPLICIT_CONSTRUCTORS(JSMapIterator);
   9793 };
   9794 
   9795 
   9796 // Base class for both JSWeakMap and JSWeakSet
   9797 class JSWeakCollection: public JSObject {
   9798  public:
   9799   // [table]: the backing hash table mapping keys to values.
   9800   DECL_ACCESSORS(table, Object)
   9801 
   9802   // [next]: linked list of encountered weak maps during GC.
   9803   DECL_ACCESSORS(next, Object)
   9804 
   9805   static const int kTableOffset = JSObject::kHeaderSize;
   9806   static const int kNextOffset = kTableOffset + kPointerSize;
   9807   static const int kSize = kNextOffset + kPointerSize;
   9808 
   9809  private:
   9810   DISALLOW_IMPLICIT_CONSTRUCTORS(JSWeakCollection);
   9811 };
   9812 
   9813 
   9814 // The JSWeakMap describes EcmaScript Harmony weak maps
   9815 class JSWeakMap: public JSWeakCollection {
   9816  public:
   9817   DECLARE_CAST(JSWeakMap)
   9818 
   9819   // Dispatched behavior.
   9820   DECLARE_PRINTER(JSWeakMap)
   9821   DECLARE_VERIFIER(JSWeakMap)
   9822 
   9823  private:
   9824   DISALLOW_IMPLICIT_CONSTRUCTORS(JSWeakMap);
   9825 };
   9826 
   9827 
   9828 // The JSWeakSet describes EcmaScript Harmony weak sets
   9829 class JSWeakSet: public JSWeakCollection {
   9830  public:
   9831   DECLARE_CAST(JSWeakSet)
   9832 
   9833   // Dispatched behavior.
   9834   DECLARE_PRINTER(JSWeakSet)
   9835   DECLARE_VERIFIER(JSWeakSet)
   9836 
   9837  private:
   9838   DISALLOW_IMPLICIT_CONSTRUCTORS(JSWeakSet);
   9839 };
   9840 
   9841 
   9842 class JSArrayBuffer: public JSObject {
   9843  public:
   9844   // [backing_store]: backing memory for this array
   9845   DECL_ACCESSORS(backing_store, void)
   9846 
   9847   // [byte_length]: length in bytes
   9848   DECL_ACCESSORS(byte_length, Object)
   9849 
   9850   // [flags]
   9851   DECL_ACCESSORS(flag, Smi)
   9852 
   9853   inline bool is_external();
   9854   inline void set_is_external(bool value);
   9855 
   9856   inline bool should_be_freed();
   9857   inline void set_should_be_freed(bool value);
   9858 
   9859   // [weak_next]: linked list of array buffers.
   9860   DECL_ACCESSORS(weak_next, Object)
   9861 
   9862   // [weak_first_array]: weak linked list of views.
   9863   DECL_ACCESSORS(weak_first_view, Object)
   9864 
   9865   DECLARE_CAST(JSArrayBuffer)
   9866 
   9867   // Neutering. Only neuters the buffer, not associated typed arrays.
   9868   void Neuter();
   9869 
   9870   // Dispatched behavior.
   9871   DECLARE_PRINTER(JSArrayBuffer)
   9872   DECLARE_VERIFIER(JSArrayBuffer)
   9873 
   9874   static const int kBackingStoreOffset = JSObject::kHeaderSize;
   9875   static const int kByteLengthOffset = kBackingStoreOffset + kPointerSize;
   9876   static const int kFlagOffset = kByteLengthOffset + kPointerSize;
   9877   static const int kWeakNextOffset = kFlagOffset + kPointerSize;
   9878   static const int kWeakFirstViewOffset = kWeakNextOffset + kPointerSize;
   9879   static const int kSize = kWeakFirstViewOffset + kPointerSize;
   9880 
   9881   static const int kSizeWithInternalFields =
   9882       kSize + v8::ArrayBuffer::kInternalFieldCount * kPointerSize;
   9883 
   9884  private:
   9885   // Bit position in a flag
   9886   static const int kIsExternalBit = 0;
   9887   static const int kShouldBeFreed = 1;
   9888 
   9889   DISALLOW_IMPLICIT_CONSTRUCTORS(JSArrayBuffer);
   9890 };
   9891 
   9892 
   9893 class JSArrayBufferView: public JSObject {
   9894  public:
   9895   // [buffer]: ArrayBuffer that this typed array views.
   9896   DECL_ACCESSORS(buffer, Object)
   9897 
   9898   // [byte_length]: offset of typed array in bytes.
   9899   DECL_ACCESSORS(byte_offset, Object)
   9900 
   9901   // [byte_length]: length of typed array in bytes.
   9902   DECL_ACCESSORS(byte_length, Object)
   9903 
   9904   // [weak_next]: linked list of typed arrays over the same array buffer.
   9905   DECL_ACCESSORS(weak_next, Object)
   9906 
   9907   DECLARE_CAST(JSArrayBufferView)
   9908 
   9909   DECLARE_VERIFIER(JSArrayBufferView)
   9910 
   9911   static const int kBufferOffset = JSObject::kHeaderSize;
   9912   static const int kByteOffsetOffset = kBufferOffset + kPointerSize;
   9913   static const int kByteLengthOffset = kByteOffsetOffset + kPointerSize;
   9914   static const int kWeakNextOffset = kByteLengthOffset + kPointerSize;
   9915   static const int kViewSize = kWeakNextOffset + kPointerSize;
   9916 
   9917  protected:
   9918   void NeuterView();
   9919 
   9920  private:
   9921   DISALLOW_IMPLICIT_CONSTRUCTORS(JSArrayBufferView);
   9922 };
   9923 
   9924 
   9925 class JSTypedArray: public JSArrayBufferView {
   9926  public:
   9927   // [length]: length of typed array in elements.
   9928   DECL_ACCESSORS(length, Object)
   9929 
   9930   // Neutering. Only neuters this typed array.
   9931   void Neuter();
   9932 
   9933   DECLARE_CAST(JSTypedArray)
   9934 
   9935   ExternalArrayType type();
   9936   size_t element_size();
   9937 
   9938   Handle<JSArrayBuffer> GetBuffer();
   9939 
   9940   // Dispatched behavior.
   9941   DECLARE_PRINTER(JSTypedArray)
   9942   DECLARE_VERIFIER(JSTypedArray)
   9943 
   9944   static const int kLengthOffset = kViewSize + kPointerSize;
   9945   static const int kSize = kLengthOffset + kPointerSize;
   9946 
   9947   static const int kSizeWithInternalFields =
   9948       kSize + v8::ArrayBufferView::kInternalFieldCount * kPointerSize;
   9949 
   9950  private:
   9951   static Handle<JSArrayBuffer> MaterializeArrayBuffer(
   9952       Handle<JSTypedArray> typed_array);
   9953 
   9954   DISALLOW_IMPLICIT_CONSTRUCTORS(JSTypedArray);
   9955 };
   9956 
   9957 
   9958 class JSDataView: public JSArrayBufferView {
   9959  public:
   9960   // Only neuters this DataView
   9961   void Neuter();
   9962 
   9963   DECLARE_CAST(JSDataView)
   9964 
   9965   // Dispatched behavior.
   9966   DECLARE_PRINTER(JSDataView)
   9967   DECLARE_VERIFIER(JSDataView)
   9968 
   9969   static const int kSize = kViewSize;
   9970 
   9971   static const int kSizeWithInternalFields =
   9972       kSize + v8::ArrayBufferView::kInternalFieldCount * kPointerSize;
   9973 
   9974  private:
   9975   DISALLOW_IMPLICIT_CONSTRUCTORS(JSDataView);
   9976 };
   9977 
   9978 
   9979 // Foreign describes objects pointing from JavaScript to C structures.
   9980 // Since they cannot contain references to JS HeapObjects they can be
   9981 // placed in old_data_space.
   9982 class Foreign: public HeapObject {
   9983  public:
   9984   // [address]: field containing the address.
   9985   inline Address foreign_address();
   9986   inline void set_foreign_address(Address value);
   9987 
   9988   DECLARE_CAST(Foreign)
   9989 
   9990   // Dispatched behavior.
   9991   inline void ForeignIterateBody(ObjectVisitor* v);
   9992 
   9993   template<typename StaticVisitor>
   9994   inline void ForeignIterateBody();
   9995 
   9996   // Dispatched behavior.
   9997   DECLARE_PRINTER(Foreign)
   9998   DECLARE_VERIFIER(Foreign)
   9999 
   10000   // Layout description.
   10001 
   10002   static const int kForeignAddressOffset = HeapObject::kHeaderSize;
   10003   static const int kSize = kForeignAddressOffset + kPointerSize;
   10004 
   10005   STATIC_ASSERT(kForeignAddressOffset == Internals::kForeignAddressOffset);
   10006 
   10007  private:
   10008   DISALLOW_IMPLICIT_CONSTRUCTORS(Foreign);
   10009 };
   10010 
   10011 
   10012 // The JSArray describes JavaScript Arrays
   10013 //  Such an array can be in one of two modes:
   10014 //    - fast, backing storage is a FixedArray and length <= elements.length();
   10015 //       Please note: push and pop can be used to grow and shrink the array.
   10016 //    - slow, backing storage is a HashTable with numbers as keys.
   10017 class JSArray: public JSObject {
   10018  public:
   10019   // [length]: The length property.
   10020   DECL_ACCESSORS(length, Object)
   10021 
   10022   // Overload the length setter to skip write barrier when the length
   10023   // is set to a smi. This matches the set function on FixedArray.
   10024   inline void set_length(Smi* length);
   10025 
   10026   static void JSArrayUpdateLengthFromIndex(Handle<JSArray> array,
   10027                                            uint32_t index,
   10028                                            Handle<Object> value);
   10029 
   10030   static bool IsReadOnlyLengthDescriptor(Handle<Map> jsarray_map);
   10031   static bool WouldChangeReadOnlyLength(Handle<JSArray> array, uint32_t index);
   10032   static MaybeHandle<Object> ReadOnlyLengthError(Handle<JSArray> array);
   10033 
   10034   // Initialize the array with the given capacity. The function may
   10035   // fail due to out-of-memory situations, but only if the requested
   10036   // capacity is non-zero.
   10037   static void Initialize(Handle<JSArray> array, int capacity, int length = 0);
   10038 
   10039   // Initializes the array to a certain length.
   10040   inline bool AllowsSetElementsLength();
   10041   // Can cause GC.
   10042   MUST_USE_RESULT static MaybeHandle<Object> SetElementsLength(
   10043       Handle<JSArray> array,
   10044       Handle<Object> length);
   10045 
   10046   // Set the content of the array to the content of storage.
   10047   static inline void SetContent(Handle<JSArray> array,
   10048                                 Handle<FixedArrayBase> storage);
   10049 
   10050   DECLARE_CAST(JSArray)
   10051 
   10052   // Ensures that the fixed array backing the JSArray has at
   10053   // least the stated size.
   10054   static inline void EnsureSize(Handle<JSArray> array,
   10055                                 int minimum_size_of_backing_fixed_array);
   10056 
   10057   // Expand the fixed array backing of a fast-case JSArray to at least
   10058   // the requested size.
   10059   static void Expand(Handle<JSArray> array,
   10060                      int minimum_size_of_backing_fixed_array);
   10061 
   10062   // Dispatched behavior.
   10063   DECLARE_PRINTER(JSArray)
   10064   DECLARE_VERIFIER(JSArray)
   10065 
   10066   // Number of element slots to pre-allocate for an empty array.
   10067   static const int kPreallocatedArrayElements = 4;
   10068 
   10069   // Layout description.
   10070   static const int kLengthOffset = JSObject::kHeaderSize;
   10071   static const int kSize = kLengthOffset + kPointerSize;
   10072 
   10073  private:
   10074   DISALLOW_IMPLICIT_CONSTRUCTORS(JSArray);
   10075 };
   10076 
   10077 
   10078 Handle<Object> CacheInitialJSArrayMaps(Handle<Context> native_context,
   10079                                        Handle<Map> initial_map);
   10080 
   10081 
   10082 // JSRegExpResult is just a JSArray with a specific initial map.
   10083 // This initial map adds in-object properties for "index" and "input"
   10084 // properties, as assigned by RegExp.prototype.exec, which allows
   10085 // faster creation of RegExp exec results.
   10086 // This class just holds constants used when creating the result.
   10087 // After creation the result must be treated as a JSArray in all regards.
   10088 class JSRegExpResult: public JSArray {
   10089  public:
   10090   // Offsets of object fields.
   10091   static const int kIndexOffset = JSArray::kSize;
   10092   static const int kInputOffset = kIndexOffset + kPointerSize;
   10093   static const int kSize = kInputOffset + kPointerSize;
   10094   // Indices of in-object properties.
   10095   static const int kIndexIndex = 0;
   10096   static const int kInputIndex = 1;
   10097  private:
   10098   DISALLOW_IMPLICIT_CONSTRUCTORS(JSRegExpResult);
   10099 };
   10100 
   10101 
   10102 class AccessorInfo: public Struct {
   10103  public:
   10104   DECL_ACCESSORS(name, Object)
   10105   DECL_ACCESSORS(flag, Smi)
   10106   DECL_ACCESSORS(expected_receiver_type, Object)
   10107 
   10108   inline bool all_can_read();
   10109   inline void set_all_can_read(bool value);
   10110 
   10111   inline bool all_can_write();
   10112   inline void set_all_can_write(bool value);
   10113 
   10114   inline PropertyAttributes property_attributes();
   10115   inline void set_property_attributes(PropertyAttributes attributes);
   10116 
   10117   // Checks whether the given receiver is compatible with this accessor.
   10118   static bool IsCompatibleReceiverType(Isolate* isolate,
   10119                                        Handle<AccessorInfo> info,
   10120                                        Handle<HeapType> type);
   10121   inline bool IsCompatibleReceiver(Object* receiver);
   10122 
   10123   DECLARE_CAST(AccessorInfo)
   10124 
   10125   // Dispatched behavior.
   10126   DECLARE_VERIFIER(AccessorInfo)
   10127 
   10128   // Append all descriptors to the array that are not already there.
   10129   // Return number added.
   10130   static int AppendUnique(Handle<Object> descriptors,
   10131                           Handle<FixedArray> array,
   10132                           int valid_descriptors);
   10133 
   10134   static const int kNameOffset = HeapObject::kHeaderSize;
   10135   static const int kFlagOffset = kNameOffset + kPointerSize;
   10136   static const int kExpectedReceiverTypeOffset = kFlagOffset + kPointerSize;
   10137   static const int kSize = kExpectedReceiverTypeOffset + kPointerSize;
   10138 
   10139  private:
   10140   inline bool HasExpectedReceiverType() {
   10141     return expected_receiver_type()->IsFunctionTemplateInfo();
   10142   }
   10143   // Bit positions in flag.
   10144   static const int kAllCanReadBit = 0;
   10145   static const int kAllCanWriteBit = 1;
   10146   class AttributesField: public BitField<PropertyAttributes, 2, 3> {};
   10147 
   10148   DISALLOW_IMPLICIT_CONSTRUCTORS(AccessorInfo);
   10149 };
   10150 
   10151 
   10152 enum AccessorDescriptorType {
   10153   kDescriptorBitmaskCompare,
   10154   kDescriptorPointerCompare,
   10155   kDescriptorPrimitiveValue,
   10156   kDescriptorObjectDereference,
   10157   kDescriptorPointerDereference,
   10158   kDescriptorPointerShift,
   10159   kDescriptorReturnObject
   10160 };
   10161 
   10162 
   10163 struct BitmaskCompareDescriptor {
   10164   uint32_t bitmask;
   10165   uint32_t compare_value;
   10166   uint8_t size;  // Must be in {1,2,4}.
   10167 };
   10168 
   10169 
   10170 struct PointerCompareDescriptor {
   10171   void* compare_value;
   10172 };
   10173 
   10174 
   10175 struct PrimitiveValueDescriptor {
   10176   v8::DeclaredAccessorDescriptorDataType data_type;
   10177   uint8_t bool_offset;  // Must be in [0,7], used for kDescriptorBoolType.
   10178 };
   10179 
   10180 
   10181 struct ObjectDerefenceDescriptor {
   10182   uint8_t internal_field;
   10183 };
   10184 
   10185 
   10186 struct PointerShiftDescriptor {
   10187   int16_t byte_offset;
   10188 };
   10189 
   10190 
   10191 struct DeclaredAccessorDescriptorData {
   10192   AccessorDescriptorType type;
   10193   union {
   10194     struct BitmaskCompareDescriptor bitmask_compare_descriptor;
   10195     struct PointerCompareDescriptor pointer_compare_descriptor;
   10196     struct PrimitiveValueDescriptor primitive_value_descriptor;
   10197     struct ObjectDerefenceDescriptor object_dereference_descriptor;
   10198     struct PointerShiftDescriptor pointer_shift_descriptor;
   10199   };
   10200 };
   10201 
   10202 
   10203 class DeclaredAccessorDescriptor;
   10204 
   10205 
   10206 class DeclaredAccessorDescriptorIterator {
   10207  public:
   10208   explicit DeclaredAccessorDescriptorIterator(
   10209       DeclaredAccessorDescriptor* descriptor);
   10210   const DeclaredAccessorDescriptorData* Next();
   10211   bool Complete() const { return length_ == offset_; }
   10212  private:
   10213   uint8_t* array_;
   10214   const int length_;
   10215   int offset_;
   10216   DISALLOW_IMPLICIT_CONSTRUCTORS(DeclaredAccessorDescriptorIterator);
   10217 };
   10218 
   10219 
   10220 class DeclaredAccessorDescriptor: public Struct {
   10221  public:
   10222   DECL_ACCESSORS(serialized_data, ByteArray)
   10223 
   10224   DECLARE_CAST(DeclaredAccessorDescriptor)
   10225 
   10226   static Handle<DeclaredAccessorDescriptor> Create(
   10227       Isolate* isolate,
   10228       const DeclaredAccessorDescriptorData& data,
   10229       Handle<DeclaredAccessorDescriptor> previous);
   10230 
   10231   // Dispatched behavior.
   10232   DECLARE_PRINTER(DeclaredAccessorDescriptor)
   10233   DECLARE_VERIFIER(DeclaredAccessorDescriptor)
   10234 
   10235   static const int kSerializedDataOffset = HeapObject::kHeaderSize;
   10236   static const int kSize = kSerializedDataOffset + kPointerSize;
   10237 
   10238  private:
   10239   DISALLOW_IMPLICIT_CONSTRUCTORS(DeclaredAccessorDescriptor);
   10240 };
   10241 
   10242 
   10243 class DeclaredAccessorInfo: public AccessorInfo {
   10244  public:
   10245   DECL_ACCESSORS(descriptor, DeclaredAccessorDescriptor)
   10246 
   10247   DECLARE_CAST(DeclaredAccessorInfo)
   10248 
   10249   // Dispatched behavior.
   10250   DECLARE_PRINTER(DeclaredAccessorInfo)
   10251   DECLARE_VERIFIER(DeclaredAccessorInfo)
   10252 
   10253   static const int kDescriptorOffset = AccessorInfo::kSize;
   10254   static const int kSize = kDescriptorOffset + kPointerSize;
   10255 
   10256  private:
   10257   DISALLOW_IMPLICIT_CONSTRUCTORS(DeclaredAccessorInfo);
   10258 };
   10259 
   10260 
   10261 // An accessor must have a getter, but can have no setter.
   10262 //
   10263 // When setting a property, V8 searches accessors in prototypes.
   10264 // If an accessor was found and it does not have a setter,
   10265 // the request is ignored.
   10266 //
   10267 // If the accessor in the prototype has the READ_ONLY property attribute, then
   10268 // a new value is added to the derived object when the property is set.
   10269 // This shadows the accessor in the prototype.
   10270 class ExecutableAccessorInfo: public AccessorInfo {
   10271  public:
   10272   DECL_ACCESSORS(getter, Object)
   10273   DECL_ACCESSORS(setter, Object)
   10274   DECL_ACCESSORS(data, Object)
   10275 
   10276   DECLARE_CAST(ExecutableAccessorInfo)
   10277 
   10278   // Dispatched behavior.
   10279   DECLARE_PRINTER(ExecutableAccessorInfo)
   10280   DECLARE_VERIFIER(ExecutableAccessorInfo)
   10281 
   10282   static const int kGetterOffset = AccessorInfo::kSize;
   10283   static const int kSetterOffset = kGetterOffset + kPointerSize;
   10284   static const int kDataOffset = kSetterOffset + kPointerSize;
   10285   static const int kSize = kDataOffset + kPointerSize;
   10286 
   10287   inline void clear_setter();
   10288 
   10289  private:
   10290   DISALLOW_IMPLICIT_CONSTRUCTORS(ExecutableAccessorInfo);
   10291 };
   10292 
   10293 
   10294 // Support for JavaScript accessors: A pair of a getter and a setter. Each
   10295 // accessor can either be
   10296 //   * a pointer to a JavaScript function or proxy: a real accessor
   10297 //   * undefined: considered an accessor by the spec, too, strangely enough
   10298 //   * the hole: an accessor which has not been set
   10299 //   * a pointer to a map: a transition used to ensure map sharing
   10300 class AccessorPair: public Struct {
   10301  public:
   10302   DECL_ACCESSORS(getter, Object)
   10303   DECL_ACCESSORS(setter, Object)
   10304 
   10305   DECLARE_CAST(AccessorPair)
   10306 
   10307   static Handle<AccessorPair> Copy(Handle<AccessorPair> pair);
   10308 
   10309   Object* get(AccessorComponent component) {
   10310     return component == ACCESSOR_GETTER ? getter() : setter();
   10311   }
   10312 
   10313   void set(AccessorComponent component, Object* value) {
   10314     if (component == ACCESSOR_GETTER) {
   10315       set_getter(value);
   10316     } else {
   10317       set_setter(value);
   10318     }
   10319   }
   10320 
   10321   // Note: Returns undefined instead in case of a hole.
   10322   Object* GetComponent(AccessorComponent component);
   10323 
   10324   // Set both components, skipping arguments which are a JavaScript null.
   10325   void SetComponents(Object* getter, Object* setter) {
   10326     if (!getter->IsNull()) set_getter(getter);
   10327     if (!setter->IsNull()) set_setter(setter);
   10328   }
   10329 
   10330   bool ContainsAccessor() {
   10331     return IsJSAccessor(getter()) || IsJSAccessor(setter());
   10332   }
   10333 
   10334   // Dispatched behavior.
   10335   DECLARE_PRINTER(AccessorPair)
   10336   DECLARE_VERIFIER(AccessorPair)
   10337 
   10338   static const int kGetterOffset = HeapObject::kHeaderSize;
   10339   static const int kSetterOffset = kGetterOffset + kPointerSize;
   10340   static const int kSize = kSetterOffset + kPointerSize;
   10341 
   10342  private:
   10343   // Strangely enough, in addition to functions and harmony proxies, the spec
   10344   // requires us to consider undefined as a kind of accessor, too:
   10345   //    var obj = {};
   10346   //    Object.defineProperty(obj, "foo", {get: undefined});
   10347   //    assertTrue("foo" in obj);
   10348   bool IsJSAccessor(Object* obj) {
   10349     return obj->IsSpecFunction() || obj->IsUndefined();
   10350   }
   10351 
   10352   DISALLOW_IMPLICIT_CONSTRUCTORS(AccessorPair);
   10353 };
   10354 
   10355 
   10356 class AccessCheckInfo: public Struct {
   10357  public:
   10358   DECL_ACCESSORS(named_callback, Object)
   10359   DECL_ACCESSORS(indexed_callback, Object)
   10360   DECL_ACCESSORS(data, Object)
   10361 
   10362   DECLARE_CAST(AccessCheckInfo)
   10363 
   10364   // Dispatched behavior.
   10365   DECLARE_PRINTER(AccessCheckInfo)
   10366   DECLARE_VERIFIER(AccessCheckInfo)
   10367 
   10368   static const int kNamedCallbackOffset   = HeapObject::kHeaderSize;
   10369   static const int kIndexedCallbackOffset = kNamedCallbackOffset + kPointerSize;
   10370   static const int kDataOffset = kIndexedCallbackOffset + kPointerSize;
   10371   static const int kSize = kDataOffset + kPointerSize;
   10372 
   10373  private:
   10374   DISALLOW_IMPLICIT_CONSTRUCTORS(AccessCheckInfo);
   10375 };
   10376 
   10377 
   10378 class InterceptorInfo: public Struct {
   10379  public:
   10380   DECL_ACCESSORS(getter, Object)
   10381   DECL_ACCESSORS(setter, Object)
   10382   DECL_ACCESSORS(query, Object)
   10383   DECL_ACCESSORS(deleter, Object)
   10384   DECL_ACCESSORS(enumerator, Object)
   10385   DECL_ACCESSORS(data, Object)
   10386 
   10387   DECLARE_CAST(InterceptorInfo)
   10388 
   10389   // Dispatched behavior.
   10390   DECLARE_PRINTER(InterceptorInfo)
   10391   DECLARE_VERIFIER(InterceptorInfo)
   10392 
   10393   static const int kGetterOffset = HeapObject::kHeaderSize;
   10394   static const int kSetterOffset = kGetterOffset + kPointerSize;
   10395   static const int kQueryOffset = kSetterOffset + kPointerSize;
   10396   static const int kDeleterOffset = kQueryOffset + kPointerSize;
   10397   static const int kEnumeratorOffset = kDeleterOffset + kPointerSize;
   10398   static const int kDataOffset = kEnumeratorOffset + kPointerSize;
   10399   static const int kSize = kDataOffset + kPointerSize;
   10400 
   10401  private:
   10402   DISALLOW_IMPLICIT_CONSTRUCTORS(InterceptorInfo);
   10403 };
   10404 
   10405 
   10406 class CallHandlerInfo: public Struct {
   10407  public:
   10408   DECL_ACCESSORS(callback, Object)
   10409   DECL_ACCESSORS(data, Object)
   10410 
   10411   DECLARE_CAST(CallHandlerInfo)
   10412 
   10413   // Dispatched behavior.
   10414   DECLARE_PRINTER(CallHandlerInfo)
   10415   DECLARE_VERIFIER(CallHandlerInfo)
   10416 
   10417   static const int kCallbackOffset = HeapObject::kHeaderSize;
   10418   static const int kDataOffset = kCallbackOffset + kPointerSize;
   10419   static const int kSize = kDataOffset + kPointerSize;
   10420 
   10421  private:
   10422   DISALLOW_IMPLICIT_CONSTRUCTORS(CallHandlerInfo);
   10423 };
   10424 
   10425 
   10426 class TemplateInfo: public Struct {
   10427  public:
   10428   DECL_ACCESSORS(tag, Object)
   10429   DECL_ACCESSORS(property_list, Object)
   10430   DECL_ACCESSORS(property_accessors, Object)
   10431 
   10432   DECLARE_VERIFIER(TemplateInfo)
   10433 
   10434   static const int kTagOffset = HeapObject::kHeaderSize;
   10435   static const int kPropertyListOffset = kTagOffset + kPointerSize;
   10436   static const int kPropertyAccessorsOffset =
   10437       kPropertyListOffset + kPointerSize;
   10438   static const int kHeaderSize = kPropertyAccessorsOffset + kPointerSize;
   10439 
   10440  private:
   10441   DISALLOW_IMPLICIT_CONSTRUCTORS(TemplateInfo);
   10442 };
   10443 
   10444 
   10445 class FunctionTemplateInfo: public TemplateInfo {
   10446  public:
   10447   DECL_ACCESSORS(serial_number, Object)
   10448   DECL_ACCESSORS(call_code, Object)
   10449   DECL_ACCESSORS(prototype_template, Object)
   10450   DECL_ACCESSORS(parent_template, Object)
   10451   DECL_ACCESSORS(named_property_handler, Object)
   10452   DECL_ACCESSORS(indexed_property_handler, Object)
   10453   DECL_ACCESSORS(instance_template, Object)
   10454   DECL_ACCESSORS(class_name, Object)
   10455   DECL_ACCESSORS(signature, Object)
   10456   DECL_ACCESSORS(instance_call_handler, Object)
   10457   DECL_ACCESSORS(access_check_info, Object)
   10458   DECL_ACCESSORS(flag, Smi)
   10459 
   10460   inline int length() const;
   10461   inline void set_length(int value);
   10462 
   10463   // Following properties use flag bits.
   10464   DECL_BOOLEAN_ACCESSORS(hidden_prototype)
   10465   DECL_BOOLEAN_ACCESSORS(undetectable)
   10466   // If the bit is set, object instances created by this function
   10467   // requires access check.
   10468   DECL_BOOLEAN_ACCESSORS(needs_access_check)
   10469   DECL_BOOLEAN_ACCESSORS(read_only_prototype)
   10470   DECL_BOOLEAN_ACCESSORS(remove_prototype)
   10471   DECL_BOOLEAN_ACCESSORS(do_not_cache)
   10472 
   10473   DECLARE_CAST(FunctionTemplateInfo)
   10474 
   10475   // Dispatched behavior.
   10476   DECLARE_PRINTER(FunctionTemplateInfo)
   10477   DECLARE_VERIFIER(FunctionTemplateInfo)
   10478 
   10479   static const int kSerialNumberOffset = TemplateInfo::kHeaderSize;
   10480   static const int kCallCodeOffset = kSerialNumberOffset + kPointerSize;
   10481   static const int kPrototypeTemplateOffset =
   10482       kCallCodeOffset + kPointerSize;
   10483   static const int kParentTemplateOffset =
   10484       kPrototypeTemplateOffset + kPointerSize;
   10485   static const int kNamedPropertyHandlerOffset =
   10486       kParentTemplateOffset + kPointerSize;
   10487   static const int kIndexedPropertyHandlerOffset =
   10488       kNamedPropertyHandlerOffset + kPointerSize;
   10489   static const int kInstanceTemplateOffset =
   10490       kIndexedPropertyHandlerOffset + kPointerSize;
   10491   static const int kClassNameOffset = kInstanceTemplateOffset + kPointerSize;
   10492   static const int kSignatureOffset = kClassNameOffset + kPointerSize;
   10493   static const int kInstanceCallHandlerOffset = kSignatureOffset + kPointerSize;
   10494   static const int kAccessCheckInfoOffset =
   10495       kInstanceCallHandlerOffset + kPointerSize;
   10496   static const int kFlagOffset = kAccessCheckInfoOffset + kPointerSize;
   10497   static const int kLengthOffset = kFlagOffset + kPointerSize;
   10498   static const int kSize = kLengthOffset + kPointerSize;
   10499 
   10500   // Returns true if |object| is an instance of this function template.
   10501   bool IsTemplateFor(Object* object);
   10502   bool IsTemplateFor(Map* map);
   10503 
   10504  private:
   10505   // Bit position in the flag, from least significant bit position.
   10506   static const int kHiddenPrototypeBit   = 0;
   10507   static const int kUndetectableBit      = 1;
   10508   static const int kNeedsAccessCheckBit  = 2;
   10509   static const int kReadOnlyPrototypeBit = 3;
   10510   static const int kRemovePrototypeBit   = 4;
   10511   static const int kDoNotCacheBit        = 5;
   10512 
   10513   DISALLOW_IMPLICIT_CONSTRUCTORS(FunctionTemplateInfo);
   10514 };
   10515 
   10516 
   10517 class ObjectTemplateInfo: public TemplateInfo {
   10518  public:
   10519   DECL_ACCESSORS(constructor, Object)
   10520   DECL_ACCESSORS(internal_field_count, Object)
   10521 
   10522   DECLARE_CAST(ObjectTemplateInfo)
   10523 
   10524   // Dispatched behavior.
   10525   DECLARE_PRINTER(ObjectTemplateInfo)
   10526   DECLARE_VERIFIER(ObjectTemplateInfo)
   10527 
   10528   static const int kConstructorOffset = TemplateInfo::kHeaderSize;
   10529   static const int kInternalFieldCountOffset =
   10530       kConstructorOffset + kPointerSize;
   10531   static const int kSize = kInternalFieldCountOffset + kPointerSize;
   10532 };
   10533 
   10534 
   10535 class SignatureInfo: public Struct {
   10536  public:
   10537   DECL_ACCESSORS(receiver, Object)
   10538   DECL_ACCESSORS(args, Object)
   10539 
   10540   DECLARE_CAST(SignatureInfo)
   10541 
   10542   // Dispatched behavior.
   10543   DECLARE_PRINTER(SignatureInfo)
   10544   DECLARE_VERIFIER(SignatureInfo)
   10545 
   10546   static const int kReceiverOffset = Struct::kHeaderSize;
   10547   static const int kArgsOffset     = kReceiverOffset + kPointerSize;
   10548   static const int kSize           = kArgsOffset + kPointerSize;
   10549 
   10550  private:
   10551   DISALLOW_IMPLICIT_CONSTRUCTORS(SignatureInfo);
   10552 };
   10553 
   10554 
   10555 class TypeSwitchInfo: public Struct {
   10556  public:
   10557   DECL_ACCESSORS(types, Object)
   10558 
   10559   DECLARE_CAST(TypeSwitchInfo)
   10560 
   10561   // Dispatched behavior.
   10562   DECLARE_PRINTER(TypeSwitchInfo)
   10563   DECLARE_VERIFIER(TypeSwitchInfo)
   10564 
   10565   static const int kTypesOffset = Struct::kHeaderSize;
   10566   static const int kSize        = kTypesOffset + kPointerSize;
   10567 };
   10568 
   10569 
   10570 // The DebugInfo class holds additional information for a function being
   10571 // debugged.
   10572 class DebugInfo: public Struct {
   10573  public:
   10574   // The shared function info for the source being debugged.
   10575   DECL_ACCESSORS(shared, SharedFunctionInfo)
   10576   // Code object for the original code.
   10577   DECL_ACCESSORS(original_code, Code)
   10578   // Code object for the patched code. This code object is the code object
   10579   // currently active for the function.
   10580   DECL_ACCESSORS(code, Code)
   10581   // Fixed array holding status information for each active break point.
   10582   DECL_ACCESSORS(break_points, FixedArray)
   10583 
   10584   // Check if there is a break point at a code position.
   10585   bool HasBreakPoint(int code_position);
   10586   // Get the break point info object for a code position.
   10587   Object* GetBreakPointInfo(int code_position);
   10588   // Clear a break point.
   10589   static void ClearBreakPoint(Handle<DebugInfo> debug_info,
   10590                               int code_position,
   10591                               Handle<Object> break_point_object);
   10592   // Set a break point.
   10593   static void SetBreakPoint(Handle<DebugInfo> debug_info, int code_position,
   10594                             int source_position, int statement_position,
   10595                             Handle<Object> break_point_object);
   10596   // Get the break point objects for a code position.
   10597   Object* GetBreakPointObjects(int code_position);
   10598   // Find the break point info holding this break point object.
   10599   static Object* FindBreakPointInfo(Handle<DebugInfo> debug_info,
   10600                                     Handle<Object> break_point_object);
   10601   // Get the number of break points for this function.
   10602   int GetBreakPointCount();
   10603 
   10604   DECLARE_CAST(DebugInfo)
   10605 
   10606   // Dispatched behavior.
   10607   DECLARE_PRINTER(DebugInfo)
   10608   DECLARE_VERIFIER(DebugInfo)
   10609 
   10610   static const int kSharedFunctionInfoIndex = Struct::kHeaderSize;
   10611   static const int kOriginalCodeIndex = kSharedFunctionInfoIndex + kPointerSize;
   10612   static const int kPatchedCodeIndex = kOriginalCodeIndex + kPointerSize;
   10613   static const int kActiveBreakPointsCountIndex =
   10614       kPatchedCodeIndex + kPointerSize;
   10615   static const int kBreakPointsStateIndex =
   10616       kActiveBreakPointsCountIndex + kPointerSize;
   10617   static const int kSize = kBreakPointsStateIndex + kPointerSize;
   10618 
   10619   static const int kEstimatedNofBreakPointsInFunction = 16;
   10620 
   10621  private:
   10622   static const int kNoBreakPointInfo = -1;
   10623 
   10624   // Lookup the index in the break_points array for a code position.
   10625   int GetBreakPointInfoIndex(int code_position);
   10626 
   10627   DISALLOW_IMPLICIT_CONSTRUCTORS(DebugInfo);
   10628 };
   10629 
   10630 
   10631 // The BreakPointInfo class holds information for break points set in a
   10632 // function. The DebugInfo object holds a BreakPointInfo object for each code
   10633 // position with one or more break points.
   10634 class BreakPointInfo: public Struct {
   10635  public:
   10636   // The position in the code for the break point.
   10637   DECL_ACCESSORS(code_position, Smi)
   10638   // The position in the source for the break position.
   10639   DECL_ACCESSORS(source_position, Smi)
   10640   // The position in the source for the last statement before this break
   10641   // position.
   10642   DECL_ACCESSORS(statement_position, Smi)
   10643   // List of related JavaScript break points.
   10644   DECL_ACCESSORS(break_point_objects, Object)
   10645 
   10646   // Removes a break point.
   10647   static void ClearBreakPoint(Handle<BreakPointInfo> info,
   10648                               Handle<Object> break_point_object);
   10649   // Set a break point.
   10650   static void SetBreakPoint(Handle<BreakPointInfo> info,
   10651                             Handle<Object> break_point_object);
   10652   // Check if break point info has this break point object.
   10653   static bool HasBreakPointObject(Handle<BreakPointInfo> info,
   10654                                   Handle<Object> break_point_object);
   10655   // Get the number of break points for this code position.
   10656   int GetBreakPointCount();
   10657 
   10658   DECLARE_CAST(BreakPointInfo)
   10659 
   10660   // Dispatched behavior.
   10661   DECLARE_PRINTER(BreakPointInfo)
   10662   DECLARE_VERIFIER(BreakPointInfo)
   10663 
   10664   static const int kCodePositionIndex = Struct::kHeaderSize;
   10665   static const int kSourcePositionIndex = kCodePositionIndex + kPointerSize;
   10666   static const int kStatementPositionIndex =
   10667       kSourcePositionIndex + kPointerSize;
   10668   static const int kBreakPointObjectsIndex =
   10669       kStatementPositionIndex + kPointerSize;
   10670   static const int kSize = kBreakPointObjectsIndex + kPointerSize;
   10671 
   10672  private:
   10673   DISALLOW_IMPLICIT_CONSTRUCTORS(BreakPointInfo);
   10674 };
   10675 
   10676 
   10677 #undef DECL_BOOLEAN_ACCESSORS
   10678 #undef DECL_ACCESSORS
   10679 #undef DECLARE_CAST
   10680 #undef DECLARE_VERIFIER
   10681 
   10682 #define VISITOR_SYNCHRONIZATION_TAGS_LIST(V)                            \
   10683   V(kStringTable, "string_table", "(Internalized strings)")             \
   10684   V(kExternalStringsTable, "external_strings_table", "(External strings)") \
   10685   V(kStrongRootList, "strong_root_list", "(Strong roots)")              \
   10686   V(kSmiRootList, "smi_root_list", "(Smi roots)")                       \
   10687   V(kInternalizedString, "internalized_string", "(Internal string)")    \
   10688   V(kBootstrapper, "bootstrapper", "(Bootstrapper)")                    \
   10689   V(kTop, "top", "(Isolate)")                                           \
   10690   V(kRelocatable, "relocatable", "(Relocatable)")                       \
   10691   V(kDebug, "debug", "(Debugger)")                                      \
   10692   V(kCompilationCache, "compilationcache", "(Compilation cache)")       \
   10693   V(kHandleScope, "handlescope", "(Handle scope)")                      \
   10694   V(kBuiltins, "builtins", "(Builtins)")                                \
   10695   V(kGlobalHandles, "globalhandles", "(Global handles)")                \
   10696   V(kEternalHandles, "eternalhandles", "(Eternal handles)")             \
   10697   V(kThreadManager, "threadmanager", "(Thread manager)")                \
   10698   V(kExtensions, "Extensions", "(Extensions)")
   10699 
   10700 class VisitorSynchronization : public AllStatic {
   10701  public:
   10702 #define DECLARE_ENUM(enum_item, ignore1, ignore2) enum_item,
   10703   enum SyncTag {
   10704     VISITOR_SYNCHRONIZATION_TAGS_LIST(DECLARE_ENUM)
   10705     kNumberOfSyncTags
   10706   };
   10707 #undef DECLARE_ENUM
   10708 
   10709   static const char* const kTags[kNumberOfSyncTags];
   10710   static const char* const kTagNames[kNumberOfSyncTags];
   10711 };
   10712 
   10713 // Abstract base class for visiting, and optionally modifying, the
   10714 // pointers contained in Objects. Used in GC and serialization/deserialization.
   10715 class ObjectVisitor BASE_EMBEDDED {
   10716  public:
   10717   virtual ~ObjectVisitor() {}
   10718 
   10719   // Visits a contiguous arrays of pointers in the half-open range
   10720   // [start, end). Any or all of the values may be modified on return.
   10721   virtual void VisitPointers(Object** start, Object** end) = 0;
   10722 
   10723   // Handy shorthand for visiting a single pointer.
   10724   virtual void VisitPointer(Object** p) { VisitPointers(p, p + 1); }
   10725 
   10726   // Visit weak next_code_link in Code object.
   10727   virtual void VisitNextCodeLink(Object** p) { VisitPointers(p, p + 1); }
   10728 
   10729   // To allow lazy clearing of inline caches the visitor has
   10730   // a rich interface for iterating over Code objects..
   10731 
   10732   // Visits a code target in the instruction stream.
   10733   virtual void VisitCodeTarget(RelocInfo* rinfo);
   10734 
   10735   // Visits a code entry in a JS function.
   10736   virtual void VisitCodeEntry(Address entry_address);
   10737 
   10738   // Visits a global property cell reference in the instruction stream.
   10739   virtual void VisitCell(RelocInfo* rinfo);
   10740 
   10741   // Visits a runtime entry in the instruction stream.
   10742   virtual void VisitRuntimeEntry(RelocInfo* rinfo) {}
   10743 
   10744   // Visits the resource of an one-byte or two-byte string.
   10745   virtual void VisitExternalOneByteString(
   10746       v8::String::ExternalOneByteStringResource** resource) {}
   10747   virtual void VisitExternalTwoByteString(
   10748       v8::String::ExternalStringResource** resource) {}
   10749 
   10750   // Visits a debug call target in the instruction stream.
   10751   virtual void VisitDebugTarget(RelocInfo* rinfo);
   10752 
   10753   // Visits the byte sequence in a function's prologue that contains information
   10754   // about the code's age.
   10755   virtual void VisitCodeAgeSequence(RelocInfo* rinfo);
   10756 
   10757   // Visit pointer embedded into a code object.
   10758   virtual void VisitEmbeddedPointer(RelocInfo* rinfo);
   10759 
   10760   // Visits an external reference embedded into a code object.
   10761   virtual void VisitExternalReference(RelocInfo* rinfo);
   10762 
   10763   // Visits an external reference. The value may be modified on return.
   10764   virtual void VisitExternalReference(Address* p) {}
   10765 
   10766   // Visits a handle that has an embedder-assigned class ID.
   10767   virtual void VisitEmbedderReference(Object** p, uint16_t class_id) {}
   10768 
   10769   // Intended for serialization/deserialization checking: insert, or
   10770   // check for the presence of, a tag at this position in the stream.
   10771   // Also used for marking up GC roots in heap snapshots.
   10772   virtual void Synchronize(VisitorSynchronization::SyncTag tag) {}
   10773 };
   10774 
   10775 
   10776 class StructBodyDescriptor : public
   10777   FlexibleBodyDescriptor<HeapObject::kHeaderSize> {
   10778  public:
   10779   static inline int SizeOf(Map* map, HeapObject* object) {
   10780     return map->instance_size();
   10781   }
   10782 };
   10783 
   10784 
   10785 // BooleanBit is a helper class for setting and getting a bit in an
   10786 // integer or Smi.
   10787 class BooleanBit : public AllStatic {
   10788  public:
   10789   static inline bool get(Smi* smi, int bit_position) {
   10790     return get(smi->value(), bit_position);
   10791   }
   10792 
   10793   static inline bool get(int value, int bit_position) {
   10794     return (value & (1 << bit_position)) != 0;
   10795   }
   10796 
   10797   static inline Smi* set(Smi* smi, int bit_position, bool v) {
   10798     return Smi::FromInt(set(smi->value(), bit_position, v));
   10799   }
   10800 
   10801   static inline int set(int value, int bit_position, bool v) {
   10802     if (v) {
   10803       value |= (1 << bit_position);
   10804     } else {
   10805       value &= ~(1 << bit_position);
   10806     }
   10807     return value;
   10808   }
   10809 };
   10810 
   10811 } }  // namespace v8::internal
   10812 
   10813 #endif  // V8_OBJECTS_H_
   10814