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