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