• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  // Copyright 2011 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 "builtins.h"
32  #include "smart-pointer.h"
33  #include "unicode-inl.h"
34  #if V8_TARGET_ARCH_ARM
35  #include "arm/constants-arm.h"
36  #elif V8_TARGET_ARCH_MIPS
37  #include "mips/constants-mips.h"
38  #endif
39  
40  //
41  // Most object types in the V8 JavaScript are described in this file.
42  //
43  // Inheritance hierarchy:
44  // - MaybeObject    (an object or a failure)
45  //   - Failure      (immediate for marking failed operation)
46  //   - Object
47  //     - Smi          (immediate small integer)
48  //     - HeapObject   (superclass for everything allocated in the heap)
49  //       - JSObject
50  //         - JSArray
51  //         - JSRegExp
52  //         - JSFunction
53  //         - GlobalObject
54  //           - JSGlobalObject
55  //           - JSBuiltinsObject
56  //         - JSGlobalProxy
57  //         - JSValue
58  //         - JSMessageObject
59  //       - ByteArray
60  //       - ExternalArray
61  //         - ExternalPixelArray
62  //         - ExternalByteArray
63  //         - ExternalUnsignedByteArray
64  //         - ExternalShortArray
65  //         - ExternalUnsignedShortArray
66  //         - ExternalIntArray
67  //         - ExternalUnsignedIntArray
68  //         - ExternalFloatArray
69  //       - FixedArray
70  //         - DescriptorArray
71  //         - HashTable
72  //           - Dictionary
73  //           - SymbolTable
74  //           - CompilationCacheTable
75  //           - CodeCacheHashTable
76  //           - MapCache
77  //         - Context
78  //         - JSFunctionResultCache
79  //         - SerializedScopeInfo
80  //       - String
81  //         - SeqString
82  //           - SeqAsciiString
83  //           - SeqTwoByteString
84  //         - ConsString
85  //         - ExternalString
86  //           - ExternalAsciiString
87  //           - ExternalTwoByteString
88  //       - HeapNumber
89  //       - Code
90  //       - Map
91  //       - Oddball
92  //       - Proxy
93  //       - SharedFunctionInfo
94  //       - Struct
95  //         - AccessorInfo
96  //         - AccessCheckInfo
97  //         - InterceptorInfo
98  //         - CallHandlerInfo
99  //         - TemplateInfo
100  //           - FunctionTemplateInfo
101  //           - ObjectTemplateInfo
102  //         - Script
103  //         - SignatureInfo
104  //         - TypeSwitchInfo
105  //         - DebugInfo
106  //         - BreakPointInfo
107  //         - CodeCache
108  //
109  // Formats of Object*:
110  //  Smi:        [31 bit signed int] 0
111  //  HeapObject: [32 bit direct pointer] (4 byte aligned) | 01
112  //  Failure:    [30 bit signed int] 11
113  
114  // Ecma-262 3rd 8.6.1
115  enum PropertyAttributes {
116    NONE              = v8::None,
117    READ_ONLY         = v8::ReadOnly,
118    DONT_ENUM         = v8::DontEnum,
119    DONT_DELETE       = v8::DontDelete,
120    ABSENT            = 16  // Used in runtime to indicate a property is absent.
121    // ABSENT can never be stored in or returned from a descriptor's attributes
122    // bitfield.  It is only used as a return value meaning the attributes of
123    // a non-existent property.
124  };
125  
126  namespace v8 {
127  namespace internal {
128  
129  
130  // PropertyDetails captures type and attributes for a property.
131  // They are used both in property dictionaries and instance descriptors.
132  class PropertyDetails BASE_EMBEDDED {
133   public:
134  
135    PropertyDetails(PropertyAttributes attributes,
136                    PropertyType type,
137                    int index = 0) {
138      ASSERT(type != EXTERNAL_ARRAY_TRANSITION);
139      ASSERT(TypeField::is_valid(type));
140      ASSERT(AttributesField::is_valid(attributes));
141      ASSERT(StorageField::is_valid(index));
142  
143      value_ = TypeField::encode(type)
144          | AttributesField::encode(attributes)
145          | StorageField::encode(index);
146  
147      ASSERT(type == this->type());
148      ASSERT(attributes == this->attributes());
149      ASSERT(index == this->index());
150    }
151  
PropertyDetails(PropertyAttributes attributes,PropertyType type,ExternalArrayType array_type)152    PropertyDetails(PropertyAttributes attributes,
153                    PropertyType type,
154                    ExternalArrayType array_type) {
155      ASSERT(type == EXTERNAL_ARRAY_TRANSITION);
156      ASSERT(TypeField::is_valid(type));
157      ASSERT(AttributesField::is_valid(attributes));
158      ASSERT(StorageField::is_valid(static_cast<int>(array_type)));
159  
160      value_ = TypeField::encode(type)
161          | AttributesField::encode(attributes)
162          | StorageField::encode(static_cast<int>(array_type));
163  
164      ASSERT(type == this->type());
165      ASSERT(attributes == this->attributes());
166      ASSERT(array_type == this->array_type());
167    }
168  
169    // Conversion for storing details as Object*.
170    explicit inline PropertyDetails(Smi* smi);
171    inline Smi* AsSmi();
172  
type()173    PropertyType type() { return TypeField::decode(value_); }
174  
IsTransition()175    bool IsTransition() {
176      PropertyType t = type();
177      ASSERT(t != INTERCEPTOR);
178      return t == MAP_TRANSITION || t == CONSTANT_TRANSITION ||
179          t == EXTERNAL_ARRAY_TRANSITION;
180    }
181  
IsProperty()182    bool IsProperty() {
183      return type() < FIRST_PHANTOM_PROPERTY_TYPE;
184    }
185  
attributes()186    PropertyAttributes attributes() { return AttributesField::decode(value_); }
187  
index()188    int index() { return StorageField::decode(value_); }
189  
array_type()190    ExternalArrayType array_type() {
191      ASSERT(type() == EXTERNAL_ARRAY_TRANSITION);
192      return static_cast<ExternalArrayType>(StorageField::decode(value_));
193    }
194  
195    inline PropertyDetails AsDeleted();
196  
IsValidIndex(int index)197    static bool IsValidIndex(int index) {
198      return StorageField::is_valid(index);
199    }
200  
IsReadOnly()201    bool IsReadOnly() { return (attributes() & READ_ONLY) != 0; }
IsDontDelete()202    bool IsDontDelete() { return (attributes() & DONT_DELETE) != 0; }
IsDontEnum()203    bool IsDontEnum() { return (attributes() & DONT_ENUM) != 0; }
IsDeleted()204    bool IsDeleted() { return DeletedField::decode(value_) != 0;}
205  
206    // Bit fields in value_ (type, shift, size). Must be public so the
207    // constants can be embedded in generated code.
208    class TypeField:       public BitField<PropertyType,       0, 4> {};
209    class AttributesField: public BitField<PropertyAttributes, 4, 3> {};
210    class DeletedField:    public BitField<uint32_t,           7, 1> {};
211    class StorageField:    public BitField<uint32_t,           8, 32-8> {};
212  
213    static const int kInitialIndex = 1;
214   private:
215    uint32_t value_;
216  };
217  
218  
219  // Setter that skips the write barrier if mode is SKIP_WRITE_BARRIER.
220  enum WriteBarrierMode { SKIP_WRITE_BARRIER, UPDATE_WRITE_BARRIER };
221  
222  
223  // PropertyNormalizationMode is used to specify whether to keep
224  // inobject properties when normalizing properties of a JSObject.
225  enum PropertyNormalizationMode {
226    CLEAR_INOBJECT_PROPERTIES,
227    KEEP_INOBJECT_PROPERTIES
228  };
229  
230  
231  // NormalizedMapSharingMode is used to specify whether a map may be shared
232  // by different objects with normalized properties.
233  enum NormalizedMapSharingMode {
234    UNIQUE_NORMALIZED_MAP,
235    SHARED_NORMALIZED_MAP
236  };
237  
238  
239  // Instance size sentinel for objects of variable size.
240  static const int kVariableSizeSentinel = 0;
241  
242  
243  // All Maps have a field instance_type containing a InstanceType.
244  // It describes the type of the instances.
245  //
246  // As an example, a JavaScript object is a heap object and its map
247  // instance_type is JS_OBJECT_TYPE.
248  //
249  // The names of the string instance types are intended to systematically
250  // mirror their encoding in the instance_type field of the map.  The default
251  // encoding is considered TWO_BYTE.  It is not mentioned in the name.  ASCII
252  // encoding is mentioned explicitly in the name.  Likewise, the default
253  // representation is considered sequential.  It is not mentioned in the
254  // name.  The other representations (eg, CONS, EXTERNAL) are explicitly
255  // mentioned.  Finally, the string is either a SYMBOL_TYPE (if it is a
256  // symbol) or a STRING_TYPE (if it is not a symbol).
257  //
258  // NOTE: The following things are some that depend on the string types having
259  // instance_types that are less than those of all other types:
260  // HeapObject::Size, HeapObject::IterateBody, the typeof operator, and
261  // Object::IsString.
262  //
263  // NOTE: Everything following JS_VALUE_TYPE is considered a
264  // JSObject for GC purposes. The first four entries here have typeof
265  // 'object', whereas JS_FUNCTION_TYPE has typeof 'function'.
266  #define INSTANCE_TYPE_LIST_ALL(V)                                              \
267    V(SYMBOL_TYPE)                                                               \
268    V(ASCII_SYMBOL_TYPE)                                                         \
269    V(CONS_SYMBOL_TYPE)                                                          \
270    V(CONS_ASCII_SYMBOL_TYPE)                                                    \
271    V(EXTERNAL_SYMBOL_TYPE)                                                      \
272    V(EXTERNAL_SYMBOL_WITH_ASCII_DATA_TYPE)                                      \
273    V(EXTERNAL_ASCII_SYMBOL_TYPE)                                                \
274    V(STRING_TYPE)                                                               \
275    V(ASCII_STRING_TYPE)                                                         \
276    V(CONS_STRING_TYPE)                                                          \
277    V(CONS_ASCII_STRING_TYPE)                                                    \
278    V(EXTERNAL_STRING_TYPE)                                                      \
279    V(EXTERNAL_STRING_WITH_ASCII_DATA_TYPE)                                      \
280    V(EXTERNAL_ASCII_STRING_TYPE)                                                \
281    V(PRIVATE_EXTERNAL_ASCII_STRING_TYPE)                                        \
282                                                                                 \
283    V(MAP_TYPE)                                                                  \
284    V(CODE_TYPE)                                                                 \
285    V(ODDBALL_TYPE)                                                              \
286    V(JS_GLOBAL_PROPERTY_CELL_TYPE)                                              \
287                                                                                 \
288    V(HEAP_NUMBER_TYPE)                                                          \
289    V(PROXY_TYPE)                                                                \
290    V(BYTE_ARRAY_TYPE)                                                           \
291    /* Note: the order of these external array */                                \
292    /* types is relied upon in */                                                \
293    /* Object::IsExternalArray(). */                                             \
294    V(EXTERNAL_BYTE_ARRAY_TYPE)                                                  \
295    V(EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)                                         \
296    V(EXTERNAL_SHORT_ARRAY_TYPE)                                                 \
297    V(EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)                                        \
298    V(EXTERNAL_INT_ARRAY_TYPE)                                                   \
299    V(EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)                                          \
300    V(EXTERNAL_FLOAT_ARRAY_TYPE)                                                 \
301    V(EXTERNAL_PIXEL_ARRAY_TYPE)                                                 \
302    V(FILLER_TYPE)                                                               \
303                                                                                 \
304    V(ACCESSOR_INFO_TYPE)                                                        \
305    V(ACCESS_CHECK_INFO_TYPE)                                                    \
306    V(INTERCEPTOR_INFO_TYPE)                                                     \
307    V(CALL_HANDLER_INFO_TYPE)                                                    \
308    V(FUNCTION_TEMPLATE_INFO_TYPE)                                               \
309    V(OBJECT_TEMPLATE_INFO_TYPE)                                                 \
310    V(SIGNATURE_INFO_TYPE)                                                       \
311    V(TYPE_SWITCH_INFO_TYPE)                                                     \
312    V(SCRIPT_TYPE)                                                               \
313    V(CODE_CACHE_TYPE)                                                           \
314                                                                                 \
315    V(FIXED_ARRAY_TYPE)                                                          \
316    V(SHARED_FUNCTION_INFO_TYPE)                                                 \
317                                                                                 \
318    V(JS_MESSAGE_OBJECT_TYPE)                                                    \
319                                                                                 \
320    V(JS_VALUE_TYPE)                                                             \
321    V(JS_OBJECT_TYPE)                                                            \
322    V(JS_CONTEXT_EXTENSION_OBJECT_TYPE)                                          \
323    V(JS_GLOBAL_OBJECT_TYPE)                                                     \
324    V(JS_BUILTINS_OBJECT_TYPE)                                                   \
325    V(JS_GLOBAL_PROXY_TYPE)                                                      \
326    V(JS_ARRAY_TYPE)                                                             \
327    V(JS_REGEXP_TYPE)                                                            \
328                                                                                 \
329    V(JS_FUNCTION_TYPE)                                                          \
330  
331  #ifdef ENABLE_DEBUGGER_SUPPORT
332  #define INSTANCE_TYPE_LIST_DEBUGGER(V)                                         \
333    V(DEBUG_INFO_TYPE)                                                           \
334    V(BREAK_POINT_INFO_TYPE)
335  #else
336  #define INSTANCE_TYPE_LIST_DEBUGGER(V)
337  #endif
338  
339  #define INSTANCE_TYPE_LIST(V)                                                  \
340    INSTANCE_TYPE_LIST_ALL(V)                                                    \
341    INSTANCE_TYPE_LIST_DEBUGGER(V)
342  
343  
344  // Since string types are not consecutive, this macro is used to
345  // iterate over them.
346  #define STRING_TYPE_LIST(V)                                                    \
347    V(SYMBOL_TYPE,                                                               \
348      kVariableSizeSentinel,                                                     \
349      symbol,                                                                    \
350      Symbol)                                                                    \
351    V(ASCII_SYMBOL_TYPE,                                                         \
352      kVariableSizeSentinel,                                                     \
353      ascii_symbol,                                                              \
354      AsciiSymbol)                                                               \
355    V(CONS_SYMBOL_TYPE,                                                          \
356      ConsString::kSize,                                                         \
357      cons_symbol,                                                               \
358      ConsSymbol)                                                                \
359    V(CONS_ASCII_SYMBOL_TYPE,                                                    \
360      ConsString::kSize,                                                         \
361      cons_ascii_symbol,                                                         \
362      ConsAsciiSymbol)                                                           \
363    V(EXTERNAL_SYMBOL_TYPE,                                                      \
364      ExternalTwoByteString::kSize,                                              \
365      external_symbol,                                                           \
366      ExternalSymbol)                                                            \
367    V(EXTERNAL_SYMBOL_WITH_ASCII_DATA_TYPE,                                      \
368      ExternalTwoByteString::kSize,                                              \
369      external_symbol_with_ascii_data,                                           \
370      ExternalSymbolWithAsciiData)                                               \
371    V(EXTERNAL_ASCII_SYMBOL_TYPE,                                                \
372      ExternalAsciiString::kSize,                                                \
373      external_ascii_symbol,                                                     \
374      ExternalAsciiSymbol)                                                       \
375    V(STRING_TYPE,                                                               \
376      kVariableSizeSentinel,                                                     \
377      string,                                                                    \
378      String)                                                                    \
379    V(ASCII_STRING_TYPE,                                                         \
380      kVariableSizeSentinel,                                                     \
381      ascii_string,                                                              \
382      AsciiString)                                                               \
383    V(CONS_STRING_TYPE,                                                          \
384      ConsString::kSize,                                                         \
385      cons_string,                                                               \
386      ConsString)                                                                \
387    V(CONS_ASCII_STRING_TYPE,                                                    \
388      ConsString::kSize,                                                         \
389      cons_ascii_string,                                                         \
390      ConsAsciiString)                                                           \
391    V(EXTERNAL_STRING_TYPE,                                                      \
392      ExternalTwoByteString::kSize,                                              \
393      external_string,                                                           \
394      ExternalString)                                                            \
395    V(EXTERNAL_STRING_WITH_ASCII_DATA_TYPE,                                      \
396      ExternalTwoByteString::kSize,                                              \
397      external_string_with_ascii_data,                                           \
398      ExternalStringWithAsciiData)                                               \
399    V(EXTERNAL_ASCII_STRING_TYPE,                                                \
400      ExternalAsciiString::kSize,                                                \
401      external_ascii_string,                                                     \
402      ExternalAsciiString)
403  
404  // A struct is a simple object a set of object-valued fields.  Including an
405  // object type in this causes the compiler to generate most of the boilerplate
406  // code for the class including allocation and garbage collection routines,
407  // casts and predicates.  All you need to define is the class, methods and
408  // object verification routines.  Easy, no?
409  //
410  // Note that for subtle reasons related to the ordering or numerical values of
411  // type tags, elements in this list have to be added to the INSTANCE_TYPE_LIST
412  // manually.
413  #define STRUCT_LIST_ALL(V)                                                     \
414    V(ACCESSOR_INFO, AccessorInfo, accessor_info)                                \
415    V(ACCESS_CHECK_INFO, AccessCheckInfo, access_check_info)                     \
416    V(INTERCEPTOR_INFO, InterceptorInfo, interceptor_info)                       \
417    V(CALL_HANDLER_INFO, CallHandlerInfo, call_handler_info)                     \
418    V(FUNCTION_TEMPLATE_INFO, FunctionTemplateInfo, function_template_info)      \
419    V(OBJECT_TEMPLATE_INFO, ObjectTemplateInfo, object_template_info)            \
420    V(SIGNATURE_INFO, SignatureInfo, signature_info)                             \
421    V(TYPE_SWITCH_INFO, TypeSwitchInfo, type_switch_info)                        \
422    V(SCRIPT, Script, script)                                                    \
423    V(CODE_CACHE, CodeCache, code_cache)
424  
425  #ifdef ENABLE_DEBUGGER_SUPPORT
426  #define STRUCT_LIST_DEBUGGER(V)                                                \
427    V(DEBUG_INFO, DebugInfo, debug_info)                                         \
428    V(BREAK_POINT_INFO, BreakPointInfo, break_point_info)
429  #else
430  #define STRUCT_LIST_DEBUGGER(V)
431  #endif
432  
433  #define STRUCT_LIST(V)                                                         \
434    STRUCT_LIST_ALL(V)                                                           \
435    STRUCT_LIST_DEBUGGER(V)
436  
437  // We use the full 8 bits of the instance_type field to encode heap object
438  // instance types.  The high-order bit (bit 7) is set if the object is not a
439  // string, and cleared if it is a string.
440  const uint32_t kIsNotStringMask = 0x80;
441  const uint32_t kStringTag = 0x0;
442  const uint32_t kNotStringTag = 0x80;
443  
444  // Bit 6 indicates that the object is a symbol (if set) or not (if cleared).
445  // There are not enough types that the non-string types (with bit 7 set) can
446  // have bit 6 set too.
447  const uint32_t kIsSymbolMask = 0x40;
448  const uint32_t kNotSymbolTag = 0x0;
449  const uint32_t kSymbolTag = 0x40;
450  
451  // If bit 7 is clear then bit 2 indicates whether the string consists of
452  // two-byte characters or one-byte characters.
453  const uint32_t kStringEncodingMask = 0x4;
454  const uint32_t kTwoByteStringTag = 0x0;
455  const uint32_t kAsciiStringTag = 0x4;
456  
457  // If bit 7 is clear, the low-order 2 bits indicate the representation
458  // of the string.
459  const uint32_t kStringRepresentationMask = 0x03;
460  enum StringRepresentationTag {
461    kSeqStringTag = 0x0,
462    kConsStringTag = 0x1,
463    kExternalStringTag = 0x2
464  };
465  const uint32_t kIsConsStringMask = 0x1;
466  
467  // If bit 7 is clear, then bit 3 indicates whether this two-byte
468  // string actually contains ascii data.
469  const uint32_t kAsciiDataHintMask = 0x08;
470  const uint32_t kAsciiDataHintTag = 0x08;
471  
472  
473  // A ConsString with an empty string as the right side is a candidate
474  // for being shortcut by the garbage collector unless it is a
475  // symbol. It's not common to have non-flat symbols, so we do not
476  // shortcut them thereby avoiding turning symbols into strings. See
477  // heap.cc and mark-compact.cc.
478  const uint32_t kShortcutTypeMask =
479      kIsNotStringMask |
480      kIsSymbolMask |
481      kStringRepresentationMask;
482  const uint32_t kShortcutTypeTag = kConsStringTag;
483  
484  
485  enum InstanceType {
486    // String types.
487    // FIRST_STRING_TYPE
488    SYMBOL_TYPE = kTwoByteStringTag | kSymbolTag | kSeqStringTag,
489    ASCII_SYMBOL_TYPE = kAsciiStringTag | kSymbolTag | kSeqStringTag,
490    CONS_SYMBOL_TYPE = kTwoByteStringTag | kSymbolTag | kConsStringTag,
491    CONS_ASCII_SYMBOL_TYPE = kAsciiStringTag | kSymbolTag | kConsStringTag,
492    EXTERNAL_SYMBOL_TYPE = kTwoByteStringTag | kSymbolTag | kExternalStringTag,
493    EXTERNAL_SYMBOL_WITH_ASCII_DATA_TYPE =
494        kTwoByteStringTag | kSymbolTag | kExternalStringTag | kAsciiDataHintTag,
495    EXTERNAL_ASCII_SYMBOL_TYPE =
496        kAsciiStringTag | kSymbolTag | kExternalStringTag,
497    STRING_TYPE = kTwoByteStringTag | kSeqStringTag,
498    ASCII_STRING_TYPE = kAsciiStringTag | kSeqStringTag,
499    CONS_STRING_TYPE = kTwoByteStringTag | kConsStringTag,
500    CONS_ASCII_STRING_TYPE = kAsciiStringTag | kConsStringTag,
501    EXTERNAL_STRING_TYPE = kTwoByteStringTag | kExternalStringTag,
502    EXTERNAL_STRING_WITH_ASCII_DATA_TYPE =
503        kTwoByteStringTag | kExternalStringTag | kAsciiDataHintTag,
504    // LAST_STRING_TYPE
505    EXTERNAL_ASCII_STRING_TYPE = kAsciiStringTag | kExternalStringTag,
506    PRIVATE_EXTERNAL_ASCII_STRING_TYPE = EXTERNAL_ASCII_STRING_TYPE,
507  
508    // Objects allocated in their own spaces (never in new space).
509    MAP_TYPE = kNotStringTag,  // FIRST_NONSTRING_TYPE
510    CODE_TYPE,
511    ODDBALL_TYPE,
512    JS_GLOBAL_PROPERTY_CELL_TYPE,
513  
514    // "Data", objects that cannot contain non-map-word pointers to heap
515    // objects.
516    HEAP_NUMBER_TYPE,
517    PROXY_TYPE,
518    BYTE_ARRAY_TYPE,
519    EXTERNAL_BYTE_ARRAY_TYPE,  // FIRST_EXTERNAL_ARRAY_TYPE
520    EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE,
521    EXTERNAL_SHORT_ARRAY_TYPE,
522    EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE,
523    EXTERNAL_INT_ARRAY_TYPE,
524    EXTERNAL_UNSIGNED_INT_ARRAY_TYPE,
525    EXTERNAL_FLOAT_ARRAY_TYPE,
526    EXTERNAL_PIXEL_ARRAY_TYPE,  // LAST_EXTERNAL_ARRAY_TYPE
527    FILLER_TYPE,  // LAST_DATA_TYPE
528  
529    // Structs.
530    ACCESSOR_INFO_TYPE,
531    ACCESS_CHECK_INFO_TYPE,
532    INTERCEPTOR_INFO_TYPE,
533    CALL_HANDLER_INFO_TYPE,
534    FUNCTION_TEMPLATE_INFO_TYPE,
535    OBJECT_TEMPLATE_INFO_TYPE,
536    SIGNATURE_INFO_TYPE,
537    TYPE_SWITCH_INFO_TYPE,
538    SCRIPT_TYPE,
539    CODE_CACHE_TYPE,
540    // The following two instance types are only used when ENABLE_DEBUGGER_SUPPORT
541    // is defined. However as include/v8.h contain some of the instance type
542    // constants always having them avoids them getting different numbers
543    // depending on whether ENABLE_DEBUGGER_SUPPORT is defined or not.
544    DEBUG_INFO_TYPE,
545    BREAK_POINT_INFO_TYPE,
546  
547    FIXED_ARRAY_TYPE,
548    SHARED_FUNCTION_INFO_TYPE,
549  
550    JS_MESSAGE_OBJECT_TYPE,
551  
552    JS_VALUE_TYPE,  // FIRST_JS_OBJECT_TYPE
553    JS_OBJECT_TYPE,
554    JS_CONTEXT_EXTENSION_OBJECT_TYPE,
555    JS_GLOBAL_OBJECT_TYPE,
556    JS_BUILTINS_OBJECT_TYPE,
557    JS_GLOBAL_PROXY_TYPE,
558    JS_ARRAY_TYPE,
559  
560    JS_REGEXP_TYPE,  // LAST_JS_OBJECT_TYPE, FIRST_FUNCTION_CLASS_TYPE
561  
562    JS_FUNCTION_TYPE,
563  
564    // Pseudo-types
565    FIRST_TYPE = 0x0,
566    LAST_TYPE = JS_FUNCTION_TYPE,
567    INVALID_TYPE = FIRST_TYPE - 1,
568    FIRST_NONSTRING_TYPE = MAP_TYPE,
569    FIRST_STRING_TYPE = FIRST_TYPE,
570    LAST_STRING_TYPE = FIRST_NONSTRING_TYPE - 1,
571    // Boundaries for testing for an external array.
572    FIRST_EXTERNAL_ARRAY_TYPE = EXTERNAL_BYTE_ARRAY_TYPE,
573    LAST_EXTERNAL_ARRAY_TYPE = EXTERNAL_PIXEL_ARRAY_TYPE,
574    // Boundary for promotion to old data space/old pointer space.
575    LAST_DATA_TYPE = FILLER_TYPE,
576    // Boundaries for testing the type is a JavaScript "object".  Note that
577    // function objects are not counted as objects, even though they are
578    // implemented as such; only values whose typeof is "object" are included.
579    FIRST_JS_OBJECT_TYPE = JS_VALUE_TYPE,
580    LAST_JS_OBJECT_TYPE = JS_REGEXP_TYPE,
581    // RegExp objects have [[Class]] "function" because they are callable.
582    // All types from this type and above are objects with [[Class]] "function".
583    FIRST_FUNCTION_CLASS_TYPE = JS_REGEXP_TYPE
584  };
585  
586  static const int kExternalArrayTypeCount = LAST_EXTERNAL_ARRAY_TYPE -
587      FIRST_EXTERNAL_ARRAY_TYPE + 1;
588  
589  STATIC_CHECK(JS_OBJECT_TYPE == Internals::kJSObjectType);
590  STATIC_CHECK(FIRST_NONSTRING_TYPE == Internals::kFirstNonstringType);
591  STATIC_CHECK(PROXY_TYPE == Internals::kProxyType);
592  
593  
594  enum CompareResult {
595    LESS      = -1,
596    EQUAL     =  0,
597    GREATER   =  1,
598  
599    NOT_EQUAL = GREATER
600  };
601  
602  
603  #define DECL_BOOLEAN_ACCESSORS(name)   \
604    inline bool name();                  \
605    inline void set_##name(bool value);  \
606  
607  
608  #define DECL_ACCESSORS(name, type)                                      \
609    inline type* name();                                                  \
610    inline void set_##name(type* value,                                   \
611                           WriteBarrierMode mode = UPDATE_WRITE_BARRIER); \
612  
613  
614  class StringStream;
615  class ObjectVisitor;
616  class Failure;
617  
618  struct ValueInfo : public Malloced {
ValueInfoValueInfo619    ValueInfo() : type(FIRST_TYPE), ptr(NULL), str(NULL), number(0) { }
620    InstanceType type;
621    Object* ptr;
622    const char* str;
623    double number;
624  };
625  
626  
627  // A template-ized version of the IsXXX functions.
628  template <class C> static inline bool Is(Object* obj);
629  
630  
631  class MaybeObject BASE_EMBEDDED {
632   public:
633    inline bool IsFailure();
634    inline bool IsRetryAfterGC();
635    inline bool IsOutOfMemory();
636    inline bool IsException();
637    INLINE(bool IsTheHole());
ToObject(Object ** obj)638    inline bool ToObject(Object** obj) {
639      if (IsFailure()) return false;
640      *obj = reinterpret_cast<Object*>(this);
641      return true;
642    }
ToFailureUnchecked()643    inline Failure* ToFailureUnchecked() {
644      ASSERT(IsFailure());
645      return reinterpret_cast<Failure*>(this);
646    }
ToObjectUnchecked()647    inline Object* ToObjectUnchecked() {
648      ASSERT(!IsFailure());
649      return reinterpret_cast<Object*>(this);
650    }
ToObjectChecked()651    inline Object* ToObjectChecked() {
652      CHECK(!IsFailure());
653      return reinterpret_cast<Object*>(this);
654    }
655  
656    template<typename T>
To(T ** obj)657    inline bool To(T** obj) {
658      if (IsFailure()) return false;
659      *obj = T::cast(reinterpret_cast<Object*>(this));
660      return true;
661    }
662  
663  #ifdef OBJECT_PRINT
664    // Prints this object with details.
Print()665    inline void Print() {
666      Print(stdout);
667    };
PrintLn()668    inline void PrintLn() {
669      PrintLn(stdout);
670    }
671    void Print(FILE* out);
672    void PrintLn(FILE* out);
673  #endif
674  #ifdef DEBUG
675    // Verifies the object.
676    void Verify();
677  #endif
678  };
679  
680  
681  #define OBJECT_TYPE_LIST(V)                    \
682    V(Smi)                                       \
683    V(HeapObject)                                \
684    V(Number)                                    \
685  
686  #define HEAP_OBJECT_TYPE_LIST(V)               \
687    V(HeapNumber)                                \
688    V(String)                                    \
689    V(Symbol)                                    \
690    V(SeqString)                                 \
691    V(ExternalString)                            \
692    V(ConsString)                                \
693    V(ExternalTwoByteString)                     \
694    V(ExternalAsciiString)                       \
695    V(SeqTwoByteString)                          \
696    V(SeqAsciiString)                            \
697                                                 \
698    V(ExternalArray)                             \
699    V(ExternalByteArray)                         \
700    V(ExternalUnsignedByteArray)                 \
701    V(ExternalShortArray)                        \
702    V(ExternalUnsignedShortArray)                \
703    V(ExternalIntArray)                          \
704    V(ExternalUnsignedIntArray)                  \
705    V(ExternalFloatArray)                        \
706    V(ExternalPixelArray)                        \
707    V(ByteArray)                                 \
708    V(JSObject)                                  \
709    V(JSContextExtensionObject)                  \
710    V(Map)                                       \
711    V(DescriptorArray)                           \
712    V(DeoptimizationInputData)                   \
713    V(DeoptimizationOutputData)                  \
714    V(FixedArray)                                \
715    V(Context)                                   \
716    V(CatchContext)                              \
717    V(GlobalContext)                             \
718    V(JSFunction)                                \
719    V(Code)                                      \
720    V(Oddball)                                   \
721    V(SharedFunctionInfo)                        \
722    V(JSValue)                                   \
723    V(JSMessageObject)                           \
724    V(StringWrapper)                             \
725    V(Proxy)                                     \
726    V(Boolean)                                   \
727    V(JSArray)                                   \
728    V(JSRegExp)                                  \
729    V(HashTable)                                 \
730    V(Dictionary)                                \
731    V(SymbolTable)                               \
732    V(JSFunctionResultCache)                     \
733    V(NormalizedMapCache)                        \
734    V(CompilationCacheTable)                     \
735    V(CodeCacheHashTable)                        \
736    V(MapCache)                                  \
737    V(Primitive)                                 \
738    V(GlobalObject)                              \
739    V(JSGlobalObject)                            \
740    V(JSBuiltinsObject)                          \
741    V(JSGlobalProxy)                             \
742    V(UndetectableObject)                        \
743    V(AccessCheckNeeded)                         \
744    V(JSGlobalPropertyCell)                      \
745  
746  // Object is the abstract superclass for all classes in the
747  // object hierarchy.
748  // Object does not use any virtual functions to avoid the
749  // allocation of the C++ vtable.
750  // Since Smi and Failure are subclasses of Object no
751  // data members can be present in Object.
752  class Object : public MaybeObject {
753   public:
754    // Type testing.
755  #define IS_TYPE_FUNCTION_DECL(type_)  inline bool Is##type_();
756    OBJECT_TYPE_LIST(IS_TYPE_FUNCTION_DECL)
757    HEAP_OBJECT_TYPE_LIST(IS_TYPE_FUNCTION_DECL)
758  #undef IS_TYPE_FUNCTION_DECL
759  
760    // Returns true if this object is an instance of the specified
761    // function template.
762    inline bool IsInstanceOf(FunctionTemplateInfo* type);
763  
764    inline bool IsStruct();
765  #define DECLARE_STRUCT_PREDICATE(NAME, Name, name) inline bool Is##Name();
766    STRUCT_LIST(DECLARE_STRUCT_PREDICATE)
767  #undef DECLARE_STRUCT_PREDICATE
768  
769    // Oddball testing.
770    INLINE(bool IsUndefined());
771    INLINE(bool IsNull());
772    INLINE(bool IsTheHole());  // Shadows MaybeObject's implementation.
773    INLINE(bool IsTrue());
774    INLINE(bool IsFalse());
775    inline bool IsArgumentsMarker();
776  
777    // Extract the number.
778    inline double Number();
779  
780    inline bool HasSpecificClassOf(String* name);
781  
782    MUST_USE_RESULT MaybeObject* ToObject();             // ECMA-262 9.9.
783    Object* ToBoolean();                                 // ECMA-262 9.2.
784  
785    // Convert to a JSObject if needed.
786    // global_context is used when creating wrapper object.
787    MUST_USE_RESULT MaybeObject* ToObject(Context* global_context);
788  
789    // Converts this to a Smi if possible.
790    // Failure is returned otherwise.
791    MUST_USE_RESULT inline MaybeObject* ToSmi();
792  
793    void Lookup(String* name, LookupResult* result);
794  
795    // Property access.
796    MUST_USE_RESULT inline MaybeObject* GetProperty(String* key);
797    MUST_USE_RESULT inline MaybeObject* GetProperty(
798        String* key,
799        PropertyAttributes* attributes);
800    MUST_USE_RESULT MaybeObject* GetPropertyWithReceiver(
801        Object* receiver,
802        String* key,
803        PropertyAttributes* attributes);
804    MUST_USE_RESULT MaybeObject* GetProperty(Object* receiver,
805                                             LookupResult* result,
806                                             String* key,
807                                             PropertyAttributes* attributes);
808    MUST_USE_RESULT MaybeObject* GetPropertyWithCallback(Object* receiver,
809                                                         Object* structure,
810                                                         String* name,
811                                                         Object* holder);
812    MUST_USE_RESULT MaybeObject* GetPropertyWithDefinedGetter(Object* receiver,
813                                                              JSFunction* getter);
814  
815    inline MaybeObject* GetElement(uint32_t index);
816    // For use when we know that no exception can be thrown.
817    inline Object* GetElementNoExceptionThrown(uint32_t index);
818    MaybeObject* GetElementWithReceiver(Object* receiver, uint32_t index);
819  
820    // Return the object's prototype (might be Heap::null_value()).
821    Object* GetPrototype();
822  
823    // Tries to convert an object to an array index.  Returns true and sets
824    // the output parameter if it succeeds.
825    inline bool ToArrayIndex(uint32_t* index);
826  
827    // Returns true if this is a JSValue containing a string and the index is
828    // < the length of the string.  Used to implement [] on strings.
829    inline bool IsStringObjectWithCharacterAt(uint32_t index);
830  
831  #ifdef DEBUG
832    // Verify a pointer is a valid object pointer.
833    static void VerifyPointer(Object* p);
834  #endif
835  
836    // Prints this object without details.
ShortPrint()837    inline void ShortPrint() {
838      ShortPrint(stdout);
839    }
840    void ShortPrint(FILE* out);
841  
842    // Prints this object without details to a message accumulator.
843    void ShortPrint(StringStream* accumulator);
844  
845    // Casting: This cast is only needed to satisfy macros in objects-inl.h.
cast(Object * value)846    static Object* cast(Object* value) { return value; }
847  
848    // Layout description.
849    static const int kHeaderSize = 0;  // Object does not take up any space.
850  
851   private:
852    DISALLOW_IMPLICIT_CONSTRUCTORS(Object);
853  };
854  
855  
856  // Smi represents integer Numbers that can be stored in 31 bits.
857  // Smis are immediate which means they are NOT allocated in the heap.
858  // The this pointer has the following format: [31 bit signed int] 0
859  // For long smis it has the following format:
860  //     [32 bit signed int] [31 bits zero padding] 0
861  // Smi stands for small integer.
862  class Smi: public Object {
863   public:
864    // Returns the integer value.
865    inline int value();
866  
867    // Convert a value to a Smi object.
868    static inline Smi* FromInt(int value);
869  
870    static inline Smi* FromIntptr(intptr_t value);
871  
872    // Returns whether value can be represented in a Smi.
873    static inline bool IsValid(intptr_t value);
874  
875    // Casting.
876    static inline Smi* cast(Object* object);
877  
878    // Dispatched behavior.
SmiPrint()879    inline void SmiPrint() {
880      SmiPrint(stdout);
881    }
882    void SmiPrint(FILE* out);
883    void SmiPrint(StringStream* accumulator);
884  #ifdef DEBUG
885    void SmiVerify();
886  #endif
887  
888    static const int kMinValue = (-1 << (kSmiValueSize - 1));
889    static const int kMaxValue = -(kMinValue + 1);
890  
891   private:
892    DISALLOW_IMPLICIT_CONSTRUCTORS(Smi);
893  };
894  
895  
896  // Failure is used for reporting out of memory situations and
897  // propagating exceptions through the runtime system.  Failure objects
898  // are transient and cannot occur as part of the object graph.
899  //
900  // Failures are a single word, encoded as follows:
901  // +-------------------------+---+--+--+
902  // |.........unused..........|sss|tt|11|
903  // +-------------------------+---+--+--+
904  //                          7 6 4 32 10
905  //
906  //
907  // The low two bits, 0-1, are the failure tag, 11.  The next two bits,
908  // 2-3, are a failure type tag 'tt' with possible values:
909  //   00 RETRY_AFTER_GC
910  //   01 EXCEPTION
911  //   10 INTERNAL_ERROR
912  //   11 OUT_OF_MEMORY_EXCEPTION
913  //
914  // The next three bits, 4-6, are an allocation space tag 'sss'.  The
915  // allocation space tag is 000 for all failure types except
916  // RETRY_AFTER_GC.  For RETRY_AFTER_GC, the possible values are the
917  // allocation spaces (the encoding is found in globals.h).
918  
919  // Failure type tag info.
920  const int kFailureTypeTagSize = 2;
921  const int kFailureTypeTagMask = (1 << kFailureTypeTagSize) - 1;
922  
923  class Failure: public MaybeObject {
924   public:
925    // RuntimeStubs assumes EXCEPTION = 1 in the compiler-generated code.
926    enum Type {
927      RETRY_AFTER_GC = 0,
928      EXCEPTION = 1,       // Returning this marker tells the real exception
929                           // is in Isolate::pending_exception.
930      INTERNAL_ERROR = 2,
931      OUT_OF_MEMORY_EXCEPTION = 3
932    };
933  
934    inline Type type() const;
935  
936    // Returns the space that needs to be collected for RetryAfterGC failures.
937    inline AllocationSpace allocation_space() const;
938  
939    inline bool IsInternalError() const;
940    inline bool IsOutOfMemoryException() const;
941  
942    static inline Failure* RetryAfterGC(AllocationSpace space);
943    static inline Failure* RetryAfterGC();  // NEW_SPACE
944    static inline Failure* Exception();
945    static inline Failure* InternalError();
946    static inline Failure* OutOfMemoryException();
947    // Casting.
948    static inline Failure* cast(MaybeObject* object);
949  
950    // Dispatched behavior.
FailurePrint()951    inline void FailurePrint() {
952      FailurePrint(stdout);
953    }
954    void FailurePrint(FILE* out);
955    void FailurePrint(StringStream* accumulator);
956  #ifdef DEBUG
957    void FailureVerify();
958  #endif
959  
960   private:
961    inline intptr_t value() const;
962    static inline Failure* Construct(Type type, intptr_t value = 0);
963  
964    DISALLOW_IMPLICIT_CONSTRUCTORS(Failure);
965  };
966  
967  
968  // Heap objects typically have a map pointer in their first word.  However,
969  // during GC other data (eg, mark bits, forwarding addresses) is sometimes
970  // encoded in the first word.  The class MapWord is an abstraction of the
971  // value in a heap object's first word.
972  class MapWord BASE_EMBEDDED {
973   public:
974    // Normal state: the map word contains a map pointer.
975  
976    // Create a map word from a map pointer.
977    static inline MapWord FromMap(Map* map);
978  
979    // View this map word as a map pointer.
980    inline Map* ToMap();
981  
982  
983    // Scavenge collection: the map word of live objects in the from space
984    // contains a forwarding address (a heap object pointer in the to space).
985  
986    // True if this map word is a forwarding address for a scavenge
987    // collection.  Only valid during a scavenge collection (specifically,
988    // when all map words are heap object pointers, ie. not during a full GC).
989    inline bool IsForwardingAddress();
990  
991    // Create a map word from a forwarding address.
992    static inline MapWord FromForwardingAddress(HeapObject* object);
993  
994    // View this map word as a forwarding address.
995    inline HeapObject* ToForwardingAddress();
996  
997    // Marking phase of full collection: the map word of live objects is
998    // marked, and may be marked as overflowed (eg, the object is live, its
999    // children have not been visited, and it does not fit in the marking
1000    // stack).
1001  
1002    // True if this map word's mark bit is set.
1003    inline bool IsMarked();
1004  
1005    // Return this map word but with its mark bit set.
1006    inline void SetMark();
1007  
1008    // Return this map word but with its mark bit cleared.
1009    inline void ClearMark();
1010  
1011    // True if this map word's overflow bit is set.
1012    inline bool IsOverflowed();
1013  
1014    // Return this map word but with its overflow bit set.
1015    inline void SetOverflow();
1016  
1017    // Return this map word but with its overflow bit cleared.
1018    inline void ClearOverflow();
1019  
1020  
1021    // Compacting phase of a full compacting collection: the map word of live
1022    // objects contains an encoding of the original map address along with the
1023    // forwarding address (represented as an offset from the first live object
1024    // in the same page as the (old) object address).
1025  
1026    // Create a map word from a map address and a forwarding address offset.
1027    static inline MapWord EncodeAddress(Address map_address, int offset);
1028  
1029    // Return the map address encoded in this map word.
1030    inline Address DecodeMapAddress(MapSpace* map_space);
1031  
1032    // Return the forwarding offset encoded in this map word.
1033    inline int DecodeOffset();
1034  
1035  
1036    // During serialization: the map word is used to hold an encoded
1037    // address, and possibly a mark bit (set and cleared with SetMark
1038    // and ClearMark).
1039  
1040    // Create a map word from an encoded address.
1041    static inline MapWord FromEncodedAddress(Address address);
1042  
1043    inline Address ToEncodedAddress();
1044  
1045    // Bits used by the marking phase of the garbage collector.
1046    //
1047    // The first word of a heap object is normally a map pointer. The last two
1048    // bits are tagged as '01' (kHeapObjectTag). We reuse the last two bits to
1049    // mark an object as live and/or overflowed:
1050    //   last bit = 0, marked as alive
1051    //   second bit = 1, overflowed
1052    // An object is only marked as overflowed when it is marked as live while
1053    // the marking stack is overflowed.
1054    static const int kMarkingBit = 0;  // marking bit
1055    static const int kMarkingMask = (1 << kMarkingBit);  // marking mask
1056    static const int kOverflowBit = 1;  // overflow bit
1057    static const int kOverflowMask = (1 << kOverflowBit);  // overflow mask
1058  
1059    // Forwarding pointers and map pointer encoding. On 32 bit all the bits are
1060    // used.
1061    // +-----------------+------------------+-----------------+
1062    // |forwarding offset|page offset of map|page index of map|
1063    // +-----------------+------------------+-----------------+
1064    //          ^                 ^                  ^
1065    //          |                 |                  |
1066    //          |                 |          kMapPageIndexBits
1067    //          |         kMapPageOffsetBits
1068    // kForwardingOffsetBits
1069    static const int kMapPageOffsetBits = kPageSizeBits - kMapAlignmentBits;
1070    static const int kForwardingOffsetBits = kPageSizeBits - kObjectAlignmentBits;
1071  #ifdef V8_HOST_ARCH_64_BIT
1072    static const int kMapPageIndexBits = 16;
1073  #else
1074    // Use all the 32-bits to encode on a 32-bit platform.
1075    static const int kMapPageIndexBits =
1076        32 - (kMapPageOffsetBits + kForwardingOffsetBits);
1077  #endif
1078  
1079    static const int kMapPageIndexShift = 0;
1080    static const int kMapPageOffsetShift =
1081        kMapPageIndexShift + kMapPageIndexBits;
1082    static const int kForwardingOffsetShift =
1083        kMapPageOffsetShift + kMapPageOffsetBits;
1084  
1085    // Bit masks covering the different parts the encoding.
1086    static const uintptr_t kMapPageIndexMask =
1087        (1 << kMapPageOffsetShift) - 1;
1088    static const uintptr_t kMapPageOffsetMask =
1089        ((1 << kForwardingOffsetShift) - 1) & ~kMapPageIndexMask;
1090    static const uintptr_t kForwardingOffsetMask =
1091        ~(kMapPageIndexMask | kMapPageOffsetMask);
1092  
1093   private:
1094    // HeapObject calls the private constructor and directly reads the value.
1095    friend class HeapObject;
1096  
MapWord(uintptr_t value)1097    explicit MapWord(uintptr_t value) : value_(value) {}
1098  
1099    uintptr_t value_;
1100  };
1101  
1102  
1103  // HeapObject is the superclass for all classes describing heap allocated
1104  // objects.
1105  class HeapObject: public Object {
1106   public:
1107    // [map]: Contains a map which contains the object's reflective
1108    // information.
1109    inline Map* map();
1110    inline void set_map(Map* value);
1111  
1112    // During garbage collection, the map word of a heap object does not
1113    // necessarily contain a map pointer.
1114    inline MapWord map_word();
1115    inline void set_map_word(MapWord map_word);
1116  
1117    // The Heap the object was allocated in. Used also to access Isolate.
1118    // This method can not be used during GC, it ASSERTs this.
1119    inline Heap* GetHeap();
1120    // Convenience method to get current isolate. This method can be
1121    // accessed only when its result is the same as
1122    // Isolate::Current(), it ASSERTs this. See also comment for GetHeap.
1123    inline Isolate* GetIsolate();
1124  
1125    // Converts an address to a HeapObject pointer.
1126    static inline HeapObject* FromAddress(Address address);
1127  
1128    // Returns the address of this HeapObject.
1129    inline Address address();
1130  
1131    // Iterates over pointers contained in the object (including the Map)
1132    void Iterate(ObjectVisitor* v);
1133  
1134    // Iterates over all pointers contained in the object except the
1135    // first map pointer.  The object type is given in the first
1136    // parameter. This function does not access the map pointer in the
1137    // object, and so is safe to call while the map pointer is modified.
1138    void IterateBody(InstanceType type, int object_size, ObjectVisitor* v);
1139  
1140    // Returns the heap object's size in bytes
1141    inline int Size();
1142  
1143    // Given a heap object's map pointer, returns the heap size in bytes
1144    // Useful when the map pointer field is used for other purposes.
1145    // GC internal.
1146    inline int SizeFromMap(Map* map);
1147  
1148    // Support for the marking heap objects during the marking phase of GC.
1149    // True if the object is marked live.
1150    inline bool IsMarked();
1151  
1152    // Mutate this object's map pointer to indicate that the object is live.
1153    inline void SetMark();
1154  
1155    // Mutate this object's map pointer to remove the indication that the
1156    // object is live (ie, partially restore the map pointer).
1157    inline void ClearMark();
1158  
1159    // True if this object is marked as overflowed.  Overflowed objects have
1160    // been reached and marked during marking of the heap, but their children
1161    // have not necessarily been marked and they have not been pushed on the
1162    // marking stack.
1163    inline bool IsOverflowed();
1164  
1165    // Mutate this object's map pointer to indicate that the object is
1166    // overflowed.
1167    inline void SetOverflow();
1168  
1169    // Mutate this object's map pointer to remove the indication that the
1170    // object is overflowed (ie, partially restore the map pointer).
1171    inline void ClearOverflow();
1172  
1173    // Returns the field at offset in obj, as a read/write Object* reference.
1174    // Does no checking, and is safe to use during GC, while maps are invalid.
1175    // Does not invoke write barrier, so should only be assigned to
1176    // during marking GC.
1177    static inline Object** RawField(HeapObject* obj, int offset);
1178  
1179    // Casting.
1180    static inline HeapObject* cast(Object* obj);
1181  
1182    // Return the write barrier mode for this. Callers of this function
1183    // must be able to present a reference to an AssertNoAllocation
1184    // object as a sign that they are not going to use this function
1185    // from code that allocates and thus invalidates the returned write
1186    // barrier mode.
1187    inline WriteBarrierMode GetWriteBarrierMode(const AssertNoAllocation&);
1188  
1189    // Dispatched behavior.
1190    void HeapObjectShortPrint(StringStream* accumulator);
1191  #ifdef OBJECT_PRINT
HeapObjectPrint()1192    inline void HeapObjectPrint() {
1193      HeapObjectPrint(stdout);
1194    }
1195    void HeapObjectPrint(FILE* out);
1196  #endif
1197  #ifdef DEBUG
1198    void HeapObjectVerify();
1199    inline void VerifyObjectField(int offset);
1200    inline void VerifySmiField(int offset);
1201  #endif
1202  
1203  #ifdef OBJECT_PRINT
1204    void PrintHeader(FILE* out, const char* id);
1205  #endif
1206  
1207  #ifdef DEBUG
1208    // Verify a pointer is a valid HeapObject pointer that points to object
1209    // areas in the heap.
1210    static void VerifyHeapPointer(Object* p);
1211  #endif
1212  
1213    // Layout description.
1214    // First field in a heap object is map.
1215    static const int kMapOffset = Object::kHeaderSize;
1216    static const int kHeaderSize = kMapOffset + kPointerSize;
1217  
1218    STATIC_CHECK(kMapOffset == Internals::kHeapObjectMapOffset);
1219  
1220   protected:
1221    // helpers for calling an ObjectVisitor to iterate over pointers in the
1222    // half-open range [start, end) specified as integer offsets
1223    inline void IteratePointers(ObjectVisitor* v, int start, int end);
1224    // as above, for the single element at "offset"
1225    inline void IteratePointer(ObjectVisitor* v, int offset);
1226  
1227   private:
1228    DISALLOW_IMPLICIT_CONSTRUCTORS(HeapObject);
1229  };
1230  
1231  
1232  #define SLOT_ADDR(obj, offset) \
1233    reinterpret_cast<Object**>((obj)->address() + offset)
1234  
1235  // This class describes a body of an object of a fixed size
1236  // in which all pointer fields are located in the [start_offset, end_offset)
1237  // interval.
1238  template<int start_offset, int end_offset, int size>
1239  class FixedBodyDescriptor {
1240   public:
1241    static const int kStartOffset = start_offset;
1242    static const int kEndOffset = end_offset;
1243    static const int kSize = size;
1244  
1245    static inline void IterateBody(HeapObject* obj, ObjectVisitor* v);
1246  
1247    template<typename StaticVisitor>
IterateBody(HeapObject * obj)1248    static inline void IterateBody(HeapObject* obj) {
1249      StaticVisitor::VisitPointers(SLOT_ADDR(obj, start_offset),
1250                                   SLOT_ADDR(obj, end_offset));
1251    }
1252  };
1253  
1254  
1255  // This class describes a body of an object of a variable size
1256  // in which all pointer fields are located in the [start_offset, object_size)
1257  // interval.
1258  template<int start_offset>
1259  class FlexibleBodyDescriptor {
1260   public:
1261    static const int kStartOffset = start_offset;
1262  
1263    static inline void IterateBody(HeapObject* obj,
1264                                   int object_size,
1265                                   ObjectVisitor* v);
1266  
1267    template<typename StaticVisitor>
IterateBody(HeapObject * obj,int object_size)1268    static inline void IterateBody(HeapObject* obj, int object_size) {
1269      StaticVisitor::VisitPointers(SLOT_ADDR(obj, start_offset),
1270                                   SLOT_ADDR(obj, object_size));
1271    }
1272  };
1273  
1274  #undef SLOT_ADDR
1275  
1276  
1277  // The HeapNumber class describes heap allocated numbers that cannot be
1278  // represented in a Smi (small integer)
1279  class HeapNumber: public HeapObject {
1280   public:
1281    // [value]: number value.
1282    inline double value();
1283    inline void set_value(double value);
1284  
1285    // Casting.
1286    static inline HeapNumber* cast(Object* obj);
1287  
1288    // Dispatched behavior.
1289    Object* HeapNumberToBoolean();
HeapNumberPrint()1290    inline void HeapNumberPrint() {
1291      HeapNumberPrint(stdout);
1292    }
1293    void HeapNumberPrint(FILE* out);
1294    void HeapNumberPrint(StringStream* accumulator);
1295  #ifdef DEBUG
1296    void HeapNumberVerify();
1297  #endif
1298  
1299    inline int get_exponent();
1300    inline int get_sign();
1301  
1302    // Layout description.
1303    static const int kValueOffset = HeapObject::kHeaderSize;
1304    // IEEE doubles are two 32 bit words.  The first is just mantissa, the second
1305    // is a mixture of sign, exponent and mantissa.  Our current platforms are all
1306    // little endian apart from non-EABI arm which is little endian with big
1307    // endian floating point word ordering!
1308    static const int kMantissaOffset = kValueOffset;
1309    static const int kExponentOffset = kValueOffset + 4;
1310  
1311    static const int kSize = kValueOffset + kDoubleSize;
1312    static const uint32_t kSignMask = 0x80000000u;
1313    static const uint32_t kExponentMask = 0x7ff00000u;
1314    static const uint32_t kMantissaMask = 0xfffffu;
1315    static const int kMantissaBits = 52;
1316    static const int kExponentBits = 11;
1317    static const int kExponentBias = 1023;
1318    static const int kExponentShift = 20;
1319    static const int kMantissaBitsInTopWord = 20;
1320    static const int kNonMantissaBitsInTopWord = 12;
1321  
1322   private:
1323    DISALLOW_IMPLICIT_CONSTRUCTORS(HeapNumber);
1324  };
1325  
1326  
1327  // The JSObject describes real heap allocated JavaScript objects with
1328  // properties.
1329  // Note that the map of JSObject changes during execution to enable inline
1330  // caching.
1331  class JSObject: public HeapObject {
1332   public:
1333    enum DeleteMode {
1334      NORMAL_DELETION,
1335      STRICT_DELETION,
1336      FORCE_DELETION
1337    };
1338  
1339    enum ElementsKind {
1340      // The only "fast" kind.
1341      FAST_ELEMENTS,
1342      // All the kinds below are "slow".
1343      DICTIONARY_ELEMENTS,
1344      EXTERNAL_BYTE_ELEMENTS,
1345      EXTERNAL_UNSIGNED_BYTE_ELEMENTS,
1346      EXTERNAL_SHORT_ELEMENTS,
1347      EXTERNAL_UNSIGNED_SHORT_ELEMENTS,
1348      EXTERNAL_INT_ELEMENTS,
1349      EXTERNAL_UNSIGNED_INT_ELEMENTS,
1350      EXTERNAL_FLOAT_ELEMENTS,
1351      EXTERNAL_PIXEL_ELEMENTS
1352    };
1353  
1354    // [properties]: Backing storage for properties.
1355    // properties is a FixedArray in the fast case and a Dictionary in the
1356    // slow case.
1357    DECL_ACCESSORS(properties, FixedArray)  // Get and set fast properties.
1358    inline void initialize_properties();
1359    inline bool HasFastProperties();
1360    inline StringDictionary* property_dictionary();  // Gets slow properties.
1361  
1362    // [elements]: The elements (properties with names that are integers).
1363    //
1364    // Elements can be in two general modes: fast and slow. Each mode
1365    // corrensponds to a set of object representations of elements that
1366    // have something in common.
1367    //
1368    // In the fast mode elements is a FixedArray and so each element can
1369    // be quickly accessed. This fact is used in the generated code. The
1370    // elements array can have one of the two maps in this mode:
1371    // fixed_array_map or fixed_cow_array_map (for copy-on-write
1372    // arrays). In the latter case the elements array may be shared by a
1373    // few objects and so before writing to any element the array must
1374    // be copied. Use EnsureWritableFastElements in this case.
1375    //
1376    // In the slow mode elements is either a NumberDictionary or an ExternalArray.
1377    DECL_ACCESSORS(elements, HeapObject)
1378    inline void initialize_elements();
1379    MUST_USE_RESULT inline MaybeObject* ResetElements();
1380    inline ElementsKind GetElementsKind();
1381    inline bool HasFastElements();
1382    inline bool HasDictionaryElements();
1383    inline bool HasExternalPixelElements();
1384    inline bool HasExternalArrayElements();
1385    inline bool HasExternalByteElements();
1386    inline bool HasExternalUnsignedByteElements();
1387    inline bool HasExternalShortElements();
1388    inline bool HasExternalUnsignedShortElements();
1389    inline bool HasExternalIntElements();
1390    inline bool HasExternalUnsignedIntElements();
1391    inline bool HasExternalFloatElements();
1392    inline bool AllowsSetElementsLength();
1393    inline NumberDictionary* element_dictionary();  // Gets slow elements.
1394    // Requires: this->HasFastElements().
1395    MUST_USE_RESULT inline MaybeObject* EnsureWritableFastElements();
1396  
1397    // Collects elements starting at index 0.
1398    // Undefined values are placed after non-undefined values.
1399    // Returns the number of non-undefined values.
1400    MUST_USE_RESULT MaybeObject* PrepareElementsForSort(uint32_t limit);
1401    // As PrepareElementsForSort, but only on objects where elements is
1402    // a dictionary, and it will stay a dictionary.
1403    MUST_USE_RESULT MaybeObject* PrepareSlowElementsForSort(uint32_t limit);
1404  
1405    MUST_USE_RESULT MaybeObject* SetProperty(String* key,
1406                                             Object* value,
1407                                             PropertyAttributes attributes,
1408                                             StrictModeFlag strict_mode);
1409    MUST_USE_RESULT MaybeObject* SetProperty(LookupResult* result,
1410                                             String* key,
1411                                             Object* value,
1412                                             PropertyAttributes attributes,
1413                                             StrictModeFlag strict_mode);
1414    MUST_USE_RESULT MaybeObject* SetPropertyWithFailedAccessCheck(
1415        LookupResult* result,
1416        String* name,
1417        Object* value,
1418        bool check_prototype);
1419    MUST_USE_RESULT MaybeObject* SetPropertyWithCallback(Object* structure,
1420                                                         String* name,
1421                                                         Object* value,
1422                                                         JSObject* holder);
1423    MUST_USE_RESULT MaybeObject* SetPropertyWithDefinedSetter(JSFunction* setter,
1424                                                              Object* value);
1425    MUST_USE_RESULT MaybeObject* SetPropertyWithInterceptor(
1426        String* name,
1427        Object* value,
1428        PropertyAttributes attributes,
1429        StrictModeFlag strict_mode);
1430    MUST_USE_RESULT MaybeObject* SetPropertyPostInterceptor(
1431        String* name,
1432        Object* value,
1433        PropertyAttributes attributes,
1434        StrictModeFlag strict_mode);
1435    MUST_USE_RESULT MaybeObject* SetLocalPropertyIgnoreAttributes(
1436        String* key,
1437        Object* value,
1438        PropertyAttributes attributes);
1439  
1440    // Retrieve a value in a normalized object given a lookup result.
1441    // Handles the special representation of JS global objects.
1442    Object* GetNormalizedProperty(LookupResult* result);
1443  
1444    // Sets the property value in a normalized object given a lookup result.
1445    // Handles the special representation of JS global objects.
1446    Object* SetNormalizedProperty(LookupResult* result, Object* value);
1447  
1448    // Sets the property value in a normalized object given (key, value, details).
1449    // Handles the special representation of JS global objects.
1450    MUST_USE_RESULT MaybeObject* SetNormalizedProperty(String* name,
1451                                                       Object* value,
1452                                                       PropertyDetails details);
1453  
1454    // Deletes the named property in a normalized object.
1455    MUST_USE_RESULT MaybeObject* DeleteNormalizedProperty(String* name,
1456                                                          DeleteMode mode);
1457  
1458    // Returns the class name ([[Class]] property in the specification).
1459    String* class_name();
1460  
1461    // Returns the constructor name (the name (possibly, inferred name) of the
1462    // function that was used to instantiate the object).
1463    String* constructor_name();
1464  
1465    // Retrieve interceptors.
1466    InterceptorInfo* GetNamedInterceptor();
1467    InterceptorInfo* GetIndexedInterceptor();
1468  
1469    inline PropertyAttributes GetPropertyAttribute(String* name);
1470    PropertyAttributes GetPropertyAttributeWithReceiver(JSObject* receiver,
1471                                                        String* name);
1472    PropertyAttributes GetLocalPropertyAttribute(String* name);
1473  
1474    MUST_USE_RESULT MaybeObject* DefineAccessor(String* name,
1475                                                bool is_getter,
1476                                                Object* fun,
1477                                                PropertyAttributes attributes);
1478    Object* LookupAccessor(String* name, bool is_getter);
1479  
1480    MUST_USE_RESULT MaybeObject* DefineAccessor(AccessorInfo* info);
1481  
1482    // Used from Object::GetProperty().
1483    MaybeObject* GetPropertyWithFailedAccessCheck(
1484        Object* receiver,
1485        LookupResult* result,
1486        String* name,
1487        PropertyAttributes* attributes);
1488    MaybeObject* GetPropertyWithInterceptor(
1489        JSObject* receiver,
1490        String* name,
1491        PropertyAttributes* attributes);
1492    MaybeObject* GetPropertyPostInterceptor(
1493        JSObject* receiver,
1494        String* name,
1495        PropertyAttributes* attributes);
1496    MaybeObject* GetLocalPropertyPostInterceptor(JSObject* receiver,
1497                                                 String* name,
1498                                                 PropertyAttributes* attributes);
1499  
1500    // Returns true if this is an instance of an api function and has
1501    // been modified since it was created.  May give false positives.
1502    bool IsDirty();
1503  
HasProperty(String * name)1504    bool HasProperty(String* name) {
1505      return GetPropertyAttribute(name) != ABSENT;
1506    }
1507  
1508    // Can cause a GC if it hits an interceptor.
HasLocalProperty(String * name)1509    bool HasLocalProperty(String* name) {
1510      return GetLocalPropertyAttribute(name) != ABSENT;
1511    }
1512  
1513    // If the receiver is a JSGlobalProxy this method will return its prototype,
1514    // otherwise the result is the receiver itself.
1515    inline Object* BypassGlobalProxy();
1516  
1517    // Accessors for hidden properties object.
1518    //
1519    // Hidden properties are not local properties of the object itself.
1520    // Instead they are stored on an auxiliary JSObject stored as a local
1521    // property with a special name Heap::hidden_symbol(). But if the
1522    // receiver is a JSGlobalProxy then the auxiliary object is a property
1523    // of its prototype.
1524    //
1525    // Has/Get/SetHiddenPropertiesObject methods don't allow the holder to be
1526    // a JSGlobalProxy. Use BypassGlobalProxy method above to get to the real
1527    // holder.
1528    //
1529    // These accessors do not touch interceptors or accessors.
1530    inline bool HasHiddenPropertiesObject();
1531    inline Object* GetHiddenPropertiesObject();
1532    MUST_USE_RESULT inline MaybeObject* SetHiddenPropertiesObject(
1533        Object* hidden_obj);
1534  
1535    MUST_USE_RESULT MaybeObject* DeleteProperty(String* name, DeleteMode mode);
1536    MUST_USE_RESULT MaybeObject* DeleteElement(uint32_t index, DeleteMode mode);
1537  
1538    // Tests for the fast common case for property enumeration.
1539    bool IsSimpleEnum();
1540  
1541    // Do we want to keep the elements in fast case when increasing the
1542    // capacity?
1543    bool ShouldConvertToSlowElements(int new_capacity);
1544    // Returns true if the backing storage for the slow-case elements of
1545    // this object takes up nearly as much space as a fast-case backing
1546    // storage would.  In that case the JSObject should have fast
1547    // elements.
1548    bool ShouldConvertToFastElements();
1549  
1550    // Return the object's prototype (might be Heap::null_value()).
1551    inline Object* GetPrototype();
1552  
1553    // Set the object's prototype (only JSObject and null are allowed).
1554    MUST_USE_RESULT MaybeObject* SetPrototype(Object* value,
1555                                              bool skip_hidden_prototypes);
1556  
1557    // Tells whether the index'th element is present.
1558    inline bool HasElement(uint32_t index);
1559    bool HasElementWithReceiver(JSObject* receiver, uint32_t index);
1560  
1561    // Computes the new capacity when expanding the elements of a JSObject.
NewElementsCapacity(int old_capacity)1562    static int NewElementsCapacity(int old_capacity) {
1563      // (old_capacity + 50%) + 16
1564      return old_capacity + (old_capacity >> 1) + 16;
1565    }
1566  
1567    // Tells whether the index'th element is present and how it is stored.
1568    enum LocalElementType {
1569      // There is no element with given index.
1570      UNDEFINED_ELEMENT,
1571  
1572      // Element with given index is handled by interceptor.
1573      INTERCEPTED_ELEMENT,
1574  
1575      // Element with given index is character in string.
1576      STRING_CHARACTER_ELEMENT,
1577  
1578      // Element with given index is stored in fast backing store.
1579      FAST_ELEMENT,
1580  
1581      // Element with given index is stored in slow backing store.
1582      DICTIONARY_ELEMENT
1583    };
1584  
1585    LocalElementType HasLocalElement(uint32_t index);
1586  
1587    bool HasElementWithInterceptor(JSObject* receiver, uint32_t index);
1588    bool HasElementPostInterceptor(JSObject* receiver, uint32_t index);
1589  
1590    MUST_USE_RESULT MaybeObject* SetFastElement(uint32_t index,
1591                                                Object* value,
1592                                                StrictModeFlag strict_mode,
1593                                                bool check_prototype = true);
1594  
1595    // Set the index'th array element.
1596    // A Failure object is returned if GC is needed.
1597    MUST_USE_RESULT MaybeObject* SetElement(uint32_t index,
1598                                            Object* value,
1599                                            StrictModeFlag strict_mode,
1600                                            bool check_prototype = true);
1601  
1602    // Returns the index'th element.
1603    // The undefined object if index is out of bounds.
1604    MaybeObject* GetElementWithReceiver(Object* receiver, uint32_t index);
1605    MaybeObject* GetElementWithInterceptor(Object* receiver, uint32_t index);
1606  
1607    // Get external element value at index if there is one and undefined
1608    // otherwise. Can return a failure if allocation of a heap number
1609    // failed.
1610    MaybeObject* GetExternalElement(uint32_t index);
1611  
1612    MUST_USE_RESULT MaybeObject* SetFastElementsCapacityAndLength(int capacity,
1613                                                                  int length);
1614    MUST_USE_RESULT MaybeObject* SetSlowElements(Object* length);
1615  
1616    // Lookup interceptors are used for handling properties controlled by host
1617    // objects.
1618    inline bool HasNamedInterceptor();
1619    inline bool HasIndexedInterceptor();
1620  
1621    // Support functions for v8 api (needed for correct interceptor behavior).
1622    bool HasRealNamedProperty(String* key);
1623    bool HasRealElementProperty(uint32_t index);
1624    bool HasRealNamedCallbackProperty(String* key);
1625  
1626    // Initializes the array to a certain length
1627    MUST_USE_RESULT MaybeObject* SetElementsLength(Object* length);
1628  
1629    // Get the header size for a JSObject.  Used to compute the index of
1630    // internal fields as well as the number of internal fields.
1631    inline int GetHeaderSize();
1632  
1633    inline int GetInternalFieldCount();
1634    inline int GetInternalFieldOffset(int index);
1635    inline Object* GetInternalField(int index);
1636    inline void SetInternalField(int index, Object* value);
1637  
1638    // Lookup a property.  If found, the result is valid and has
1639    // detailed information.
1640    void LocalLookup(String* name, LookupResult* result);
1641    void Lookup(String* name, LookupResult* result);
1642  
1643    // The following lookup functions skip interceptors.
1644    void LocalLookupRealNamedProperty(String* name, LookupResult* result);
1645    void LookupRealNamedProperty(String* name, LookupResult* result);
1646    void LookupRealNamedPropertyInPrototypes(String* name, LookupResult* result);
1647    void LookupCallbackSetterInPrototypes(String* name, LookupResult* result);
1648    MUST_USE_RESULT MaybeObject* SetElementWithCallbackSetterInPrototypes(
1649        uint32_t index, Object* value, bool* found);
1650    void LookupCallback(String* name, LookupResult* result);
1651  
1652    // Returns the number of properties on this object filtering out properties
1653    // with the specified attributes (ignoring interceptors).
1654    int NumberOfLocalProperties(PropertyAttributes filter);
1655    // Returns the number of enumerable properties (ignoring interceptors).
1656    int NumberOfEnumProperties();
1657    // Fill in details for properties into storage starting at the specified
1658    // index.
1659    void GetLocalPropertyNames(FixedArray* storage, int index);
1660  
1661    // Returns the number of properties on this object filtering out properties
1662    // with the specified attributes (ignoring interceptors).
1663    int NumberOfLocalElements(PropertyAttributes filter);
1664    // Returns the number of enumerable elements (ignoring interceptors).
1665    int NumberOfEnumElements();
1666    // Returns the number of elements on this object filtering out elements
1667    // with the specified attributes (ignoring interceptors).
1668    int GetLocalElementKeys(FixedArray* storage, PropertyAttributes filter);
1669    // Count and fill in the enumerable elements into storage.
1670    // (storage->length() == NumberOfEnumElements()).
1671    // If storage is NULL, will count the elements without adding
1672    // them to any storage.
1673    // Returns the number of enumerable elements.
1674    int GetEnumElementKeys(FixedArray* storage);
1675  
1676    // Add a property to a fast-case object using a map transition to
1677    // new_map.
1678    MUST_USE_RESULT MaybeObject* AddFastPropertyUsingMap(Map* new_map,
1679                                                         String* name,
1680                                                         Object* value);
1681  
1682    // Add a constant function property to a fast-case object.
1683    // This leaves a CONSTANT_TRANSITION in the old map, and
1684    // if it is called on a second object with this map, a
1685    // normal property is added instead, with a map transition.
1686    // This avoids the creation of many maps with the same constant
1687    // function, all orphaned.
1688    MUST_USE_RESULT MaybeObject* AddConstantFunctionProperty(
1689        String* name,
1690        JSFunction* function,
1691        PropertyAttributes attributes);
1692  
1693    MUST_USE_RESULT MaybeObject* ReplaceSlowProperty(
1694        String* name,
1695        Object* value,
1696        PropertyAttributes attributes);
1697  
1698    // Converts a descriptor of any other type to a real field,
1699    // backed by the properties array.  Descriptors of visible
1700    // types, such as CONSTANT_FUNCTION, keep their enumeration order.
1701    // Converts the descriptor on the original object's map to a
1702    // map transition, and the the new field is on the object's new map.
1703    MUST_USE_RESULT MaybeObject* ConvertDescriptorToFieldAndMapTransition(
1704        String* name,
1705        Object* new_value,
1706        PropertyAttributes attributes);
1707  
1708    // Converts a descriptor of any other type to a real field,
1709    // backed by the properties array.  Descriptors of visible
1710    // types, such as CONSTANT_FUNCTION, keep their enumeration order.
1711    MUST_USE_RESULT MaybeObject* ConvertDescriptorToField(
1712        String* name,
1713        Object* new_value,
1714        PropertyAttributes attributes);
1715  
1716    // Add a property to a fast-case object.
1717    MUST_USE_RESULT MaybeObject* AddFastProperty(String* name,
1718                                                 Object* value,
1719                                                 PropertyAttributes attributes);
1720  
1721    // Add a property to a slow-case object.
1722    MUST_USE_RESULT MaybeObject* AddSlowProperty(String* name,
1723                                                 Object* value,
1724                                                 PropertyAttributes attributes);
1725  
1726    // Add a property to an object.
1727    MUST_USE_RESULT MaybeObject* AddProperty(String* name,
1728                                             Object* value,
1729                                             PropertyAttributes attributes,
1730                                             StrictModeFlag strict_mode);
1731  
1732    // Convert the object to use the canonical dictionary
1733    // representation. If the object is expected to have additional properties
1734    // added this number can be indicated to have the backing store allocated to
1735    // an initial capacity for holding these properties.
1736    MUST_USE_RESULT MaybeObject* NormalizeProperties(
1737        PropertyNormalizationMode mode,
1738        int expected_additional_properties);
1739    MUST_USE_RESULT MaybeObject* NormalizeElements();
1740  
1741    MUST_USE_RESULT MaybeObject* UpdateMapCodeCache(String* name, Code* code);
1742  
1743    // Transform slow named properties to fast variants.
1744    // Returns failure if allocation failed.
1745    MUST_USE_RESULT MaybeObject* TransformToFastProperties(
1746        int unused_property_fields);
1747  
1748    // Access fast-case object properties at index.
1749    inline Object* FastPropertyAt(int index);
1750    inline Object* FastPropertyAtPut(int index, Object* value);
1751  
1752    // Access to in object properties.
1753    inline int GetInObjectPropertyOffset(int index);
1754    inline Object* InObjectPropertyAt(int index);
1755    inline Object* InObjectPropertyAtPut(int index,
1756                                         Object* value,
1757                                         WriteBarrierMode mode
1758                                         = UPDATE_WRITE_BARRIER);
1759  
1760    // initializes the body after properties slot, properties slot is
1761    // initialized by set_properties
1762    // Note: this call does not update write barrier, it is caller's
1763    // reponsibility to ensure that *v* can be collected without WB here.
1764    inline void InitializeBody(int object_size, Object* value);
1765  
1766    // Check whether this object references another object
1767    bool ReferencesObject(Object* obj);
1768  
1769    // Casting.
1770    static inline JSObject* cast(Object* obj);
1771  
1772    // Disalow further properties to be added to the object.
1773    MUST_USE_RESULT MaybeObject* PreventExtensions();
1774  
1775  
1776    // Dispatched behavior.
1777    void JSObjectShortPrint(StringStream* accumulator);
1778  #ifdef OBJECT_PRINT
JSObjectPrint()1779    inline void JSObjectPrint() {
1780      JSObjectPrint(stdout);
1781    }
1782    void JSObjectPrint(FILE* out);
1783  #endif
1784  #ifdef DEBUG
1785    void JSObjectVerify();
1786  #endif
1787  #ifdef OBJECT_PRINT
PrintProperties()1788    inline void PrintProperties() {
1789      PrintProperties(stdout);
1790    }
1791    void PrintProperties(FILE* out);
1792  
PrintElements()1793    inline void PrintElements() {
1794      PrintElements(stdout);
1795    }
1796    void PrintElements(FILE* out);
1797  #endif
1798  
1799  #ifdef DEBUG
1800    // Structure for collecting spill information about JSObjects.
1801    class SpillInformation {
1802     public:
1803      void Clear();
1804      void Print();
1805      int number_of_objects_;
1806      int number_of_objects_with_fast_properties_;
1807      int number_of_objects_with_fast_elements_;
1808      int number_of_fast_used_fields_;
1809      int number_of_fast_unused_fields_;
1810      int number_of_slow_used_properties_;
1811      int number_of_slow_unused_properties_;
1812      int number_of_fast_used_elements_;
1813      int number_of_fast_unused_elements_;
1814      int number_of_slow_used_elements_;
1815      int number_of_slow_unused_elements_;
1816    };
1817  
1818    void IncrementSpillStatistics(SpillInformation* info);
1819  #endif
1820    Object* SlowReverseLookup(Object* value);
1821  
1822    // Maximal number of fast properties for the JSObject. Used to
1823    // restrict the number of map transitions to avoid an explosion in
1824    // the number of maps for objects used as dictionaries.
1825    inline int MaxFastProperties();
1826  
1827    // Maximal number of elements (numbered 0 .. kMaxElementCount - 1).
1828    // Also maximal value of JSArray's length property.
1829    static const uint32_t kMaxElementCount = 0xffffffffu;
1830  
1831    static const uint32_t kMaxGap = 1024;
1832    static const int kMaxFastElementsLength = 5000;
1833    static const int kInitialMaxFastElementArray = 100000;
1834    static const int kMaxFastProperties = 12;
1835    static const int kMaxInstanceSize = 255 * kPointerSize;
1836    // When extending the backing storage for property values, we increase
1837    // its size by more than the 1 entry necessary, so sequentially adding fields
1838    // to the same object requires fewer allocations and copies.
1839    static const int kFieldsAdded = 3;
1840  
1841    // Layout description.
1842    static const int kPropertiesOffset = HeapObject::kHeaderSize;
1843    static const int kElementsOffset = kPropertiesOffset + kPointerSize;
1844    static const int kHeaderSize = kElementsOffset + kPointerSize;
1845  
1846    STATIC_CHECK(kHeaderSize == Internals::kJSObjectHeaderSize);
1847  
1848    class BodyDescriptor : public FlexibleBodyDescriptor<kPropertiesOffset> {
1849     public:
1850      static inline int SizeOf(Map* map, HeapObject* object);
1851    };
1852  
1853   private:
1854    MUST_USE_RESULT MaybeObject* GetElementWithCallback(Object* receiver,
1855                                                        Object* structure,
1856                                                        uint32_t index,
1857                                                        Object* holder);
1858    MaybeObject* SetElementWithCallback(Object* structure,
1859                                        uint32_t index,
1860                                        Object* value,
1861                                        JSObject* holder);
1862    MUST_USE_RESULT MaybeObject* SetElementWithInterceptor(
1863        uint32_t index,
1864        Object* value,
1865        StrictModeFlag strict_mode,
1866        bool check_prototype);
1867    MUST_USE_RESULT MaybeObject* SetElementWithoutInterceptor(
1868        uint32_t index,
1869        Object* value,
1870        StrictModeFlag strict_mode,
1871        bool check_prototype);
1872  
1873    MaybeObject* GetElementPostInterceptor(Object* receiver, uint32_t index);
1874  
1875    MUST_USE_RESULT MaybeObject* DeletePropertyPostInterceptor(String* name,
1876                                                               DeleteMode mode);
1877    MUST_USE_RESULT MaybeObject* DeletePropertyWithInterceptor(String* name);
1878  
1879    MUST_USE_RESULT MaybeObject* DeleteElementPostInterceptor(uint32_t index,
1880                                                              DeleteMode mode);
1881    MUST_USE_RESULT MaybeObject* DeleteElementWithInterceptor(uint32_t index);
1882  
1883    PropertyAttributes GetPropertyAttributePostInterceptor(JSObject* receiver,
1884                                                           String* name,
1885                                                           bool continue_search);
1886    PropertyAttributes GetPropertyAttributeWithInterceptor(JSObject* receiver,
1887                                                           String* name,
1888                                                           bool continue_search);
1889    PropertyAttributes GetPropertyAttributeWithFailedAccessCheck(
1890        Object* receiver,
1891        LookupResult* result,
1892        String* name,
1893        bool continue_search);
1894    PropertyAttributes GetPropertyAttribute(JSObject* receiver,
1895                                            LookupResult* result,
1896                                            String* name,
1897                                            bool continue_search);
1898  
1899    // Returns true if most of the elements backing storage is used.
1900    bool HasDenseElements();
1901  
1902    bool CanSetCallback(String* name);
1903    MUST_USE_RESULT MaybeObject* SetElementCallback(
1904        uint32_t index,
1905        Object* structure,
1906        PropertyAttributes attributes);
1907    MUST_USE_RESULT MaybeObject* SetPropertyCallback(
1908        String* name,
1909        Object* structure,
1910        PropertyAttributes attributes);
1911    MUST_USE_RESULT MaybeObject* DefineGetterSetter(
1912        String* name,
1913        PropertyAttributes attributes);
1914  
1915    void LookupInDescriptor(String* name, LookupResult* result);
1916  
1917    DISALLOW_IMPLICIT_CONSTRUCTORS(JSObject);
1918  };
1919  
1920  
1921  // FixedArray describes fixed-sized arrays with element type Object*.
1922  class FixedArray: public HeapObject {
1923   public:
1924    // [length]: length of the array.
1925    inline int length();
1926    inline void set_length(int value);
1927  
1928    // Setter and getter for elements.
1929    inline Object* get(int index);
1930    // Setter that uses write barrier.
1931    inline void set(int index, Object* value);
1932  
1933    // Setter that doesn't need write barrier).
1934    inline void set(int index, Smi* value);
1935    // Setter with explicit barrier mode.
1936    inline void set(int index, Object* value, WriteBarrierMode mode);
1937  
1938    // Setters for frequently used oddballs located in old space.
1939    inline void set_undefined(int index);
1940    // TODO(isolates): duplicate.
1941    inline void set_undefined(Heap* heap, int index);
1942    inline void set_null(int index);
1943    // TODO(isolates): duplicate.
1944    inline void set_null(Heap* heap, int index);
1945    inline void set_the_hole(int index);
1946  
1947    // Setters with less debug checks for the GC to use.
1948    inline void set_unchecked(int index, Smi* value);
1949    inline void set_null_unchecked(Heap* heap, int index);
1950    inline void set_unchecked(Heap* heap, int index, Object* value,
1951                              WriteBarrierMode mode);
1952  
1953    // Gives access to raw memory which stores the array's data.
1954    inline Object** data_start();
1955  
1956    // Copy operations.
1957    MUST_USE_RESULT inline MaybeObject* Copy();
1958    MUST_USE_RESULT MaybeObject* CopySize(int new_length);
1959  
1960    // Add the elements of a JSArray to this FixedArray.
1961    MUST_USE_RESULT MaybeObject* AddKeysFromJSArray(JSArray* array);
1962  
1963    // Compute the union of this and other.
1964    MUST_USE_RESULT MaybeObject* UnionOfKeys(FixedArray* other);
1965  
1966    // Copy a sub array from the receiver to dest.
1967    void CopyTo(int pos, FixedArray* dest, int dest_pos, int len);
1968  
1969    // Garbage collection support.
SizeFor(int length)1970    static int SizeFor(int length) { return kHeaderSize + length * kPointerSize; }
1971  
1972    // Code Generation support.
OffsetOfElementAt(int index)1973    static int OffsetOfElementAt(int index) { return SizeFor(index); }
1974  
1975    // Casting.
1976    static inline FixedArray* cast(Object* obj);
1977  
1978    // Layout description.
1979    // Length is smi tagged when it is stored.
1980    static const int kLengthOffset = HeapObject::kHeaderSize;
1981    static const int kHeaderSize = kLengthOffset + kPointerSize;
1982  
1983    // Maximal allowed size, in bytes, of a single FixedArray.
1984    // Prevents overflowing size computations, as well as extreme memory
1985    // consumption.
1986    static const int kMaxSize = 512 * MB;
1987    // Maximally allowed length of a FixedArray.
1988    static const int kMaxLength = (kMaxSize - kHeaderSize) / kPointerSize;
1989  
1990    // Dispatched behavior.
1991  #ifdef OBJECT_PRINT
FixedArrayPrint()1992    inline void FixedArrayPrint() {
1993      FixedArrayPrint(stdout);
1994    }
1995    void FixedArrayPrint(FILE* out);
1996  #endif
1997  #ifdef DEBUG
1998    void FixedArrayVerify();
1999    // Checks if two FixedArrays have identical contents.
2000    bool IsEqualTo(FixedArray* other);
2001  #endif
2002  
2003    // Swap two elements in a pair of arrays.  If this array and the
2004    // numbers array are the same object, the elements are only swapped
2005    // once.
2006    void SwapPairs(FixedArray* numbers, int i, int j);
2007  
2008    // Sort prefix of this array and the numbers array as pairs wrt. the
2009    // numbers.  If the numbers array and the this array are the same
2010    // object, the prefix of this array is sorted.
2011    void SortPairs(FixedArray* numbers, uint32_t len);
2012  
2013    class BodyDescriptor : public FlexibleBodyDescriptor<kHeaderSize> {
2014     public:
SizeOf(Map * map,HeapObject * object)2015      static inline int SizeOf(Map* map, HeapObject* object) {
2016        return SizeFor(reinterpret_cast<FixedArray*>(object)->length());
2017      }
2018    };
2019  
2020   protected:
2021    // Set operation on FixedArray without using write barriers. Can
2022    // only be used for storing old space objects or smis.
2023    static inline void fast_set(FixedArray* array, int index, Object* value);
2024  
2025   private:
2026    DISALLOW_IMPLICIT_CONSTRUCTORS(FixedArray);
2027  };
2028  
2029  
2030  // DescriptorArrays are fixed arrays used to hold instance descriptors.
2031  // The format of the these objects is:
2032  //   [0]: point to a fixed array with (value, detail) pairs.
2033  //   [1]: next enumeration index (Smi), or pointer to small fixed array:
2034  //          [0]: next enumeration index (Smi)
2035  //          [1]: pointer to fixed array with enum cache
2036  //   [2]: first key
2037  //   [length() - 1]: last key
2038  //
2039  class DescriptorArray: public FixedArray {
2040   public:
2041    // Is this the singleton empty_descriptor_array?
2042    inline bool IsEmpty();
2043  
2044    // Returns the number of descriptors in the array.
number_of_descriptors()2045    int number_of_descriptors() {
2046      ASSERT(length() > kFirstIndex || IsEmpty());
2047      int len = length();
2048      return len <= kFirstIndex ? 0 : len - kFirstIndex;
2049    }
2050  
NextEnumerationIndex()2051    int NextEnumerationIndex() {
2052      if (IsEmpty()) return PropertyDetails::kInitialIndex;
2053      Object* obj = get(kEnumerationIndexIndex);
2054      if (obj->IsSmi()) {
2055        return Smi::cast(obj)->value();
2056      } else {
2057        Object* index = FixedArray::cast(obj)->get(kEnumCacheBridgeEnumIndex);
2058        return Smi::cast(index)->value();
2059      }
2060    }
2061  
2062    // Set next enumeration index and flush any enum cache.
SetNextEnumerationIndex(int value)2063    void SetNextEnumerationIndex(int value) {
2064      if (!IsEmpty()) {
2065        fast_set(this, kEnumerationIndexIndex, Smi::FromInt(value));
2066      }
2067    }
HasEnumCache()2068    bool HasEnumCache() {
2069      return !IsEmpty() && !get(kEnumerationIndexIndex)->IsSmi();
2070    }
2071  
GetEnumCache()2072    Object* GetEnumCache() {
2073      ASSERT(HasEnumCache());
2074      FixedArray* bridge = FixedArray::cast(get(kEnumerationIndexIndex));
2075      return bridge->get(kEnumCacheBridgeCacheIndex);
2076    }
2077  
2078    // Initialize or change the enum cache,
2079    // using the supplied storage for the small "bridge".
2080    void SetEnumCache(FixedArray* bridge_storage, FixedArray* new_cache);
2081  
2082    // Accessors for fetching instance descriptor at descriptor number.
2083    inline String* GetKey(int descriptor_number);
2084    inline Object* GetValue(int descriptor_number);
2085    inline Smi* GetDetails(int descriptor_number);
2086    inline PropertyType GetType(int descriptor_number);
2087    inline int GetFieldIndex(int descriptor_number);
2088    inline JSFunction* GetConstantFunction(int descriptor_number);
2089    inline Object* GetCallbacksObject(int descriptor_number);
2090    inline AccessorDescriptor* GetCallbacks(int descriptor_number);
2091    inline bool IsProperty(int descriptor_number);
2092    inline bool IsTransition(int descriptor_number);
2093    inline bool IsNullDescriptor(int descriptor_number);
2094    inline bool IsDontEnum(int descriptor_number);
2095  
2096    // Accessor for complete descriptor.
2097    inline void Get(int descriptor_number, Descriptor* desc);
2098    inline void Set(int descriptor_number, Descriptor* desc);
2099  
2100    // Transfer complete descriptor from another descriptor array to
2101    // this one.
2102    inline void CopyFrom(int index, DescriptorArray* src, int src_index);
2103  
2104    // Copy the descriptor array, insert a new descriptor and optionally
2105    // remove map transitions.  If the descriptor is already present, it is
2106    // replaced.  If a replaced descriptor is a real property (not a transition
2107    // or null), its enumeration index is kept as is.
2108    // If adding a real property, map transitions must be removed.  If adding
2109    // a transition, they must not be removed.  All null descriptors are removed.
2110    MUST_USE_RESULT MaybeObject* CopyInsert(Descriptor* descriptor,
2111                                            TransitionFlag transition_flag);
2112  
2113    // Remove all transitions.  Return  a copy of the array with all transitions
2114    // removed, or a Failure object if the new array could not be allocated.
2115    MUST_USE_RESULT MaybeObject* RemoveTransitions();
2116  
2117    // Sort the instance descriptors by the hash codes of their keys.
2118    // Does not check for duplicates.
2119    void SortUnchecked();
2120  
2121    // Sort the instance descriptors by the hash codes of their keys.
2122    // Checks the result for duplicates.
2123    void Sort();
2124  
2125    // Search the instance descriptors for given name.
2126    inline int Search(String* name);
2127  
2128    // As the above, but uses DescriptorLookupCache and updates it when
2129    // necessary.
2130    inline int SearchWithCache(String* name);
2131  
2132    // Tells whether the name is present int the array.
Contains(String * name)2133    bool Contains(String* name) { return kNotFound != Search(name); }
2134  
2135    // Perform a binary search in the instance descriptors represented
2136    // by this fixed array.  low and high are descriptor indices.  If there
2137    // are three instance descriptors in this array it should be called
2138    // with low=0 and high=2.
2139    int BinarySearch(String* name, int low, int high);
2140  
2141    // Perform a linear search in the instance descriptors represented
2142    // by this fixed array.  len is the number of descriptor indices that are
2143    // valid.  Does not require the descriptors to be sorted.
2144    int LinearSearch(String* name, int len);
2145  
2146    // Allocates a DescriptorArray, but returns the singleton
2147    // empty descriptor array object if number_of_descriptors is 0.
2148    MUST_USE_RESULT static MaybeObject* Allocate(int number_of_descriptors);
2149  
2150    // Casting.
2151    static inline DescriptorArray* cast(Object* obj);
2152  
2153    // Constant for denoting key was not found.
2154    static const int kNotFound = -1;
2155  
2156    static const int kContentArrayIndex = 0;
2157    static const int kEnumerationIndexIndex = 1;
2158    static const int kFirstIndex = 2;
2159  
2160    // The length of the "bridge" to the enum cache.
2161    static const int kEnumCacheBridgeLength = 2;
2162    static const int kEnumCacheBridgeEnumIndex = 0;
2163    static const int kEnumCacheBridgeCacheIndex = 1;
2164  
2165    // Layout description.
2166    static const int kContentArrayOffset = FixedArray::kHeaderSize;
2167    static const int kEnumerationIndexOffset = kContentArrayOffset + kPointerSize;
2168    static const int kFirstOffset = kEnumerationIndexOffset + kPointerSize;
2169  
2170    // Layout description for the bridge array.
2171    static const int kEnumCacheBridgeEnumOffset = FixedArray::kHeaderSize;
2172    static const int kEnumCacheBridgeCacheOffset =
2173      kEnumCacheBridgeEnumOffset + kPointerSize;
2174  
2175  #ifdef OBJECT_PRINT
2176    // Print all the descriptors.
PrintDescriptors()2177    inline void PrintDescriptors() {
2178      PrintDescriptors(stdout);
2179    }
2180    void PrintDescriptors(FILE* out);
2181  #endif
2182  
2183  #ifdef DEBUG
2184    // Is the descriptor array sorted and without duplicates?
2185    bool IsSortedNoDuplicates();
2186  
2187    // Are two DescriptorArrays equal?
2188    bool IsEqualTo(DescriptorArray* other);
2189  #endif
2190  
2191    // The maximum number of descriptors we want in a descriptor array (should
2192    // fit in a page).
2193    static const int kMaxNumberOfDescriptors = 1024 + 512;
2194  
2195   private:
2196    // Conversion from descriptor number to array indices.
ToKeyIndex(int descriptor_number)2197    static int ToKeyIndex(int descriptor_number) {
2198      return descriptor_number+kFirstIndex;
2199    }
2200  
ToDetailsIndex(int descriptor_number)2201    static int ToDetailsIndex(int descriptor_number) {
2202      return (descriptor_number << 1) + 1;
2203    }
2204  
ToValueIndex(int descriptor_number)2205    static int ToValueIndex(int descriptor_number) {
2206      return descriptor_number << 1;
2207    }
2208  
is_null_descriptor(int descriptor_number)2209    bool is_null_descriptor(int descriptor_number) {
2210      return PropertyDetails(GetDetails(descriptor_number)).type() ==
2211          NULL_DESCRIPTOR;
2212    }
2213    // Swap operation on FixedArray without using write barriers.
2214    static inline void fast_swap(FixedArray* array, int first, int second);
2215  
2216    // Swap descriptor first and second.
2217    inline void Swap(int first, int second);
2218  
GetContentArray()2219    FixedArray* GetContentArray() {
2220      return FixedArray::cast(get(kContentArrayIndex));
2221    }
2222    DISALLOW_IMPLICIT_CONSTRUCTORS(DescriptorArray);
2223  };
2224  
2225  
2226  // HashTable is a subclass of FixedArray that implements a hash table
2227  // that uses open addressing and quadratic probing.
2228  //
2229  // In order for the quadratic probing to work, elements that have not
2230  // yet been used and elements that have been deleted are
2231  // distinguished.  Probing continues when deleted elements are
2232  // encountered and stops when unused elements are encountered.
2233  //
2234  // - Elements with key == undefined have not been used yet.
2235  // - Elements with key == null have been deleted.
2236  //
2237  // The hash table class is parameterized with a Shape and a Key.
2238  // Shape must be a class with the following interface:
2239  //   class ExampleShape {
2240  //    public:
2241  //      // Tells whether key matches other.
2242  //     static bool IsMatch(Key key, Object* other);
2243  //     // Returns the hash value for key.
2244  //     static uint32_t Hash(Key key);
2245  //     // Returns the hash value for object.
2246  //     static uint32_t HashForObject(Key key, Object* object);
2247  //     // Convert key to an object.
2248  //     static inline Object* AsObject(Key key);
2249  //     // The prefix size indicates number of elements in the beginning
2250  //     // of the backing storage.
2251  //     static const int kPrefixSize = ..;
2252  //     // The Element size indicates number of elements per entry.
2253  //     static const int kEntrySize = ..;
2254  //   };
2255  // The prefix size indicates an amount of memory in the
2256  // beginning of the backing storage that can be used for non-element
2257  // information by subclasses.
2258  
2259  template<typename Shape, typename Key>
2260  class HashTable: public FixedArray {
2261   public:
2262    // Returns the number of elements in the hash table.
NumberOfElements()2263    int NumberOfElements() {
2264      return Smi::cast(get(kNumberOfElementsIndex))->value();
2265    }
2266  
2267    // Returns the number of deleted elements in the hash table.
NumberOfDeletedElements()2268    int NumberOfDeletedElements() {
2269      return Smi::cast(get(kNumberOfDeletedElementsIndex))->value();
2270    }
2271  
2272    // Returns the capacity of the hash table.
Capacity()2273    int Capacity() {
2274      return Smi::cast(get(kCapacityIndex))->value();
2275    }
2276  
2277    // ElementAdded should be called whenever an element is added to a
2278    // hash table.
ElementAdded()2279    void ElementAdded() { SetNumberOfElements(NumberOfElements() + 1); }
2280  
2281    // ElementRemoved should be called whenever an element is removed from
2282    // a hash table.
ElementRemoved()2283    void ElementRemoved() {
2284      SetNumberOfElements(NumberOfElements() - 1);
2285      SetNumberOfDeletedElements(NumberOfDeletedElements() + 1);
2286    }
ElementsRemoved(int n)2287    void ElementsRemoved(int n) {
2288      SetNumberOfElements(NumberOfElements() - n);
2289      SetNumberOfDeletedElements(NumberOfDeletedElements() + n);
2290    }
2291  
2292    // Returns a new HashTable object. Might return Failure.
2293    MUST_USE_RESULT static MaybeObject* Allocate(
2294        int at_least_space_for,
2295        PretenureFlag pretenure = NOT_TENURED);
2296  
2297    // Returns the key at entry.
KeyAt(int entry)2298    Object* KeyAt(int entry) { return get(EntryToIndex(entry)); }
2299  
2300    // Tells whether k is a real key.  Null and undefined are not allowed
2301    // as keys and can be used to indicate missing or deleted elements.
IsKey(Object * k)2302    bool IsKey(Object* k) {
2303      return !k->IsNull() && !k->IsUndefined();
2304    }
2305  
2306    // Garbage collection support.
2307    void IteratePrefix(ObjectVisitor* visitor);
2308    void IterateElements(ObjectVisitor* visitor);
2309  
2310    // Casting.
2311    static inline HashTable* cast(Object* obj);
2312  
2313    // Compute the probe offset (quadratic probing).
INLINE(static uint32_t GetProbeOffset (uint32_t n))2314    INLINE(static uint32_t GetProbeOffset(uint32_t n)) {
2315      return (n + n * n) >> 1;
2316    }
2317  
2318    static const int kNumberOfElementsIndex = 0;
2319    static const int kNumberOfDeletedElementsIndex = 1;
2320    static const int kCapacityIndex = 2;
2321    static const int kPrefixStartIndex = 3;
2322    static const int kElementsStartIndex =
2323        kPrefixStartIndex + Shape::kPrefixSize;
2324    static const int kEntrySize = Shape::kEntrySize;
2325    static const int kElementsStartOffset =
2326        kHeaderSize + kElementsStartIndex * kPointerSize;
2327    static const int kCapacityOffset =
2328        kHeaderSize + kCapacityIndex * kPointerSize;
2329  
2330    // Constant used for denoting a absent entry.
2331    static const int kNotFound = -1;
2332  
2333    // Maximal capacity of HashTable. Based on maximal length of underlying
2334    // FixedArray. Staying below kMaxCapacity also ensures that EntryToIndex
2335    // cannot overflow.
2336    static const int kMaxCapacity =
2337        (FixedArray::kMaxLength - kElementsStartOffset) / kEntrySize;
2338  
2339    // Find entry for key otherwise return kNotFound.
2340    inline int FindEntry(Key key);
2341    int FindEntry(Isolate* isolate, Key key);
2342  
2343   protected:
2344  
2345    // Find the entry at which to insert element with the given key that
2346    // has the given hash value.
2347    uint32_t FindInsertionEntry(uint32_t hash);
2348  
2349    // Returns the index for an entry (of the key)
EntryToIndex(int entry)2350    static inline int EntryToIndex(int entry) {
2351      return (entry * kEntrySize) + kElementsStartIndex;
2352    }
2353  
2354    // Update the number of elements in the hash table.
SetNumberOfElements(int nof)2355    void SetNumberOfElements(int nof) {
2356      fast_set(this, kNumberOfElementsIndex, Smi::FromInt(nof));
2357    }
2358  
2359    // Update the number of deleted elements in the hash table.
SetNumberOfDeletedElements(int nod)2360    void SetNumberOfDeletedElements(int nod) {
2361      fast_set(this, kNumberOfDeletedElementsIndex, Smi::FromInt(nod));
2362    }
2363  
2364    // Sets the capacity of the hash table.
SetCapacity(int capacity)2365    void SetCapacity(int capacity) {
2366      // To scale a computed hash code to fit within the hash table, we
2367      // use bit-wise AND with a mask, so the capacity must be positive
2368      // and non-zero.
2369      ASSERT(capacity > 0);
2370      ASSERT(capacity <= kMaxCapacity);
2371      fast_set(this, kCapacityIndex, Smi::FromInt(capacity));
2372    }
2373  
2374  
2375    // Returns probe entry.
GetProbe(uint32_t hash,uint32_t number,uint32_t size)2376    static uint32_t GetProbe(uint32_t hash, uint32_t number, uint32_t size) {
2377      ASSERT(IsPowerOf2(size));
2378      return (hash + GetProbeOffset(number)) & (size - 1);
2379    }
2380  
FirstProbe(uint32_t hash,uint32_t size)2381    static uint32_t FirstProbe(uint32_t hash, uint32_t size) {
2382      return hash & (size - 1);
2383    }
2384  
NextProbe(uint32_t last,uint32_t number,uint32_t size)2385    static uint32_t NextProbe(uint32_t last, uint32_t number, uint32_t size) {
2386      return (last + number) & (size - 1);
2387    }
2388  
2389    // Ensure enough space for n additional elements.
2390    MUST_USE_RESULT MaybeObject* EnsureCapacity(int n, Key key);
2391  };
2392  
2393  
2394  
2395  // HashTableKey is an abstract superclass for virtual key behavior.
2396  class HashTableKey {
2397   public:
2398    // Returns whether the other object matches this key.
2399    virtual bool IsMatch(Object* other) = 0;
2400    // Returns the hash value for this key.
2401    virtual uint32_t Hash() = 0;
2402    // Returns the hash value for object.
2403    virtual uint32_t HashForObject(Object* key) = 0;
2404    // Returns the key object for storing into the hash table.
2405    // If allocations fails a failure object is returned.
2406    MUST_USE_RESULT virtual MaybeObject* AsObject() = 0;
2407    // Required.
~HashTableKey()2408    virtual ~HashTableKey() {}
2409  };
2410  
2411  class SymbolTableShape {
2412   public:
IsMatch(HashTableKey * key,Object * value)2413    static inline bool IsMatch(HashTableKey* key, Object* value) {
2414      return key->IsMatch(value);
2415    }
Hash(HashTableKey * key)2416    static inline uint32_t Hash(HashTableKey* key) {
2417      return key->Hash();
2418    }
HashForObject(HashTableKey * key,Object * object)2419    static inline uint32_t HashForObject(HashTableKey* key, Object* object) {
2420      return key->HashForObject(object);
2421    }
AsObject(HashTableKey * key)2422    MUST_USE_RESULT static inline MaybeObject* AsObject(HashTableKey* key) {
2423      return key->AsObject();
2424    }
2425  
2426    static const int kPrefixSize = 0;
2427    static const int kEntrySize = 1;
2428  };
2429  
2430  // SymbolTable.
2431  //
2432  // No special elements in the prefix and the element size is 1
2433  // because only the symbol itself (the key) needs to be stored.
2434  class SymbolTable: public HashTable<SymbolTableShape, HashTableKey*> {
2435   public:
2436    // Find symbol in the symbol table.  If it is not there yet, it is
2437    // added.  The return value is the symbol table which might have
2438    // been enlarged.  If the return value is not a failure, the symbol
2439    // pointer *s is set to the symbol found.
2440    MUST_USE_RESULT MaybeObject* LookupSymbol(Vector<const char> str, Object** s);
2441    MUST_USE_RESULT MaybeObject* LookupAsciiSymbol(Vector<const char> str,
2442                                                   Object** s);
2443    MUST_USE_RESULT MaybeObject* LookupTwoByteSymbol(Vector<const uc16> str,
2444                                                     Object** s);
2445    MUST_USE_RESULT MaybeObject* LookupString(String* key, Object** s);
2446  
2447    // Looks up a symbol that is equal to the given string and returns
2448    // true if it is found, assigning the symbol to the given output
2449    // parameter.
2450    bool LookupSymbolIfExists(String* str, String** symbol);
2451    bool LookupTwoCharsSymbolIfExists(uint32_t c1, uint32_t c2, String** symbol);
2452  
2453    // Casting.
2454    static inline SymbolTable* cast(Object* obj);
2455  
2456   private:
2457    MUST_USE_RESULT MaybeObject* LookupKey(HashTableKey* key, Object** s);
2458  
2459    DISALLOW_IMPLICIT_CONSTRUCTORS(SymbolTable);
2460  };
2461  
2462  
2463  class MapCacheShape {
2464   public:
IsMatch(HashTableKey * key,Object * value)2465    static inline bool IsMatch(HashTableKey* key, Object* value) {
2466      return key->IsMatch(value);
2467    }
Hash(HashTableKey * key)2468    static inline uint32_t Hash(HashTableKey* key) {
2469      return key->Hash();
2470    }
2471  
HashForObject(HashTableKey * key,Object * object)2472    static inline uint32_t HashForObject(HashTableKey* key, Object* object) {
2473      return key->HashForObject(object);
2474    }
2475  
AsObject(HashTableKey * key)2476    MUST_USE_RESULT static inline MaybeObject* AsObject(HashTableKey* key) {
2477      return key->AsObject();
2478    }
2479  
2480    static const int kPrefixSize = 0;
2481    static const int kEntrySize = 2;
2482  };
2483  
2484  
2485  // MapCache.
2486  //
2487  // Maps keys that are a fixed array of symbols to a map.
2488  // Used for canonicalize maps for object literals.
2489  class MapCache: public HashTable<MapCacheShape, HashTableKey*> {
2490   public:
2491    // Find cached value for a string key, otherwise return null.
2492    Object* Lookup(FixedArray* key);
2493    MUST_USE_RESULT MaybeObject* Put(FixedArray* key, Map* value);
2494    static inline MapCache* cast(Object* obj);
2495  
2496   private:
2497    DISALLOW_IMPLICIT_CONSTRUCTORS(MapCache);
2498  };
2499  
2500  
2501  template <typename Shape, typename Key>
2502  class Dictionary: public HashTable<Shape, Key> {
2503   public:
2504  
cast(Object * obj)2505    static inline Dictionary<Shape, Key>* cast(Object* obj) {
2506      return reinterpret_cast<Dictionary<Shape, Key>*>(obj);
2507    }
2508  
2509    // Returns the value at entry.
ValueAt(int entry)2510    Object* ValueAt(int entry) {
2511      return this->get(HashTable<Shape, Key>::EntryToIndex(entry)+1);
2512    }
2513  
2514    // Set the value for entry.
2515    // Returns false if the put wasn't performed due to property being read only.
2516    // Returns true on successful put.
ValueAtPut(int entry,Object * value)2517    bool ValueAtPut(int entry, Object* value) {
2518      // Check that this value can actually be written.
2519      PropertyDetails details = DetailsAt(entry);
2520      // If a value has not been initilized we allow writing to it even if
2521      // it is read only (a declared const that has not been initialized).
2522      if (details.IsReadOnly() && !ValueAt(entry)->IsTheHole()) {
2523        return false;
2524      }
2525      this->set(HashTable<Shape, Key>::EntryToIndex(entry) + 1, value);
2526      return true;
2527    }
2528  
2529    // Returns the property details for the property at entry.
DetailsAt(int entry)2530    PropertyDetails DetailsAt(int entry) {
2531      ASSERT(entry >= 0);  // Not found is -1, which is not caught by get().
2532      return PropertyDetails(
2533          Smi::cast(this->get(HashTable<Shape, Key>::EntryToIndex(entry) + 2)));
2534    }
2535  
2536    // Set the details for entry.
DetailsAtPut(int entry,PropertyDetails value)2537    void DetailsAtPut(int entry, PropertyDetails value) {
2538      this->set(HashTable<Shape, Key>::EntryToIndex(entry) + 2, value.AsSmi());
2539    }
2540  
2541    // Sorting support
2542    void CopyValuesTo(FixedArray* elements);
2543  
2544    // Delete a property from the dictionary.
2545    Object* DeleteProperty(int entry, JSObject::DeleteMode mode);
2546  
2547    // Returns the number of elements in the dictionary filtering out properties
2548    // with the specified attributes.
2549    int NumberOfElementsFilterAttributes(PropertyAttributes filter);
2550  
2551    // Returns the number of enumerable elements in the dictionary.
2552    int NumberOfEnumElements();
2553  
2554    // Copies keys to preallocated fixed array.
2555    void CopyKeysTo(FixedArray* storage, PropertyAttributes filter);
2556    // Fill in details for properties into storage.
2557    void CopyKeysTo(FixedArray* storage, int index);
2558  
2559    // Accessors for next enumeration index.
SetNextEnumerationIndex(int index)2560    void SetNextEnumerationIndex(int index) {
2561      this->fast_set(this, kNextEnumerationIndexIndex, Smi::FromInt(index));
2562    }
2563  
NextEnumerationIndex()2564    int NextEnumerationIndex() {
2565      return Smi::cast(FixedArray::get(kNextEnumerationIndexIndex))->value();
2566    }
2567  
2568    // Returns a new array for dictionary usage. Might return Failure.
2569    MUST_USE_RESULT static MaybeObject* Allocate(int at_least_space_for);
2570  
2571    // Ensure enough space for n additional elements.
2572    MUST_USE_RESULT MaybeObject* EnsureCapacity(int n, Key key);
2573  
2574  #ifdef OBJECT_PRINT
Print()2575    inline void Print() {
2576      Print(stdout);
2577    }
2578    void Print(FILE* out);
2579  #endif
2580    // Returns the key (slow).
2581    Object* SlowReverseLookup(Object* value);
2582  
2583    // Sets the entry to (key, value) pair.
2584    inline void SetEntry(int entry,
2585                         Object* key,
2586                         Object* value);
2587    inline void SetEntry(int entry,
2588                         Object* key,
2589                         Object* value,
2590                         PropertyDetails details);
2591  
2592    MUST_USE_RESULT MaybeObject* Add(Key key,
2593                                     Object* value,
2594                                     PropertyDetails details);
2595  
2596   protected:
2597    // Generic at put operation.
2598    MUST_USE_RESULT MaybeObject* AtPut(Key key, Object* value);
2599  
2600    // Add entry to dictionary.
2601    MUST_USE_RESULT MaybeObject* AddEntry(Key key,
2602                                          Object* value,
2603                                          PropertyDetails details,
2604                                          uint32_t hash);
2605  
2606    // Generate new enumeration indices to avoid enumeration index overflow.
2607    MUST_USE_RESULT MaybeObject* GenerateNewEnumerationIndices();
2608    static const int kMaxNumberKeyIndex =
2609        HashTable<Shape, Key>::kPrefixStartIndex;
2610    static const int kNextEnumerationIndexIndex = kMaxNumberKeyIndex + 1;
2611  };
2612  
2613  
2614  class StringDictionaryShape {
2615   public:
2616    static inline bool IsMatch(String* key, Object* other);
2617    static inline uint32_t Hash(String* key);
2618    static inline uint32_t HashForObject(String* key, Object* object);
2619    MUST_USE_RESULT static inline MaybeObject* AsObject(String* key);
2620    static const int kPrefixSize = 2;
2621    static const int kEntrySize = 3;
2622    static const bool kIsEnumerable = true;
2623  };
2624  
2625  
2626  class StringDictionary: public Dictionary<StringDictionaryShape, String*> {
2627   public:
cast(Object * obj)2628    static inline StringDictionary* cast(Object* obj) {
2629      ASSERT(obj->IsDictionary());
2630      return reinterpret_cast<StringDictionary*>(obj);
2631    }
2632  
2633    // Copies enumerable keys to preallocated fixed array.
2634    void CopyEnumKeysTo(FixedArray* storage, FixedArray* sort_array);
2635  
2636    // For transforming properties of a JSObject.
2637    MUST_USE_RESULT MaybeObject* TransformPropertiesToFastFor(
2638        JSObject* obj,
2639        int unused_property_fields);
2640  
2641    // Find entry for key otherwise return kNotFound. Optimzed version of
2642    // HashTable::FindEntry.
2643    int FindEntry(String* key);
2644  };
2645  
2646  
2647  class NumberDictionaryShape {
2648   public:
2649    static inline bool IsMatch(uint32_t key, Object* other);
2650    static inline uint32_t Hash(uint32_t key);
2651    static inline uint32_t HashForObject(uint32_t key, Object* object);
2652    MUST_USE_RESULT static inline MaybeObject* AsObject(uint32_t key);
2653    static const int kPrefixSize = 2;
2654    static const int kEntrySize = 3;
2655    static const bool kIsEnumerable = false;
2656  };
2657  
2658  
2659  class NumberDictionary: public Dictionary<NumberDictionaryShape, uint32_t> {
2660   public:
cast(Object * obj)2661    static NumberDictionary* cast(Object* obj) {
2662      ASSERT(obj->IsDictionary());
2663      return reinterpret_cast<NumberDictionary*>(obj);
2664    }
2665  
2666    // Type specific at put (default NONE attributes is used when adding).
2667    MUST_USE_RESULT MaybeObject* AtNumberPut(uint32_t key, Object* value);
2668    MUST_USE_RESULT MaybeObject* AddNumberEntry(uint32_t key,
2669                                                Object* value,
2670                                                PropertyDetails details);
2671  
2672    // Set an existing entry or add a new one if needed.
2673    MUST_USE_RESULT MaybeObject* Set(uint32_t key,
2674                                     Object* value,
2675                                     PropertyDetails details);
2676  
2677    void UpdateMaxNumberKey(uint32_t key);
2678  
2679    // If slow elements are required we will never go back to fast-case
2680    // for the elements kept in this dictionary.  We require slow
2681    // elements if an element has been added at an index larger than
2682    // kRequiresSlowElementsLimit or set_requires_slow_elements() has been called
2683    // when defining a getter or setter with a number key.
2684    inline bool requires_slow_elements();
2685    inline void set_requires_slow_elements();
2686  
2687    // Get the value of the max number key that has been added to this
2688    // dictionary.  max_number_key can only be called if
2689    // requires_slow_elements returns false.
2690    inline uint32_t max_number_key();
2691  
2692    // Remove all entries were key is a number and (from <= key && key < to).
2693    void RemoveNumberEntries(uint32_t from, uint32_t to);
2694  
2695    // Bit masks.
2696    static const int kRequiresSlowElementsMask = 1;
2697    static const int kRequiresSlowElementsTagSize = 1;
2698    static const uint32_t kRequiresSlowElementsLimit = (1 << 29) - 1;
2699  };
2700  
2701  
2702  // JSFunctionResultCache caches results of some JSFunction invocation.
2703  // It is a fixed array with fixed structure:
2704  //   [0]: factory function
2705  //   [1]: finger index
2706  //   [2]: current cache size
2707  //   [3]: dummy field.
2708  // The rest of array are key/value pairs.
2709  class JSFunctionResultCache: public FixedArray {
2710   public:
2711    static const int kFactoryIndex = 0;
2712    static const int kFingerIndex = kFactoryIndex + 1;
2713    static const int kCacheSizeIndex = kFingerIndex + 1;
2714    static const int kDummyIndex = kCacheSizeIndex + 1;
2715    static const int kEntriesIndex = kDummyIndex + 1;
2716  
2717    static const int kEntrySize = 2;  // key + value
2718  
2719    static const int kFactoryOffset = kHeaderSize;
2720    static const int kFingerOffset = kFactoryOffset + kPointerSize;
2721    static const int kCacheSizeOffset = kFingerOffset + kPointerSize;
2722  
2723    inline void MakeZeroSize();
2724    inline void Clear();
2725  
2726    inline int size();
2727    inline void set_size(int size);
2728    inline int finger_index();
2729    inline void set_finger_index(int finger_index);
2730  
2731    // Casting
2732    static inline JSFunctionResultCache* cast(Object* obj);
2733  
2734  #ifdef DEBUG
2735    void JSFunctionResultCacheVerify();
2736  #endif
2737  };
2738  
2739  
2740  // The cache for maps used by normalized (dictionary mode) objects.
2741  // Such maps do not have property descriptors, so a typical program
2742  // needs very limited number of distinct normalized maps.
2743  class NormalizedMapCache: public FixedArray {
2744   public:
2745    static const int kEntries = 64;
2746  
2747    MUST_USE_RESULT MaybeObject* Get(JSObject* object,
2748                                     PropertyNormalizationMode mode);
2749  
2750    void Clear();
2751  
2752    // Casting
2753    static inline NormalizedMapCache* cast(Object* obj);
2754  
2755  #ifdef DEBUG
2756    void NormalizedMapCacheVerify();
2757  #endif
2758  
2759   private:
2760    static int Hash(Map* fast);
2761  
2762    static bool CheckHit(Map* slow, Map* fast, PropertyNormalizationMode mode);
2763  };
2764  
2765  
2766  // ByteArray represents fixed sized byte arrays.  Used by the outside world,
2767  // such as PCRE, and also by the memory allocator and garbage collector to
2768  // fill in free blocks in the heap.
2769  class ByteArray: public HeapObject {
2770   public:
2771    // [length]: length of the array.
2772    inline int length();
2773    inline void set_length(int value);
2774  
2775    // Setter and getter.
2776    inline byte get(int index);
2777    inline void set(int index, byte value);
2778  
2779    // Treat contents as an int array.
2780    inline int get_int(int index);
2781  
SizeFor(int length)2782    static int SizeFor(int length) {
2783      return OBJECT_POINTER_ALIGN(kHeaderSize + length);
2784    }
2785    // We use byte arrays for free blocks in the heap.  Given a desired size in
2786    // bytes that is a multiple of the word size and big enough to hold a byte
2787    // array, this function returns the number of elements a byte array should
2788    // have.
LengthFor(int size_in_bytes)2789    static int LengthFor(int size_in_bytes) {
2790      ASSERT(IsAligned(size_in_bytes, kPointerSize));
2791      ASSERT(size_in_bytes >= kHeaderSize);
2792      return size_in_bytes - kHeaderSize;
2793    }
2794  
2795    // Returns data start address.
2796    inline Address GetDataStartAddress();
2797  
2798    // Returns a pointer to the ByteArray object for a given data start address.
2799    static inline ByteArray* FromDataStartAddress(Address address);
2800  
2801    // Casting.
2802    static inline ByteArray* cast(Object* obj);
2803  
2804    // Dispatched behavior.
ByteArraySize()2805    inline int ByteArraySize() {
2806      return SizeFor(this->length());
2807    }
2808  #ifdef OBJECT_PRINT
ByteArrayPrint()2809    inline void ByteArrayPrint() {
2810      ByteArrayPrint(stdout);
2811    }
2812    void ByteArrayPrint(FILE* out);
2813  #endif
2814  #ifdef DEBUG
2815    void ByteArrayVerify();
2816  #endif
2817  
2818    // Layout description.
2819    // Length is smi tagged when it is stored.
2820    static const int kLengthOffset = HeapObject::kHeaderSize;
2821    static const int kHeaderSize = kLengthOffset + kPointerSize;
2822  
2823    static const int kAlignedSize = OBJECT_POINTER_ALIGN(kHeaderSize);
2824  
2825    // Maximal memory consumption for a single ByteArray.
2826    static const int kMaxSize = 512 * MB;
2827    // Maximal length of a single ByteArray.
2828    static const int kMaxLength = kMaxSize - kHeaderSize;
2829  
2830   private:
2831    DISALLOW_IMPLICIT_CONSTRUCTORS(ByteArray);
2832  };
2833  
2834  
2835  // An ExternalArray represents a fixed-size array of primitive values
2836  // which live outside the JavaScript heap. Its subclasses are used to
2837  // implement the CanvasArray types being defined in the WebGL
2838  // specification. As of this writing the first public draft is not yet
2839  // available, but Khronos members can access the draft at:
2840  //   https://cvs.khronos.org/svn/repos/3dweb/trunk/doc/spec/WebGL-spec.html
2841  //
2842  // The semantics of these arrays differ from CanvasPixelArray.
2843  // Out-of-range values passed to the setter are converted via a C
2844  // cast, not clamping. Out-of-range indices cause exceptions to be
2845  // raised rather than being silently ignored.
2846  class ExternalArray: public HeapObject {
2847   public:
2848    // [length]: length of the array.
2849    inline int length();
2850    inline void set_length(int value);
2851  
2852    // [external_pointer]: The pointer to the external memory area backing this
2853    // external array.
2854    DECL_ACCESSORS(external_pointer, void)  // Pointer to the data store.
2855  
2856    // Casting.
2857    static inline ExternalArray* cast(Object* obj);
2858  
2859    // Maximal acceptable length for an external array.
2860    static const int kMaxLength = 0x3fffffff;
2861  
2862    // ExternalArray headers are not quadword aligned.
2863    static const int kLengthOffset = HeapObject::kHeaderSize;
2864    static const int kExternalPointerOffset =
2865        POINTER_SIZE_ALIGN(kLengthOffset + kIntSize);
2866    static const int kHeaderSize = kExternalPointerOffset + kPointerSize;
2867    static const int kAlignedSize = OBJECT_POINTER_ALIGN(kHeaderSize);
2868  
2869   private:
2870    DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalArray);
2871  };
2872  
2873  
2874  // A ExternalPixelArray represents a fixed-size byte array with special
2875  // semantics used for implementing the CanvasPixelArray object. Please see the
2876  // specification at:
2877  
2878  // http://www.whatwg.org/specs/web-apps/current-work/
2879  //                      multipage/the-canvas-element.html#canvaspixelarray
2880  // In particular, write access clamps the value written to 0 or 255 if the
2881  // value written is outside this range.
2882  class ExternalPixelArray: public ExternalArray {
2883   public:
2884    inline uint8_t* external_pixel_pointer();
2885  
2886    // Setter and getter.
2887    inline uint8_t get(int index);
2888    inline void set(int index, uint8_t value);
2889  
2890    // This accessor applies the correct conversion from Smi, HeapNumber and
2891    // undefined and clamps the converted value between 0 and 255.
2892    Object* SetValue(uint32_t index, Object* value);
2893  
2894    // Casting.
2895    static inline ExternalPixelArray* cast(Object* obj);
2896  
2897  #ifdef OBJECT_PRINT
ExternalPixelArrayPrint()2898    inline void ExternalPixelArrayPrint() {
2899      ExternalPixelArrayPrint(stdout);
2900    }
2901    void ExternalPixelArrayPrint(FILE* out);
2902  #endif
2903  #ifdef DEBUG
2904    void ExternalPixelArrayVerify();
2905  #endif  // DEBUG
2906  
2907   private:
2908    DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalPixelArray);
2909  };
2910  
2911  
2912  class ExternalByteArray: public ExternalArray {
2913   public:
2914    // Setter and getter.
2915    inline int8_t get(int index);
2916    inline void set(int index, int8_t value);
2917  
2918    // This accessor applies the correct conversion from Smi, HeapNumber
2919    // and undefined.
2920    MaybeObject* SetValue(uint32_t index, Object* value);
2921  
2922    // Casting.
2923    static inline ExternalByteArray* cast(Object* obj);
2924  
2925  #ifdef OBJECT_PRINT
ExternalByteArrayPrint()2926    inline void ExternalByteArrayPrint() {
2927      ExternalByteArrayPrint(stdout);
2928    }
2929    void ExternalByteArrayPrint(FILE* out);
2930  #endif
2931  #ifdef DEBUG
2932    void ExternalByteArrayVerify();
2933  #endif  // DEBUG
2934  
2935   private:
2936    DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalByteArray);
2937  };
2938  
2939  
2940  class ExternalUnsignedByteArray: public ExternalArray {
2941   public:
2942    // Setter and getter.
2943    inline uint8_t get(int index);
2944    inline void set(int index, uint8_t value);
2945  
2946    // This accessor applies the correct conversion from Smi, HeapNumber
2947    // and undefined.
2948    MaybeObject* SetValue(uint32_t index, Object* value);
2949  
2950    // Casting.
2951    static inline ExternalUnsignedByteArray* cast(Object* obj);
2952  
2953  #ifdef OBJECT_PRINT
ExternalUnsignedByteArrayPrint()2954    inline void ExternalUnsignedByteArrayPrint() {
2955      ExternalUnsignedByteArrayPrint(stdout);
2956    }
2957    void ExternalUnsignedByteArrayPrint(FILE* out);
2958  #endif
2959  #ifdef DEBUG
2960    void ExternalUnsignedByteArrayVerify();
2961  #endif  // DEBUG
2962  
2963   private:
2964    DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalUnsignedByteArray);
2965  };
2966  
2967  
2968  class ExternalShortArray: public ExternalArray {
2969   public:
2970    // Setter and getter.
2971    inline int16_t get(int index);
2972    inline void set(int index, int16_t value);
2973  
2974    // This accessor applies the correct conversion from Smi, HeapNumber
2975    // and undefined.
2976    MaybeObject* SetValue(uint32_t index, Object* value);
2977  
2978    // Casting.
2979    static inline ExternalShortArray* cast(Object* obj);
2980  
2981  #ifdef OBJECT_PRINT
ExternalShortArrayPrint()2982    inline void ExternalShortArrayPrint() {
2983      ExternalShortArrayPrint(stdout);
2984    }
2985    void ExternalShortArrayPrint(FILE* out);
2986  #endif
2987  #ifdef DEBUG
2988    void ExternalShortArrayVerify();
2989  #endif  // DEBUG
2990  
2991   private:
2992    DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalShortArray);
2993  };
2994  
2995  
2996  class ExternalUnsignedShortArray: public ExternalArray {
2997   public:
2998    // Setter and getter.
2999    inline uint16_t get(int index);
3000    inline void set(int index, uint16_t value);
3001  
3002    // This accessor applies the correct conversion from Smi, HeapNumber
3003    // and undefined.
3004    MaybeObject* SetValue(uint32_t index, Object* value);
3005  
3006    // Casting.
3007    static inline ExternalUnsignedShortArray* cast(Object* obj);
3008  
3009  #ifdef OBJECT_PRINT
ExternalUnsignedShortArrayPrint()3010    inline void ExternalUnsignedShortArrayPrint() {
3011      ExternalUnsignedShortArrayPrint(stdout);
3012    }
3013    void ExternalUnsignedShortArrayPrint(FILE* out);
3014  #endif
3015  #ifdef DEBUG
3016    void ExternalUnsignedShortArrayVerify();
3017  #endif  // DEBUG
3018  
3019   private:
3020    DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalUnsignedShortArray);
3021  };
3022  
3023  
3024  class ExternalIntArray: public ExternalArray {
3025   public:
3026    // Setter and getter.
3027    inline int32_t get(int index);
3028    inline void set(int index, int32_t value);
3029  
3030    // This accessor applies the correct conversion from Smi, HeapNumber
3031    // and undefined.
3032    MaybeObject* SetValue(uint32_t index, Object* value);
3033  
3034    // Casting.
3035    static inline ExternalIntArray* cast(Object* obj);
3036  
3037  #ifdef OBJECT_PRINT
ExternalIntArrayPrint()3038    inline void ExternalIntArrayPrint() {
3039      ExternalIntArrayPrint(stdout);
3040    }
3041    void ExternalIntArrayPrint(FILE* out);
3042  #endif
3043  #ifdef DEBUG
3044    void ExternalIntArrayVerify();
3045  #endif  // DEBUG
3046  
3047   private:
3048    DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalIntArray);
3049  };
3050  
3051  
3052  class ExternalUnsignedIntArray: public ExternalArray {
3053   public:
3054    // Setter and getter.
3055    inline uint32_t get(int index);
3056    inline void set(int index, uint32_t value);
3057  
3058    // This accessor applies the correct conversion from Smi, HeapNumber
3059    // and undefined.
3060    MaybeObject* SetValue(uint32_t index, Object* value);
3061  
3062    // Casting.
3063    static inline ExternalUnsignedIntArray* cast(Object* obj);
3064  
3065  #ifdef OBJECT_PRINT
ExternalUnsignedIntArrayPrint()3066    inline void ExternalUnsignedIntArrayPrint() {
3067      ExternalUnsignedIntArrayPrint(stdout);
3068    }
3069    void ExternalUnsignedIntArrayPrint(FILE* out);
3070  #endif
3071  #ifdef DEBUG
3072    void ExternalUnsignedIntArrayVerify();
3073  #endif  // DEBUG
3074  
3075   private:
3076    DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalUnsignedIntArray);
3077  };
3078  
3079  
3080  class ExternalFloatArray: public ExternalArray {
3081   public:
3082    // Setter and getter.
3083    inline float get(int index);
3084    inline void set(int index, float value);
3085  
3086    // This accessor applies the correct conversion from Smi, HeapNumber
3087    // and undefined.
3088    MaybeObject* SetValue(uint32_t index, Object* value);
3089  
3090    // Casting.
3091    static inline ExternalFloatArray* cast(Object* obj);
3092  
3093  #ifdef OBJECT_PRINT
ExternalFloatArrayPrint()3094    inline void ExternalFloatArrayPrint() {
3095      ExternalFloatArrayPrint(stdout);
3096    }
3097    void ExternalFloatArrayPrint(FILE* out);
3098  #endif
3099  #ifdef DEBUG
3100    void ExternalFloatArrayVerify();
3101  #endif  // DEBUG
3102  
3103   private:
3104    DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalFloatArray);
3105  };
3106  
3107  
3108  // DeoptimizationInputData is a fixed array used to hold the deoptimization
3109  // data for code generated by the Hydrogen/Lithium compiler.  It also
3110  // contains information about functions that were inlined.  If N different
3111  // functions were inlined then first N elements of the literal array will
3112  // contain these functions.
3113  //
3114  // It can be empty.
3115  class DeoptimizationInputData: public FixedArray {
3116   public:
3117    // Layout description.  Indices in the array.
3118    static const int kTranslationByteArrayIndex = 0;
3119    static const int kInlinedFunctionCountIndex = 1;
3120    static const int kLiteralArrayIndex = 2;
3121    static const int kOsrAstIdIndex = 3;
3122    static const int kOsrPcOffsetIndex = 4;
3123    static const int kFirstDeoptEntryIndex = 5;
3124  
3125    // Offsets of deopt entry elements relative to the start of the entry.
3126    static const int kAstIdOffset = 0;
3127    static const int kTranslationIndexOffset = 1;
3128    static const int kArgumentsStackHeightOffset = 2;
3129    static const int kDeoptEntrySize = 3;
3130  
3131    // Simple element accessors.
3132  #define DEFINE_ELEMENT_ACCESSORS(name, type)      \
3133    type* name() {                                  \
3134      return type::cast(get(k##name##Index));       \
3135    }                                               \
3136    void Set##name(type* value) {                   \
3137      set(k##name##Index, value);                   \
3138    }
3139  
DEFINE_ELEMENT_ACCESSORS(TranslationByteArray,ByteArray)3140    DEFINE_ELEMENT_ACCESSORS(TranslationByteArray, ByteArray)
3141    DEFINE_ELEMENT_ACCESSORS(InlinedFunctionCount, Smi)
3142    DEFINE_ELEMENT_ACCESSORS(LiteralArray, FixedArray)
3143    DEFINE_ELEMENT_ACCESSORS(OsrAstId, Smi)
3144    DEFINE_ELEMENT_ACCESSORS(OsrPcOffset, Smi)
3145  
3146    // Unchecked accessor to be used during GC.
3147    FixedArray* UncheckedLiteralArray() {
3148      return reinterpret_cast<FixedArray*>(get(kLiteralArrayIndex));
3149    }
3150  
3151  #undef DEFINE_ELEMENT_ACCESSORS
3152  
3153    // Accessors for elements of the ith deoptimization entry.
3154  #define DEFINE_ENTRY_ACCESSORS(name, type)                       \
3155    type* name(int i) {                                            \
3156      return type::cast(get(IndexForEntry(i) + k##name##Offset));  \
3157    }                                                              \
3158    void Set##name(int i, type* value) {                           \
3159      set(IndexForEntry(i) + k##name##Offset, value);              \
3160    }
3161  
DEFINE_ENTRY_ACCESSORS(AstId,Smi)3162    DEFINE_ENTRY_ACCESSORS(AstId, Smi)
3163    DEFINE_ENTRY_ACCESSORS(TranslationIndex, Smi)
3164    DEFINE_ENTRY_ACCESSORS(ArgumentsStackHeight, Smi)
3165  
3166  #undef DEFINE_ENTRY_ACCESSORS
3167  
3168    int DeoptCount() {
3169      return (length() - kFirstDeoptEntryIndex) / kDeoptEntrySize;
3170    }
3171  
3172    // Allocates a DeoptimizationInputData.
3173    MUST_USE_RESULT static MaybeObject* Allocate(int deopt_entry_count,
3174                                                 PretenureFlag pretenure);
3175  
3176    // Casting.
3177    static inline DeoptimizationInputData* cast(Object* obj);
3178  
3179  #ifdef OBJECT_PRINT
3180    void DeoptimizationInputDataPrint(FILE* out);
3181  #endif
3182  
3183   private:
IndexForEntry(int i)3184    static int IndexForEntry(int i) {
3185      return kFirstDeoptEntryIndex + (i * kDeoptEntrySize);
3186    }
3187  
LengthFor(int entry_count)3188    static int LengthFor(int entry_count) {
3189      return IndexForEntry(entry_count);
3190    }
3191  };
3192  
3193  
3194  // DeoptimizationOutputData is a fixed array used to hold the deoptimization
3195  // data for code generated by the full compiler.
3196  // The format of the these objects is
3197  //   [i * 2]: Ast ID for ith deoptimization.
3198  //   [i * 2 + 1]: PC and state of ith deoptimization
3199  class DeoptimizationOutputData: public FixedArray {
3200   public:
DeoptPoints()3201    int DeoptPoints() { return length() / 2; }
AstId(int index)3202    Smi* AstId(int index) { return Smi::cast(get(index * 2)); }
SetAstId(int index,Smi * id)3203    void SetAstId(int index, Smi* id) { set(index * 2, id); }
PcAndState(int index)3204    Smi* PcAndState(int index) { return Smi::cast(get(1 + index * 2)); }
SetPcAndState(int index,Smi * offset)3205    void SetPcAndState(int index, Smi* offset) { set(1 + index * 2, offset); }
3206  
LengthOfFixedArray(int deopt_points)3207    static int LengthOfFixedArray(int deopt_points) {
3208      return deopt_points * 2;
3209    }
3210  
3211    // Allocates a DeoptimizationOutputData.
3212    MUST_USE_RESULT static MaybeObject* Allocate(int number_of_deopt_points,
3213                                                 PretenureFlag pretenure);
3214  
3215    // Casting.
3216    static inline DeoptimizationOutputData* cast(Object* obj);
3217  
3218  #ifdef OBJECT_PRINT
3219    void DeoptimizationOutputDataPrint(FILE* out);
3220  #endif
3221  };
3222  
3223  
3224  class SafepointEntry;
3225  
3226  
3227  // Code describes objects with on-the-fly generated machine code.
3228  class Code: public HeapObject {
3229   public:
3230    // Opaque data type for encapsulating code flags like kind, inline
3231    // cache state, and arguments count.
3232    // FLAGS_MIN_VALUE and FLAGS_MAX_VALUE are specified to ensure that
3233    // enumeration type has correct value range (see Issue 830 for more details).
3234    enum Flags {
3235      FLAGS_MIN_VALUE = kMinInt,
3236      FLAGS_MAX_VALUE = kMaxInt
3237    };
3238  
3239    enum Kind {
3240      FUNCTION,
3241      OPTIMIZED_FUNCTION,
3242      STUB,
3243      BUILTIN,
3244      LOAD_IC,
3245      KEYED_LOAD_IC,
3246      KEYED_EXTERNAL_ARRAY_LOAD_IC,
3247      CALL_IC,
3248      KEYED_CALL_IC,
3249      STORE_IC,
3250      KEYED_STORE_IC,
3251      KEYED_EXTERNAL_ARRAY_STORE_IC,
3252      TYPE_RECORDING_BINARY_OP_IC,
3253      COMPARE_IC,
3254      // No more than 16 kinds. The value currently encoded in four bits in
3255      // Flags.
3256  
3257      // Pseudo-kinds.
3258      REGEXP = BUILTIN,
3259      FIRST_IC_KIND = LOAD_IC,
3260      LAST_IC_KIND = COMPARE_IC
3261    };
3262  
3263    enum {
3264      NUMBER_OF_KINDS = LAST_IC_KIND + 1
3265    };
3266  
3267    typedef int ExtraICState;
3268  
3269    static const ExtraICState kNoExtraICState = 0;
3270  
3271  #ifdef ENABLE_DISASSEMBLER
3272    // Printing
3273    static const char* Kind2String(Kind kind);
3274    static const char* ICState2String(InlineCacheState state);
3275    static const char* PropertyType2String(PropertyType type);
3276    static void PrintExtraICState(FILE* out, Kind kind, ExtraICState extra);
Disassemble(const char * name)3277    inline void Disassemble(const char* name) {
3278      Disassemble(name, stdout);
3279    }
3280    void Disassemble(const char* name, FILE* out);
3281  #endif  // ENABLE_DISASSEMBLER
3282  
3283    // [instruction_size]: Size of the native instructions
3284    inline int instruction_size();
3285    inline void set_instruction_size(int value);
3286  
3287    // [relocation_info]: Code relocation information
3288    DECL_ACCESSORS(relocation_info, ByteArray)
3289    void InvalidateRelocation();
3290  
3291    // [deoptimization_data]: Array containing data for deopt.
3292    DECL_ACCESSORS(deoptimization_data, FixedArray)
3293  
3294    // Unchecked accessors to be used during GC.
3295    inline ByteArray* unchecked_relocation_info();
3296    inline FixedArray* unchecked_deoptimization_data();
3297  
3298    inline int relocation_size();
3299  
3300    // [flags]: Various code flags.
3301    inline Flags flags();
3302    inline void set_flags(Flags flags);
3303  
3304    // [flags]: Access to specific code flags.
3305    inline Kind kind();
3306    inline InlineCacheState ic_state();  // Only valid for IC stubs.
3307    inline ExtraICState extra_ic_state();  // Only valid for IC stubs.
3308    inline InLoopFlag ic_in_loop();  // Only valid for IC stubs.
3309    inline PropertyType type();  // Only valid for monomorphic IC stubs.
3310    inline int arguments_count();  // Only valid for call IC stubs.
3311  
3312    // Testers for IC stub kinds.
3313    inline bool is_inline_cache_stub();
is_load_stub()3314    inline bool is_load_stub() { return kind() == LOAD_IC; }
is_keyed_load_stub()3315    inline bool is_keyed_load_stub() { return kind() == KEYED_LOAD_IC; }
is_store_stub()3316    inline bool is_store_stub() { return kind() == STORE_IC; }
is_keyed_store_stub()3317    inline bool is_keyed_store_stub() { return kind() == KEYED_STORE_IC; }
is_call_stub()3318    inline bool is_call_stub() { return kind() == CALL_IC; }
is_keyed_call_stub()3319    inline bool is_keyed_call_stub() { return kind() == KEYED_CALL_IC; }
is_type_recording_binary_op_stub()3320    inline bool is_type_recording_binary_op_stub() {
3321      return kind() == TYPE_RECORDING_BINARY_OP_IC;
3322    }
is_compare_ic_stub()3323    inline bool is_compare_ic_stub() { return kind() == COMPARE_IC; }
is_external_array_load_stub()3324    inline bool is_external_array_load_stub() {
3325      return kind() == KEYED_EXTERNAL_ARRAY_LOAD_IC;
3326    }
is_external_array_store_stub()3327    inline bool is_external_array_store_stub() {
3328      return kind() == KEYED_EXTERNAL_ARRAY_STORE_IC;
3329    }
3330  
3331    // [major_key]: For kind STUB or BINARY_OP_IC, the major key.
3332    inline int major_key();
3333    inline void set_major_key(int value);
3334  
3335    // [optimizable]: For FUNCTION kind, tells if it is optimizable.
3336    inline bool optimizable();
3337    inline void set_optimizable(bool value);
3338  
3339    // [has_deoptimization_support]: For FUNCTION kind, tells if it has
3340    // deoptimization support.
3341    inline bool has_deoptimization_support();
3342    inline void set_has_deoptimization_support(bool value);
3343  
3344    // [allow_osr_at_loop_nesting_level]: For FUNCTION kind, tells for
3345    // how long the function has been marked for OSR and therefore which
3346    // level of loop nesting we are willing to do on-stack replacement
3347    // for.
3348    inline void set_allow_osr_at_loop_nesting_level(int level);
3349    inline int allow_osr_at_loop_nesting_level();
3350  
3351    // [stack_slots]: For kind OPTIMIZED_FUNCTION, the number of stack slots
3352    // reserved in the code prologue.
3353    inline unsigned stack_slots();
3354    inline void set_stack_slots(unsigned slots);
3355  
3356    // [safepoint_table_start]: For kind OPTIMIZED_CODE, the offset in
3357    // the instruction stream where the safepoint table starts.
3358    inline unsigned safepoint_table_offset();
3359    inline void set_safepoint_table_offset(unsigned offset);
3360  
3361    // [stack_check_table_start]: For kind FUNCTION, the offset in the
3362    // instruction stream where the stack check table starts.
3363    inline unsigned stack_check_table_offset();
3364    inline void set_stack_check_table_offset(unsigned offset);
3365  
3366    // [check type]: For kind CALL_IC, tells how to check if the
3367    // receiver is valid for the given call.
3368    inline CheckType check_type();
3369    inline void set_check_type(CheckType value);
3370  
3371    // [external array type]: For kind KEYED_EXTERNAL_ARRAY_LOAD_IC and
3372    // KEYED_EXTERNAL_ARRAY_STORE_IC, identifies the type of external
3373    // array that the code stub is specialized for.
3374    inline ExternalArrayType external_array_type();
3375    inline void set_external_array_type(ExternalArrayType value);
3376  
3377    // [type-recording binary op type]: For all TYPE_RECORDING_BINARY_OP_IC.
3378    inline byte type_recording_binary_op_type();
3379    inline void set_type_recording_binary_op_type(byte value);
3380    inline byte type_recording_binary_op_result_type();
3381    inline void set_type_recording_binary_op_result_type(byte value);
3382  
3383    // [compare state]: For kind compare IC stubs, tells what state the
3384    // stub is in.
3385    inline byte compare_state();
3386    inline void set_compare_state(byte value);
3387  
3388    // Get the safepoint entry for the given pc.
3389    SafepointEntry GetSafepointEntry(Address pc);
3390  
3391    // Mark this code object as not having a stack check table.  Assumes kind
3392    // is FUNCTION.
3393    void SetNoStackCheckTable();
3394  
3395    // Find the first map in an IC stub.
3396    Map* FindFirstMap();
3397  
3398    // Flags operations.
3399    static inline Flags ComputeFlags(
3400        Kind kind,
3401        InLoopFlag in_loop = NOT_IN_LOOP,
3402        InlineCacheState ic_state = UNINITIALIZED,
3403        ExtraICState extra_ic_state = kNoExtraICState,
3404        PropertyType type = NORMAL,
3405        int argc = -1,
3406        InlineCacheHolderFlag holder = OWN_MAP);
3407  
3408    static inline Flags ComputeMonomorphicFlags(
3409        Kind kind,
3410        PropertyType type,
3411        ExtraICState extra_ic_state = kNoExtraICState,
3412        InlineCacheHolderFlag holder = OWN_MAP,
3413        InLoopFlag in_loop = NOT_IN_LOOP,
3414        int argc = -1);
3415  
3416    static inline Kind ExtractKindFromFlags(Flags flags);
3417    static inline InlineCacheState ExtractICStateFromFlags(Flags flags);
3418    static inline ExtraICState ExtractExtraICStateFromFlags(Flags flags);
3419    static inline InLoopFlag ExtractICInLoopFromFlags(Flags flags);
3420    static inline PropertyType ExtractTypeFromFlags(Flags flags);
3421    static inline int ExtractArgumentsCountFromFlags(Flags flags);
3422    static inline InlineCacheHolderFlag ExtractCacheHolderFromFlags(Flags flags);
3423    static inline Flags RemoveTypeFromFlags(Flags flags);
3424  
3425    // Convert a target address into a code object.
3426    static inline Code* GetCodeFromTargetAddress(Address address);
3427  
3428    // Convert an entry address into an object.
3429    static inline Object* GetObjectFromEntryAddress(Address location_of_address);
3430  
3431    // Returns the address of the first instruction.
3432    inline byte* instruction_start();
3433  
3434    // Returns the address right after the last instruction.
3435    inline byte* instruction_end();
3436  
3437    // Returns the size of the instructions, padding, and relocation information.
3438    inline int body_size();
3439  
3440    // Returns the address of the first relocation info (read backwards!).
3441    inline byte* relocation_start();
3442  
3443    // Code entry point.
3444    inline byte* entry();
3445  
3446    // Returns true if pc is inside this object's instructions.
3447    inline bool contains(byte* pc);
3448  
3449    // Relocate the code by delta bytes. Called to signal that this code
3450    // object has been moved by delta bytes.
3451    void Relocate(intptr_t delta);
3452  
3453    // Migrate code described by desc.
3454    void CopyFrom(const CodeDesc& desc);
3455  
3456    // Returns the object size for a given body (used for allocation).
SizeFor(int body_size)3457    static int SizeFor(int body_size) {
3458      ASSERT_SIZE_TAG_ALIGNED(body_size);
3459      return RoundUp(kHeaderSize + body_size, kCodeAlignment);
3460    }
3461  
3462    // Calculate the size of the code object to report for log events. This takes
3463    // the layout of the code object into account.
ExecutableSize()3464    int ExecutableSize() {
3465      // Check that the assumptions about the layout of the code object holds.
3466      ASSERT_EQ(static_cast<int>(instruction_start() - address()),
3467                Code::kHeaderSize);
3468      return instruction_size() + Code::kHeaderSize;
3469    }
3470  
3471    // Locating source position.
3472    int SourcePosition(Address pc);
3473    int SourceStatementPosition(Address pc);
3474  
3475    // Casting.
3476    static inline Code* cast(Object* obj);
3477  
3478    // Dispatched behavior.
CodeSize()3479    int CodeSize() { return SizeFor(body_size()); }
3480    inline void CodeIterateBody(ObjectVisitor* v);
3481  
3482    template<typename StaticVisitor>
3483    inline void CodeIterateBody(Heap* heap);
3484  #ifdef OBJECT_PRINT
CodePrint()3485    inline void CodePrint() {
3486      CodePrint(stdout);
3487    }
3488    void CodePrint(FILE* out);
3489  #endif
3490  #ifdef DEBUG
3491    void CodeVerify();
3492  #endif
3493  
3494    // Returns the isolate/heap this code object belongs to.
3495    inline Isolate* isolate();
3496    inline Heap* heap();
3497  
3498    // Max loop nesting marker used to postpose OSR. We don't take loop
3499    // nesting that is deeper than 5 levels into account.
3500    static const int kMaxLoopNestingMarker = 6;
3501  
3502    // Layout description.
3503    static const int kInstructionSizeOffset = HeapObject::kHeaderSize;
3504    static const int kRelocationInfoOffset = kInstructionSizeOffset + kIntSize;
3505    static const int kDeoptimizationDataOffset =
3506        kRelocationInfoOffset + kPointerSize;
3507    static const int kFlagsOffset = kDeoptimizationDataOffset + kPointerSize;
3508    static const int kKindSpecificFlagsOffset  = kFlagsOffset + kIntSize;
3509  
3510    static const int kKindSpecificFlagsSize = 2 * kIntSize;
3511  
3512    static const int kHeaderPaddingStart = kKindSpecificFlagsOffset +
3513        kKindSpecificFlagsSize;
3514  
3515    // Add padding to align the instruction start following right after
3516    // the Code object header.
3517    static const int kHeaderSize =
3518        (kHeaderPaddingStart + kCodeAlignmentMask) & ~kCodeAlignmentMask;
3519  
3520    // Byte offsets within kKindSpecificFlagsOffset.
3521    static const int kStubMajorKeyOffset = kKindSpecificFlagsOffset;
3522    static const int kOptimizableOffset = kKindSpecificFlagsOffset;
3523    static const int kStackSlotsOffset = kKindSpecificFlagsOffset;
3524    static const int kCheckTypeOffset = kKindSpecificFlagsOffset;
3525    static const int kExternalArrayTypeOffset = kKindSpecificFlagsOffset;
3526  
3527    static const int kCompareStateOffset = kStubMajorKeyOffset + 1;
3528    static const int kBinaryOpTypeOffset = kStubMajorKeyOffset + 1;
3529    static const int kHasDeoptimizationSupportOffset = kOptimizableOffset + 1;
3530  
3531    static const int kBinaryOpReturnTypeOffset = kBinaryOpTypeOffset + 1;
3532    static const int kAllowOSRAtLoopNestingLevelOffset =
3533        kHasDeoptimizationSupportOffset + 1;
3534  
3535    static const int kSafepointTableOffsetOffset = kStackSlotsOffset + kIntSize;
3536    static const int kStackCheckTableOffsetOffset = kStackSlotsOffset + kIntSize;
3537  
3538    // Flags layout.
3539    static const int kFlagsICStateShift        = 0;
3540    static const int kFlagsICInLoopShift       = 3;
3541    static const int kFlagsTypeShift           = 4;
3542    static const int kFlagsKindShift           = 8;
3543    static const int kFlagsICHolderShift       = 12;
3544    static const int kFlagsExtraICStateShift   = 13;
3545    static const int kFlagsArgumentsCountShift = 15;
3546  
3547    static const int kFlagsICStateMask        = 0x00000007;  // 00000000111
3548    static const int kFlagsICInLoopMask       = 0x00000008;  // 00000001000
3549    static const int kFlagsTypeMask           = 0x000000F0;  // 00001110000
3550    static const int kFlagsKindMask           = 0x00000F00;  // 11110000000
3551    static const int kFlagsCacheInPrototypeMapMask = 0x00001000;
3552    static const int kFlagsExtraICStateMask   = 0x00006000;
3553    static const int kFlagsArgumentsCountMask = 0xFFFF8000;
3554  
3555    static const int kFlagsNotUsedInLookup =
3556        (kFlagsICInLoopMask | kFlagsTypeMask | kFlagsCacheInPrototypeMapMask);
3557  
3558   private:
3559    DISALLOW_IMPLICIT_CONSTRUCTORS(Code);
3560  };
3561  
3562  
3563  // All heap objects have a Map that describes their structure.
3564  //  A Map contains information about:
3565  //  - Size information about the object
3566  //  - How to iterate over an object (for garbage collection)
3567  class Map: public HeapObject {
3568   public:
3569    // Instance size.
3570    // Size in bytes or kVariableSizeSentinel if instances do not have
3571    // a fixed size.
3572    inline int instance_size();
3573    inline void set_instance_size(int value);
3574  
3575    // Count of properties allocated in the object.
3576    inline int inobject_properties();
3577    inline void set_inobject_properties(int value);
3578  
3579    // Count of property fields pre-allocated in the object when first allocated.
3580    inline int pre_allocated_property_fields();
3581    inline void set_pre_allocated_property_fields(int value);
3582  
3583    // Instance type.
3584    inline InstanceType instance_type();
3585    inline void set_instance_type(InstanceType value);
3586  
3587    // Tells how many unused property fields are available in the
3588    // instance (only used for JSObject in fast mode).
3589    inline int unused_property_fields();
3590    inline void set_unused_property_fields(int value);
3591  
3592    // Bit field.
3593    inline byte bit_field();
3594    inline void set_bit_field(byte value);
3595  
3596    // Bit field 2.
3597    inline byte bit_field2();
3598    inline void set_bit_field2(byte value);
3599  
3600    // Tells whether the object in the prototype property will be used
3601    // for instances created from this function.  If the prototype
3602    // property is set to a value that is not a JSObject, the prototype
3603    // property will not be used to create instances of the function.
3604    // See ECMA-262, 13.2.2.
3605    inline void set_non_instance_prototype(bool value);
3606    inline bool has_non_instance_prototype();
3607  
3608    // Tells whether function has special prototype property. If not, prototype
3609    // property will not be created when accessed (will return undefined),
3610    // and construction from this function will not be allowed.
3611    inline void set_function_with_prototype(bool value);
3612    inline bool function_with_prototype();
3613  
3614    // Tells whether the instance with this map should be ignored by the
3615    // __proto__ accessor.
set_is_hidden_prototype()3616    inline void set_is_hidden_prototype() {
3617      set_bit_field(bit_field() | (1 << kIsHiddenPrototype));
3618    }
3619  
is_hidden_prototype()3620    inline bool is_hidden_prototype() {
3621      return ((1 << kIsHiddenPrototype) & bit_field()) != 0;
3622    }
3623  
3624    // Records and queries whether the instance has a named interceptor.
set_has_named_interceptor()3625    inline void set_has_named_interceptor() {
3626      set_bit_field(bit_field() | (1 << kHasNamedInterceptor));
3627    }
3628  
has_named_interceptor()3629    inline bool has_named_interceptor() {
3630      return ((1 << kHasNamedInterceptor) & bit_field()) != 0;
3631    }
3632  
3633    // Records and queries whether the instance has an indexed interceptor.
set_has_indexed_interceptor()3634    inline void set_has_indexed_interceptor() {
3635      set_bit_field(bit_field() | (1 << kHasIndexedInterceptor));
3636    }
3637  
has_indexed_interceptor()3638    inline bool has_indexed_interceptor() {
3639      return ((1 << kHasIndexedInterceptor) & bit_field()) != 0;
3640    }
3641  
3642    // Tells whether the instance is undetectable.
3643    // An undetectable object is a special class of JSObject: 'typeof' operator
3644    // returns undefined, ToBoolean returns false. Otherwise it behaves like
3645    // a normal JS object.  It is useful for implementing undetectable
3646    // document.all in Firefox & Safari.
3647    // See https://bugzilla.mozilla.org/show_bug.cgi?id=248549.
set_is_undetectable()3648    inline void set_is_undetectable() {
3649      set_bit_field(bit_field() | (1 << kIsUndetectable));
3650    }
3651  
is_undetectable()3652    inline bool is_undetectable() {
3653      return ((1 << kIsUndetectable) & bit_field()) != 0;
3654    }
3655  
3656    // Tells whether the instance has a call-as-function handler.
set_has_instance_call_handler()3657    inline void set_has_instance_call_handler() {
3658      set_bit_field(bit_field() | (1 << kHasInstanceCallHandler));
3659    }
3660  
has_instance_call_handler()3661    inline bool has_instance_call_handler() {
3662      return ((1 << kHasInstanceCallHandler) & bit_field()) != 0;
3663    }
3664  
3665    inline void set_is_extensible(bool value);
3666    inline bool is_extensible();
3667  
3668    // Tells whether the instance has fast elements.
3669    // Equivalent to instance->GetElementsKind() == FAST_ELEMENTS.
set_has_fast_elements(bool value)3670    inline void set_has_fast_elements(bool value) {
3671      if (value) {
3672        set_bit_field2(bit_field2() | (1 << kHasFastElements));
3673      } else {
3674        set_bit_field2(bit_field2() & ~(1 << kHasFastElements));
3675      }
3676    }
3677  
has_fast_elements()3678    inline bool has_fast_elements() {
3679      return ((1 << kHasFastElements) & bit_field2()) != 0;
3680    }
3681  
3682    // Tells whether an instance has pixel array elements.
set_has_external_array_elements(bool value)3683    inline void set_has_external_array_elements(bool value) {
3684      if (value) {
3685        set_bit_field2(bit_field2() | (1 << kHasExternalArrayElements));
3686      } else {
3687        set_bit_field2(bit_field2() & ~(1 << kHasExternalArrayElements));
3688      }
3689    }
3690  
has_external_array_elements()3691    inline bool has_external_array_elements() {
3692      return ((1 << kHasExternalArrayElements) & bit_field2()) != 0;
3693    }
3694  
3695    // Tells whether the map is attached to SharedFunctionInfo
3696    // (for inobject slack tracking).
3697    inline void set_attached_to_shared_function_info(bool value);
3698  
3699    inline bool attached_to_shared_function_info();
3700  
3701    // Tells whether the map is shared between objects that may have different
3702    // behavior. If true, the map should never be modified, instead a clone
3703    // should be created and modified.
3704    inline void set_is_shared(bool value);
3705  
3706    inline bool is_shared();
3707  
3708    // Tells whether the instance needs security checks when accessing its
3709    // properties.
3710    inline void set_is_access_check_needed(bool access_check_needed);
3711    inline bool is_access_check_needed();
3712  
3713    // [prototype]: implicit prototype object.
3714    DECL_ACCESSORS(prototype, Object)
3715  
3716    // [constructor]: points back to the function responsible for this map.
3717    DECL_ACCESSORS(constructor, Object)
3718  
3719    inline JSFunction* unchecked_constructor();
3720  
3721    // [instance descriptors]: describes the object.
3722    DECL_ACCESSORS(instance_descriptors, DescriptorArray)
3723  
3724    // [stub cache]: contains stubs compiled for this map.
3725    DECL_ACCESSORS(code_cache, Object)
3726  
3727    // [prototype transitions]: cache of prototype transitions.
3728    // Prototype transition is a transition that happens
3729    // when we change object's prototype to a new one.
3730    // Cache format:
3731    //    0: finger - index of the first free cell in the cache
3732    //    1 + 2 * i: prototype
3733    //    2 + 2 * i: target map
3734    DECL_ACCESSORS(prototype_transitions, FixedArray)
3735    inline FixedArray* unchecked_prototype_transitions();
3736  
3737    // Lookup in the map's instance descriptors and fill out the result
3738    // with the given holder if the name is found. The holder may be
3739    // NULL when this function is used from the compiler.
3740    void LookupInDescriptors(JSObject* holder,
3741                             String* name,
3742                             LookupResult* result);
3743  
3744    MUST_USE_RESULT MaybeObject* CopyDropDescriptors();
3745  
3746    MUST_USE_RESULT MaybeObject* CopyNormalized(PropertyNormalizationMode mode,
3747                                                NormalizedMapSharingMode sharing);
3748  
3749    // Returns a copy of the map, with all transitions dropped from the
3750    // instance descriptors.
3751    MUST_USE_RESULT MaybeObject* CopyDropTransitions();
3752  
3753    // Returns this map if it has the fast elements bit set, otherwise
3754    // returns a copy of the map, with all transitions dropped from the
3755    // descriptors and the fast elements bit set.
3756    MUST_USE_RESULT inline MaybeObject* GetFastElementsMap();
3757  
3758    // Returns this map if it has the fast elements bit cleared,
3759    // otherwise returns a copy of the map, with all transitions dropped
3760    // from the descriptors and the fast elements bit cleared.
3761    MUST_USE_RESULT inline MaybeObject* GetSlowElementsMap();
3762  
3763    // Returns a new map with all transitions dropped from the descriptors and the
3764    // external array elements bit set.
3765    MUST_USE_RESULT MaybeObject* GetExternalArrayElementsMap(
3766        ExternalArrayType array_type,
3767        bool safe_to_add_transition);
3768  
3769    // Returns the property index for name (only valid for FAST MODE).
3770    int PropertyIndexFor(String* name);
3771  
3772    // Returns the next free property index (only valid for FAST MODE).
3773    int NextFreePropertyIndex();
3774  
3775    // Returns the number of properties described in instance_descriptors.
3776    int NumberOfDescribedProperties();
3777  
3778    // Casting.
3779    static inline Map* cast(Object* obj);
3780  
3781    // Locate an accessor in the instance descriptor.
3782    AccessorDescriptor* FindAccessor(String* name);
3783  
3784    // Code cache operations.
3785  
3786    // Clears the code cache.
3787    inline void ClearCodeCache(Heap* heap);
3788  
3789    // Update code cache.
3790    MUST_USE_RESULT MaybeObject* UpdateCodeCache(String* name, Code* code);
3791  
3792    // Returns the found code or undefined if absent.
3793    Object* FindInCodeCache(String* name, Code::Flags flags);
3794  
3795    // Returns the non-negative index of the code object if it is in the
3796    // cache and -1 otherwise.
3797    int IndexInCodeCache(Object* name, Code* code);
3798  
3799    // Removes a code object from the code cache at the given index.
3800    void RemoveFromCodeCache(String* name, Code* code, int index);
3801  
3802    // For every transition in this map, makes the transition's
3803    // target's prototype pointer point back to this map.
3804    // This is undone in MarkCompactCollector::ClearNonLiveTransitions().
3805    void CreateBackPointers();
3806  
3807    // Set all map transitions from this map to dead maps to null.
3808    // Also, restore the original prototype on the targets of these
3809    // transitions, so that we do not process this map again while
3810    // following back pointers.
3811    void ClearNonLiveTransitions(Heap* heap, Object* real_prototype);
3812  
3813    // Dispatched behavior.
3814  #ifdef OBJECT_PRINT
MapPrint()3815    inline void MapPrint() {
3816      MapPrint(stdout);
3817    }
3818    void MapPrint(FILE* out);
3819  #endif
3820  #ifdef DEBUG
3821    void MapVerify();
3822    void SharedMapVerify();
3823  #endif
3824  
3825    inline int visitor_id();
3826    inline void set_visitor_id(int visitor_id);
3827  
3828    // Returns the isolate/heap this map belongs to.
3829    inline Isolate* isolate();
3830    inline Heap* heap();
3831  
3832    typedef void (*TraverseCallback)(Map* map, void* data);
3833  
3834    void TraverseTransitionTree(TraverseCallback callback, void* data);
3835  
3836    static const int kMaxCachedPrototypeTransitions = 256;
3837  
3838    Object* GetPrototypeTransition(Object* prototype);
3839  
3840    MaybeObject* PutPrototypeTransition(Object* prototype, Map* map);
3841  
3842    static const int kMaxPreAllocatedPropertyFields = 255;
3843  
3844    // Layout description.
3845    static const int kInstanceSizesOffset = HeapObject::kHeaderSize;
3846    static const int kInstanceAttributesOffset = kInstanceSizesOffset + kIntSize;
3847    static const int kPrototypeOffset = kInstanceAttributesOffset + kIntSize;
3848    static const int kConstructorOffset = kPrototypeOffset + kPointerSize;
3849    static const int kInstanceDescriptorsOffset =
3850        kConstructorOffset + kPointerSize;
3851    static const int kCodeCacheOffset = kInstanceDescriptorsOffset + kPointerSize;
3852    static const int kPrototypeTransitionsOffset =
3853        kCodeCacheOffset + kPointerSize;
3854    static const int kPadStart = kPrototypeTransitionsOffset + kPointerSize;
3855    static const int kSize = MAP_POINTER_ALIGN(kPadStart);
3856  
3857    // Layout of pointer fields. Heap iteration code relies on them
3858    // being continiously allocated.
3859    static const int kPointerFieldsBeginOffset = Map::kPrototypeOffset;
3860    static const int kPointerFieldsEndOffset =
3861        Map::kPrototypeTransitionsOffset + kPointerSize;
3862  
3863    // Byte offsets within kInstanceSizesOffset.
3864    static const int kInstanceSizeOffset = kInstanceSizesOffset + 0;
3865    static const int kInObjectPropertiesByte = 1;
3866    static const int kInObjectPropertiesOffset =
3867        kInstanceSizesOffset + kInObjectPropertiesByte;
3868    static const int kPreAllocatedPropertyFieldsByte = 2;
3869    static const int kPreAllocatedPropertyFieldsOffset =
3870        kInstanceSizesOffset + kPreAllocatedPropertyFieldsByte;
3871    static const int kVisitorIdByte = 3;
3872    static const int kVisitorIdOffset = kInstanceSizesOffset + kVisitorIdByte;
3873  
3874    // Byte offsets within kInstanceAttributesOffset attributes.
3875    static const int kInstanceTypeOffset = kInstanceAttributesOffset + 0;
3876    static const int kUnusedPropertyFieldsOffset = kInstanceAttributesOffset + 1;
3877    static const int kBitFieldOffset = kInstanceAttributesOffset + 2;
3878    static const int kBitField2Offset = kInstanceAttributesOffset + 3;
3879  
3880    STATIC_CHECK(kInstanceTypeOffset == Internals::kMapInstanceTypeOffset);
3881  
3882    // Bit positions for bit field.
3883    static const int kUnused = 0;  // To be used for marking recently used maps.
3884    static const int kHasNonInstancePrototype = 1;
3885    static const int kIsHiddenPrototype = 2;
3886    static const int kHasNamedInterceptor = 3;
3887    static const int kHasIndexedInterceptor = 4;
3888    static const int kIsUndetectable = 5;
3889    static const int kHasInstanceCallHandler = 6;
3890    static const int kIsAccessCheckNeeded = 7;
3891  
3892    // Bit positions for bit field 2
3893    static const int kIsExtensible = 0;
3894    static const int kFunctionWithPrototype = 1;
3895    static const int kHasFastElements = 2;
3896    static const int kStringWrapperSafeForDefaultValueOf = 3;
3897    static const int kAttachedToSharedFunctionInfo = 4;
3898    static const int kIsShared = 5;
3899    static const int kHasExternalArrayElements = 6;
3900  
3901    // Layout of the default cache. It holds alternating name and code objects.
3902    static const int kCodeCacheEntrySize = 2;
3903    static const int kCodeCacheEntryNameOffset = 0;
3904    static const int kCodeCacheEntryCodeOffset = 1;
3905  
3906    typedef FixedBodyDescriptor<kPointerFieldsBeginOffset,
3907                                kPointerFieldsEndOffset,
3908                                kSize> BodyDescriptor;
3909  
3910   private:
3911    DISALLOW_IMPLICIT_CONSTRUCTORS(Map);
3912  };
3913  
3914  
3915  // An abstract superclass, a marker class really, for simple structure classes.
3916  // It doesn't carry much functionality but allows struct classes to me
3917  // identified in the type system.
3918  class Struct: public HeapObject {
3919   public:
3920    inline void InitializeBody(int object_size);
3921    static inline Struct* cast(Object* that);
3922  };
3923  
3924  
3925  // Script describes a script which has been added to the VM.
3926  class Script: public Struct {
3927   public:
3928    // Script types.
3929    enum Type {
3930      TYPE_NATIVE = 0,
3931      TYPE_EXTENSION = 1,
3932      TYPE_NORMAL = 2
3933    };
3934  
3935    // Script compilation types.
3936    enum CompilationType {
3937      COMPILATION_TYPE_HOST = 0,
3938      COMPILATION_TYPE_EVAL = 1
3939    };
3940  
3941    // [source]: the script source.
3942    DECL_ACCESSORS(source, Object)
3943  
3944    // [name]: the script name.
3945    DECL_ACCESSORS(name, Object)
3946  
3947    // [id]: the script id.
3948    DECL_ACCESSORS(id, Object)
3949  
3950    // [line_offset]: script line offset in resource from where it was extracted.
3951    DECL_ACCESSORS(line_offset, Smi)
3952  
3953    // [column_offset]: script column offset in resource from where it was
3954    // extracted.
3955    DECL_ACCESSORS(column_offset, Smi)
3956  
3957    // [data]: additional data associated with this script.
3958    DECL_ACCESSORS(data, Object)
3959  
3960    // [context_data]: context data for the context this script was compiled in.
3961    DECL_ACCESSORS(context_data, Object)
3962  
3963    // [wrapper]: the wrapper cache.
3964    DECL_ACCESSORS(wrapper, Proxy)
3965  
3966    // [type]: the script type.
3967    DECL_ACCESSORS(type, Smi)
3968  
3969    // [compilation]: how the the script was compiled.
3970    DECL_ACCESSORS(compilation_type, Smi)
3971  
3972    // [line_ends]: FixedArray of line ends positions.
3973    DECL_ACCESSORS(line_ends, Object)
3974  
3975    // [eval_from_shared]: for eval scripts the shared funcion info for the
3976    // function from which eval was called.
3977    DECL_ACCESSORS(eval_from_shared, Object)
3978  
3979    // [eval_from_instructions_offset]: the instruction offset in the code for the
3980    // function from which eval was called where eval was called.
3981    DECL_ACCESSORS(eval_from_instructions_offset, Smi)
3982  
3983    static inline Script* cast(Object* obj);
3984  
3985    // If script source is an external string, check that the underlying
3986    // resource is accessible. Otherwise, always return true.
3987    inline bool HasValidSource();
3988  
3989  #ifdef OBJECT_PRINT
ScriptPrint()3990    inline void ScriptPrint() {
3991      ScriptPrint(stdout);
3992    }
3993    void ScriptPrint(FILE* out);
3994  #endif
3995  #ifdef DEBUG
3996    void ScriptVerify();
3997  #endif
3998  
3999    static const int kSourceOffset = HeapObject::kHeaderSize;
4000    static const int kNameOffset = kSourceOffset + kPointerSize;
4001    static const int kLineOffsetOffset = kNameOffset + kPointerSize;
4002    static const int kColumnOffsetOffset = kLineOffsetOffset + kPointerSize;
4003    static const int kDataOffset = kColumnOffsetOffset + kPointerSize;
4004    static const int kContextOffset = kDataOffset + kPointerSize;
4005    static const int kWrapperOffset = kContextOffset + kPointerSize;
4006    static const int kTypeOffset = kWrapperOffset + kPointerSize;
4007    static const int kCompilationTypeOffset = kTypeOffset + kPointerSize;
4008    static const int kLineEndsOffset = kCompilationTypeOffset + kPointerSize;
4009    static const int kIdOffset = kLineEndsOffset + kPointerSize;
4010    static const int kEvalFromSharedOffset = kIdOffset + kPointerSize;
4011    static const int kEvalFrominstructionsOffsetOffset =
4012        kEvalFromSharedOffset + kPointerSize;
4013    static const int kSize = kEvalFrominstructionsOffsetOffset + kPointerSize;
4014  
4015   private:
4016    DISALLOW_IMPLICIT_CONSTRUCTORS(Script);
4017  };
4018  
4019  
4020  // List of builtin functions we want to identify to improve code
4021  // generation.
4022  //
4023  // Each entry has a name of a global object property holding an object
4024  // optionally followed by ".prototype", a name of a builtin function
4025  // on the object (the one the id is set for), and a label.
4026  //
4027  // Installation of ids for the selected builtin functions is handled
4028  // by the bootstrapper.
4029  //
4030  // NOTE: Order is important: math functions should be at the end of
4031  // the list and MathFloor should be the first math function.
4032  #define FUNCTIONS_WITH_ID_LIST(V)                   \
4033    V(Array.prototype, push, ArrayPush)               \
4034    V(Array.prototype, pop, ArrayPop)                 \
4035    V(Function.prototype, apply, FunctionApply)       \
4036    V(String.prototype, charCodeAt, StringCharCodeAt) \
4037    V(String.prototype, charAt, StringCharAt)         \
4038    V(String, fromCharCode, StringFromCharCode)       \
4039    V(Math, floor, MathFloor)                         \
4040    V(Math, round, MathRound)                         \
4041    V(Math, ceil, MathCeil)                           \
4042    V(Math, abs, MathAbs)                             \
4043    V(Math, log, MathLog)                             \
4044    V(Math, sin, MathSin)                             \
4045    V(Math, cos, MathCos)                             \
4046    V(Math, tan, MathTan)                             \
4047    V(Math, asin, MathASin)                           \
4048    V(Math, acos, MathACos)                           \
4049    V(Math, atan, MathATan)                           \
4050    V(Math, exp, MathExp)                             \
4051    V(Math, sqrt, MathSqrt)                           \
4052    V(Math, pow, MathPow)
4053  
4054  
4055  enum BuiltinFunctionId {
4056  #define DECLARE_FUNCTION_ID(ignored1, ignore2, name)    \
4057    k##name,
4058    FUNCTIONS_WITH_ID_LIST(DECLARE_FUNCTION_ID)
4059  #undef DECLARE_FUNCTION_ID
4060    // Fake id for a special case of Math.pow. Note, it continues the
4061    // list of math functions.
4062    kMathPowHalf,
4063    kFirstMathFunctionId = kMathFloor
4064  };
4065  
4066  
4067  // SharedFunctionInfo describes the JSFunction information that can be
4068  // shared by multiple instances of the function.
4069  class SharedFunctionInfo: public HeapObject {
4070   public:
4071    // [name]: Function name.
4072    DECL_ACCESSORS(name, Object)
4073  
4074    // [code]: Function code.
4075    DECL_ACCESSORS(code, Code)
4076  
4077    // [scope_info]: Scope info.
4078    DECL_ACCESSORS(scope_info, SerializedScopeInfo)
4079  
4080    // [construct stub]: Code stub for constructing instances of this function.
4081    DECL_ACCESSORS(construct_stub, Code)
4082  
4083    inline Code* unchecked_code();
4084  
4085    // Returns if this function has been compiled to native code yet.
4086    inline bool is_compiled();
4087  
4088    // [length]: The function length - usually the number of declared parameters.
4089    // Use up to 2^30 parameters.
4090    inline int length();
4091    inline void set_length(int value);
4092  
4093    // [formal parameter count]: The declared number of parameters.
4094    inline int formal_parameter_count();
4095    inline void set_formal_parameter_count(int value);
4096  
4097    // Set the formal parameter count so the function code will be
4098    // called without using argument adaptor frames.
4099    inline void DontAdaptArguments();
4100  
4101    // [expected_nof_properties]: Expected number of properties for the function.
4102    inline int expected_nof_properties();
4103    inline void set_expected_nof_properties(int value);
4104  
4105    // Inobject slack tracking is the way to reclaim unused inobject space.
4106    //
4107    // The instance size is initially determined by adding some slack to
4108    // expected_nof_properties (to allow for a few extra properties added
4109    // after the constructor). There is no guarantee that the extra space
4110    // will not be wasted.
4111    //
4112    // Here is the algorithm to reclaim the unused inobject space:
4113    // - Detect the first constructor call for this SharedFunctionInfo.
4114    //   When it happens enter the "in progress" state: remember the
4115    //   constructor's initial_map and install a special construct stub that
4116    //   counts constructor calls.
4117    // - While the tracking is in progress create objects filled with
4118    //   one_pointer_filler_map instead of undefined_value. This way they can be
4119    //   resized quickly and safely.
4120    // - Once enough (kGenerousAllocationCount) objects have been created
4121    //   compute the 'slack' (traverse the map transition tree starting from the
4122    //   initial_map and find the lowest value of unused_property_fields).
4123    // - Traverse the transition tree again and decrease the instance size
4124    //   of every map. Existing objects will resize automatically (they are
4125    //   filled with one_pointer_filler_map). All further allocations will
4126    //   use the adjusted instance size.
4127    // - Decrease expected_nof_properties so that an allocations made from
4128    //   another context will use the adjusted instance size too.
4129    // - Exit "in progress" state by clearing the reference to the initial_map
4130    //   and setting the regular construct stub (generic or inline).
4131    //
4132    //  The above is the main event sequence. Some special cases are possible
4133    //  while the tracking is in progress:
4134    //
4135    // - GC occurs.
4136    //   Check if the initial_map is referenced by any live objects (except this
4137    //   SharedFunctionInfo). If it is, continue tracking as usual.
4138    //   If it is not, clear the reference and reset the tracking state. The
4139    //   tracking will be initiated again on the next constructor call.
4140    //
4141    // - The constructor is called from another context.
4142    //   Immediately complete the tracking, perform all the necessary changes
4143    //   to maps. This is  necessary because there is no efficient way to track
4144    //   multiple initial_maps.
4145    //   Proceed to create an object in the current context (with the adjusted
4146    //   size).
4147    //
4148    // - A different constructor function sharing the same SharedFunctionInfo is
4149    //   called in the same context. This could be another closure in the same
4150    //   context, or the first function could have been disposed.
4151    //   This is handled the same way as the previous case.
4152    //
4153    //  Important: inobject slack tracking is not attempted during the snapshot
4154    //  creation.
4155  
4156    static const int kGenerousAllocationCount = 8;
4157  
4158    // [construction_count]: Counter for constructor calls made during
4159    // the tracking phase.
4160    inline int construction_count();
4161    inline void set_construction_count(int value);
4162  
4163    // [initial_map]: initial map of the first function called as a constructor.
4164    // Saved for the duration of the tracking phase.
4165    // This is a weak link (GC resets it to undefined_value if no other live
4166    // object reference this map).
4167    DECL_ACCESSORS(initial_map, Object)
4168  
4169    // True if the initial_map is not undefined and the countdown stub is
4170    // installed.
4171    inline bool IsInobjectSlackTrackingInProgress();
4172  
4173    // Starts the tracking.
4174    // Stores the initial map and installs the countdown stub.
4175    // IsInobjectSlackTrackingInProgress is normally true after this call,
4176    // except when tracking have not been started (e.g. the map has no unused
4177    // properties or the snapshot is being built).
4178    void StartInobjectSlackTracking(Map* map);
4179  
4180    // Completes the tracking.
4181    // IsInobjectSlackTrackingInProgress is false after this call.
4182    void CompleteInobjectSlackTracking();
4183  
4184    // Clears the initial_map before the GC marking phase to ensure the reference
4185    // is weak. IsInobjectSlackTrackingInProgress is false after this call.
4186    void DetachInitialMap();
4187  
4188    // Restores the link to the initial map after the GC marking phase.
4189    // IsInobjectSlackTrackingInProgress is true after this call.
4190    void AttachInitialMap(Map* map);
4191  
4192    // False if there are definitely no live objects created from this function.
4193    // True if live objects _may_ exist (existence not guaranteed).
4194    // May go back from true to false after GC.
4195    inline bool live_objects_may_exist();
4196  
4197    inline void set_live_objects_may_exist(bool value);
4198  
4199    // [instance class name]: class name for instances.
4200    DECL_ACCESSORS(instance_class_name, Object)
4201  
4202    // [function data]: This field holds some additional data for function.
4203    // Currently it either has FunctionTemplateInfo to make benefit the API
4204    // or Smi identifying a builtin function.
4205    // In the long run we don't want all functions to have this field but
4206    // we can fix that when we have a better model for storing hidden data
4207    // on objects.
4208    DECL_ACCESSORS(function_data, Object)
4209  
4210    inline bool IsApiFunction();
4211    inline FunctionTemplateInfo* get_api_func_data();
4212    inline bool HasBuiltinFunctionId();
4213    inline BuiltinFunctionId builtin_function_id();
4214  
4215    // [script info]: Script from which the function originates.
4216    DECL_ACCESSORS(script, Object)
4217  
4218    // [num_literals]: Number of literals used by this function.
4219    inline int num_literals();
4220    inline void set_num_literals(int value);
4221  
4222    // [start_position_and_type]: Field used to store both the source code
4223    // position, whether or not the function is a function expression,
4224    // and whether or not the function is a toplevel function. The two
4225    // least significants bit indicates whether the function is an
4226    // expression and the rest contains the source code position.
4227    inline int start_position_and_type();
4228    inline void set_start_position_and_type(int value);
4229  
4230    // [debug info]: Debug information.
4231    DECL_ACCESSORS(debug_info, Object)
4232  
4233    // [inferred name]: Name inferred from variable or property
4234    // assignment of this function. Used to facilitate debugging and
4235    // profiling of JavaScript code written in OO style, where almost
4236    // all functions are anonymous but are assigned to object
4237    // properties.
4238    DECL_ACCESSORS(inferred_name, String)
4239  
4240    // The function's name if it is non-empty, otherwise the inferred name.
4241    String* DebugName();
4242  
4243    // Position of the 'function' token in the script source.
4244    inline int function_token_position();
4245    inline void set_function_token_position(int function_token_position);
4246  
4247    // Position of this function in the script source.
4248    inline int start_position();
4249    inline void set_start_position(int start_position);
4250  
4251    // End position of this function in the script source.
4252    inline int end_position();
4253    inline void set_end_position(int end_position);
4254  
4255    // Is this function a function expression in the source code.
4256    inline bool is_expression();
4257    inline void set_is_expression(bool value);
4258  
4259    // Is this function a top-level function (scripts, evals).
4260    inline bool is_toplevel();
4261    inline void set_is_toplevel(bool value);
4262  
4263    // Bit field containing various information collected by the compiler to
4264    // drive optimization.
4265    inline int compiler_hints();
4266    inline void set_compiler_hints(int value);
4267  
4268    // A counter used to determine when to stress the deoptimizer with a
4269    // deopt.
4270    inline Smi* deopt_counter();
4271    inline void set_deopt_counter(Smi* counter);
4272  
4273    // Add information on assignments of the form this.x = ...;
4274    void SetThisPropertyAssignmentsInfo(
4275        bool has_only_simple_this_property_assignments,
4276        FixedArray* this_property_assignments);
4277  
4278    // Clear information on assignments of the form this.x = ...;
4279    void ClearThisPropertyAssignmentsInfo();
4280  
4281    // Indicate that this function only consists of assignments of the form
4282    // this.x = y; where y is either a constant or refers to an argument.
4283    inline bool has_only_simple_this_property_assignments();
4284  
4285    // Indicates if this function can be lazy compiled.
4286    // This is used to determine if we can safely flush code from a function
4287    // when doing GC if we expect that the function will no longer be used.
4288    inline bool allows_lazy_compilation();
4289    inline void set_allows_lazy_compilation(bool flag);
4290  
4291    // Indicates how many full GCs this function has survived with assigned
4292    // code object. Used to determine when it is relatively safe to flush
4293    // this code object and replace it with lazy compilation stub.
4294    // Age is reset when GC notices that the code object is referenced
4295    // from the stack or compilation cache.
4296    inline int code_age();
4297    inline void set_code_age(int age);
4298  
4299    // Indicates whether optimizations have been disabled for this
4300    // shared function info. If a function is repeatedly optimized or if
4301    // we cannot optimize the function we disable optimization to avoid
4302    // spending time attempting to optimize it again.
4303    inline bool optimization_disabled();
4304    inline void set_optimization_disabled(bool value);
4305  
4306    // Indicates whether the function is a strict mode function.
4307    inline bool strict_mode();
4308    inline void set_strict_mode(bool value);
4309  
4310    // Indicates whether or not the code in the shared function support
4311    // deoptimization.
4312    inline bool has_deoptimization_support();
4313  
4314    // Enable deoptimization support through recompiled code.
4315    void EnableDeoptimizationSupport(Code* recompiled);
4316  
4317    // Lookup the bailout ID and ASSERT that it exists in the non-optimized
4318    // code, returns whether it asserted (i.e., always true if assertions are
4319    // disabled).
4320    bool VerifyBailoutId(int id);
4321  
4322    // Check whether a inlined constructor can be generated with the given
4323    // prototype.
4324    bool CanGenerateInlineConstructor(Object* prototype);
4325  
4326    // Prevents further attempts to generate inline constructors.
4327    // To be called if generation failed for any reason.
4328    void ForbidInlineConstructor();
4329  
4330    // For functions which only contains this property assignments this provides
4331    // access to the names for the properties assigned.
4332    DECL_ACCESSORS(this_property_assignments, Object)
4333    inline int this_property_assignments_count();
4334    inline void set_this_property_assignments_count(int value);
4335    String* GetThisPropertyAssignmentName(int index);
4336    bool IsThisPropertyAssignmentArgument(int index);
4337    int GetThisPropertyAssignmentArgument(int index);
4338    Object* GetThisPropertyAssignmentConstant(int index);
4339  
4340    // [source code]: Source code for the function.
4341    bool HasSourceCode();
4342    Object* GetSourceCode();
4343  
4344    inline int opt_count();
4345    inline void set_opt_count(int opt_count);
4346  
4347    // Source size of this function.
4348    int SourceSize();
4349  
4350    // Calculate the instance size.
4351    int CalculateInstanceSize();
4352  
4353    // Calculate the number of in-object properties.
4354    int CalculateInObjectProperties();
4355  
4356    // Dispatched behavior.
4357    // Set max_length to -1 for unlimited length.
4358    void SourceCodePrint(StringStream* accumulator, int max_length);
4359  #ifdef OBJECT_PRINT
SharedFunctionInfoPrint()4360    inline void SharedFunctionInfoPrint() {
4361      SharedFunctionInfoPrint(stdout);
4362    }
4363    void SharedFunctionInfoPrint(FILE* out);
4364  #endif
4365  #ifdef DEBUG
4366    void SharedFunctionInfoVerify();
4367  #endif
4368  
4369    // Casting.
4370    static inline SharedFunctionInfo* cast(Object* obj);
4371  
4372    // Constants.
4373    static const int kDontAdaptArgumentsSentinel = -1;
4374  
4375    // Layout description.
4376    // Pointer fields.
4377    static const int kNameOffset = HeapObject::kHeaderSize;
4378    static const int kCodeOffset = kNameOffset + kPointerSize;
4379    static const int kScopeInfoOffset = kCodeOffset + kPointerSize;
4380    static const int kConstructStubOffset = kScopeInfoOffset + kPointerSize;
4381    static const int kInstanceClassNameOffset =
4382        kConstructStubOffset + kPointerSize;
4383    static const int kFunctionDataOffset =
4384        kInstanceClassNameOffset + kPointerSize;
4385    static const int kScriptOffset = kFunctionDataOffset + kPointerSize;
4386    static const int kDebugInfoOffset = kScriptOffset + kPointerSize;
4387    static const int kInferredNameOffset = kDebugInfoOffset + kPointerSize;
4388    static const int kInitialMapOffset =
4389        kInferredNameOffset + kPointerSize;
4390    static const int kThisPropertyAssignmentsOffset =
4391        kInitialMapOffset + kPointerSize;
4392    static const int kDeoptCounterOffset =
4393        kThisPropertyAssignmentsOffset + kPointerSize;
4394  #if V8_HOST_ARCH_32_BIT
4395    // Smi fields.
4396    static const int kLengthOffset =
4397        kDeoptCounterOffset + kPointerSize;
4398    static const int kFormalParameterCountOffset = kLengthOffset + kPointerSize;
4399    static const int kExpectedNofPropertiesOffset =
4400        kFormalParameterCountOffset + kPointerSize;
4401    static const int kNumLiteralsOffset =
4402        kExpectedNofPropertiesOffset + kPointerSize;
4403    static const int kStartPositionAndTypeOffset =
4404        kNumLiteralsOffset + kPointerSize;
4405    static const int kEndPositionOffset =
4406        kStartPositionAndTypeOffset + kPointerSize;
4407    static const int kFunctionTokenPositionOffset =
4408        kEndPositionOffset + kPointerSize;
4409    static const int kCompilerHintsOffset =
4410        kFunctionTokenPositionOffset + kPointerSize;
4411    static const int kThisPropertyAssignmentsCountOffset =
4412        kCompilerHintsOffset + kPointerSize;
4413    static const int kOptCountOffset =
4414        kThisPropertyAssignmentsCountOffset + kPointerSize;
4415    // Total size.
4416    static const int kSize = kOptCountOffset + kPointerSize;
4417  #else
4418    // The only reason to use smi fields instead of int fields
4419    // is to allow iteration without maps decoding during
4420    // garbage collections.
4421    // To avoid wasting space on 64-bit architectures we use
4422    // the following trick: we group integer fields into pairs
4423    // First integer in each pair is shifted left by 1.
4424    // By doing this we guarantee that LSB of each kPointerSize aligned
4425    // word is not set and thus this word cannot be treated as pointer
4426    // to HeapObject during old space traversal.
4427    static const int kLengthOffset =
4428        kDeoptCounterOffset + kPointerSize;
4429    static const int kFormalParameterCountOffset =
4430        kLengthOffset + kIntSize;
4431  
4432    static const int kExpectedNofPropertiesOffset =
4433        kFormalParameterCountOffset + kIntSize;
4434    static const int kNumLiteralsOffset =
4435        kExpectedNofPropertiesOffset + kIntSize;
4436  
4437    static const int kEndPositionOffset =
4438        kNumLiteralsOffset + kIntSize;
4439    static const int kStartPositionAndTypeOffset =
4440        kEndPositionOffset + kIntSize;
4441  
4442    static const int kFunctionTokenPositionOffset =
4443        kStartPositionAndTypeOffset + kIntSize;
4444    static const int kCompilerHintsOffset =
4445        kFunctionTokenPositionOffset + kIntSize;
4446  
4447    static const int kThisPropertyAssignmentsCountOffset =
4448        kCompilerHintsOffset + kIntSize;
4449    static const int kOptCountOffset =
4450        kThisPropertyAssignmentsCountOffset + kIntSize;
4451  
4452    // Total size.
4453    static const int kSize = kOptCountOffset + kIntSize;
4454  
4455  #endif
4456  
4457    // The construction counter for inobject slack tracking is stored in the
4458    // most significant byte of compiler_hints which is otherwise unused.
4459    // Its offset depends on the endian-ness of the architecture.
4460  #if __BYTE_ORDER == __LITTLE_ENDIAN
4461    static const int kConstructionCountOffset = kCompilerHintsOffset + 3;
4462  #elif __BYTE_ORDER == __BIG_ENDIAN
4463    static const int kConstructionCountOffset = kCompilerHintsOffset + 0;
4464  #else
4465  #error Unknown byte ordering
4466  #endif
4467  
4468    static const int kAlignedSize = POINTER_SIZE_ALIGN(kSize);
4469  
4470    typedef FixedBodyDescriptor<kNameOffset,
4471                                kThisPropertyAssignmentsOffset + kPointerSize,
4472                                kSize> BodyDescriptor;
4473  
4474    // Bit positions in start_position_and_type.
4475    // The source code start position is in the 30 most significant bits of
4476    // the start_position_and_type field.
4477    static const int kIsExpressionBit = 0;
4478    static const int kIsTopLevelBit   = 1;
4479    static const int kStartPositionShift = 2;
4480    static const int kStartPositionMask = ~((1 << kStartPositionShift) - 1);
4481  
4482    // Bit positions in compiler_hints.
4483    static const int kHasOnlySimpleThisPropertyAssignments = 0;
4484    static const int kAllowLazyCompilation = 1;
4485    static const int kLiveObjectsMayExist = 2;
4486    static const int kCodeAgeShift = 3;
4487    static const int kCodeAgeMask = 0x7;
4488    static const int kOptimizationDisabled = 6;
4489    static const int kStrictModeFunction = 7;
4490  
4491   private:
4492  #if V8_HOST_ARCH_32_BIT
4493    // On 32 bit platforms, compiler hints is a smi.
4494    static const int kCompilerHintsSmiTagSize = kSmiTagSize;
4495    static const int kCompilerHintsSize = kPointerSize;
4496  #else
4497    // On 64 bit platforms, compiler hints is not a smi, see comment above.
4498    static const int kCompilerHintsSmiTagSize = 0;
4499    static const int kCompilerHintsSize = kIntSize;
4500  #endif
4501  
4502   public:
4503    // Constants for optimizing codegen for strict mode function tests.
4504    // Allows to use byte-widgh instructions.
4505    static const int kStrictModeBitWithinByte =
4506        (kStrictModeFunction + kCompilerHintsSmiTagSize) % kBitsPerByte;
4507  
4508  #if __BYTE_ORDER == __LITTLE_ENDIAN
4509    static const int kStrictModeByteOffset = kCompilerHintsOffset +
4510      (kStrictModeFunction + kCompilerHintsSmiTagSize) / kBitsPerByte;
4511  #elif __BYTE_ORDER == __BIG_ENDIAN
4512    static const int kStrictModeByteOffset = kCompilerHintsOffset +
4513      (kCompilerHintsSize - 1) -
4514      ((kStrictModeFunction + kCompilerHintsSmiTagSize) / kBitsPerByte);
4515  #else
4516  #error Unknown byte ordering
4517  #endif
4518  
4519   private:
4520    DISALLOW_IMPLICIT_CONSTRUCTORS(SharedFunctionInfo);
4521  };
4522  
4523  
4524  // JSFunction describes JavaScript functions.
4525  class JSFunction: public JSObject {
4526   public:
4527    // [prototype_or_initial_map]:
4528    DECL_ACCESSORS(prototype_or_initial_map, Object)
4529  
4530    // [shared_function_info]: The information about the function that
4531    // can be shared by instances.
4532    DECL_ACCESSORS(shared, SharedFunctionInfo)
4533  
4534    inline SharedFunctionInfo* unchecked_shared();
4535  
4536    // [context]: The context for this function.
4537    inline Context* context();
4538    inline Object* unchecked_context();
4539    inline void set_context(Object* context);
4540  
4541    // [code]: The generated code object for this function.  Executed
4542    // when the function is invoked, e.g. foo() or new foo(). See
4543    // [[Call]] and [[Construct]] description in ECMA-262, section
4544    // 8.6.2, page 27.
4545    inline Code* code();
4546    inline void set_code(Code* code);
4547    inline void ReplaceCode(Code* code);
4548  
4549    inline Code* unchecked_code();
4550  
4551    // Tells whether this function is builtin.
4552    inline bool IsBuiltin();
4553  
4554    // Tells whether or not the function needs arguments adaption.
4555    inline bool NeedsArgumentsAdaption();
4556  
4557    // Tells whether or not this function has been optimized.
4558    inline bool IsOptimized();
4559  
4560    // Tells whether or not this function can be optimized.
4561    inline bool IsOptimizable();
4562  
4563    // Mark this function for lazy recompilation. The function will be
4564    // recompiled the next time it is executed.
4565    void MarkForLazyRecompilation();
4566  
4567    // Tells whether or not the function is already marked for lazy
4568    // recompilation.
4569    inline bool IsMarkedForLazyRecompilation();
4570  
4571    // Compute a hash code for the source code of this function.
4572    uint32_t SourceHash();
4573  
4574    // Check whether or not this function is inlineable.
4575    bool IsInlineable();
4576  
4577    // [literals]: Fixed array holding the materialized literals.
4578    //
4579    // If the function contains object, regexp or array literals, the
4580    // literals array prefix contains the object, regexp, and array
4581    // function to be used when creating these literals.  This is
4582    // necessary so that we do not dynamically lookup the object, regexp
4583    // or array functions.  Performing a dynamic lookup, we might end up
4584    // using the functions from a new context that we should not have
4585    // access to.
4586    DECL_ACCESSORS(literals, FixedArray)
4587  
4588    // The initial map for an object created by this constructor.
4589    inline Map* initial_map();
4590    inline void set_initial_map(Map* value);
4591    inline bool has_initial_map();
4592  
4593    // Get and set the prototype property on a JSFunction. If the
4594    // function has an initial map the prototype is set on the initial
4595    // map. Otherwise, the prototype is put in the initial map field
4596    // until an initial map is needed.
4597    inline bool has_prototype();
4598    inline bool has_instance_prototype();
4599    inline Object* prototype();
4600    inline Object* instance_prototype();
4601    Object* SetInstancePrototype(Object* value);
4602    MUST_USE_RESULT MaybeObject* SetPrototype(Object* value);
4603  
4604    // After prototype is removed, it will not be created when accessed, and
4605    // [[Construct]] from this function will not be allowed.
4606    Object* RemovePrototype();
4607    inline bool should_have_prototype();
4608  
4609    // Accessor for this function's initial map's [[class]]
4610    // property. This is primarily used by ECMA native functions.  This
4611    // method sets the class_name field of this function's initial map
4612    // to a given value. It creates an initial map if this function does
4613    // not have one. Note that this method does not copy the initial map
4614    // if it has one already, but simply replaces it with the new value.
4615    // Instances created afterwards will have a map whose [[class]] is
4616    // set to 'value', but there is no guarantees on instances created
4617    // before.
4618    Object* SetInstanceClassName(String* name);
4619  
4620    // Returns if this function has been compiled to native code yet.
4621    inline bool is_compiled();
4622  
4623    // [next_function_link]: Field for linking functions. This list is treated as
4624    // a weak list by the GC.
DECL_ACCESSORS(next_function_link,Object)4625    DECL_ACCESSORS(next_function_link, Object)
4626  
4627    // Prints the name of the function using PrintF.
4628    inline void PrintName() {
4629      PrintName(stdout);
4630    }
4631    void PrintName(FILE* out);
4632  
4633    // Casting.
4634    static inline JSFunction* cast(Object* obj);
4635  
4636    // Iterates the objects, including code objects indirectly referenced
4637    // through pointers to the first instruction in the code object.
4638    void JSFunctionIterateBody(int object_size, ObjectVisitor* v);
4639  
4640    // Dispatched behavior.
4641  #ifdef OBJECT_PRINT
JSFunctionPrint()4642    inline void JSFunctionPrint() {
4643      JSFunctionPrint(stdout);
4644    }
4645    void JSFunctionPrint(FILE* out);
4646  #endif
4647  #ifdef DEBUG
4648    void JSFunctionVerify();
4649  #endif
4650  
4651    // Returns the number of allocated literals.
4652    inline int NumberOfLiterals();
4653  
4654    // Retrieve the global context from a function's literal array.
4655    static Context* GlobalContextFromLiterals(FixedArray* literals);
4656  
4657    // Layout descriptors. The last property (from kNonWeakFieldsEndOffset to
4658    // kSize) is weak and has special handling during garbage collection.
4659    static const int kCodeEntryOffset = JSObject::kHeaderSize;
4660    static const int kPrototypeOrInitialMapOffset =
4661        kCodeEntryOffset + kPointerSize;
4662    static const int kSharedFunctionInfoOffset =
4663        kPrototypeOrInitialMapOffset + kPointerSize;
4664    static const int kContextOffset = kSharedFunctionInfoOffset + kPointerSize;
4665    static const int kLiteralsOffset = kContextOffset + kPointerSize;
4666    static const int kNonWeakFieldsEndOffset = kLiteralsOffset + kPointerSize;
4667    static const int kNextFunctionLinkOffset = kNonWeakFieldsEndOffset;
4668    static const int kSize = kNextFunctionLinkOffset + kPointerSize;
4669  
4670    // Layout of the literals array.
4671    static const int kLiteralsPrefixSize = 1;
4672    static const int kLiteralGlobalContextIndex = 0;
4673   private:
4674    DISALLOW_IMPLICIT_CONSTRUCTORS(JSFunction);
4675  };
4676  
4677  
4678  // JSGlobalProxy's prototype must be a JSGlobalObject or null,
4679  // and the prototype is hidden. JSGlobalProxy always delegates
4680  // property accesses to its prototype if the prototype is not null.
4681  //
4682  // A JSGlobalProxy can be reinitialized which will preserve its identity.
4683  //
4684  // Accessing a JSGlobalProxy requires security check.
4685  
4686  class JSGlobalProxy : public JSObject {
4687   public:
4688    // [context]: the owner global context of this proxy object.
4689    // It is null value if this object is not used by any context.
4690    DECL_ACCESSORS(context, Object)
4691  
4692    // Casting.
4693    static inline JSGlobalProxy* cast(Object* obj);
4694  
4695    // Dispatched behavior.
4696  #ifdef OBJECT_PRINT
JSGlobalProxyPrint()4697    inline void JSGlobalProxyPrint() {
4698      JSGlobalProxyPrint(stdout);
4699    }
4700    void JSGlobalProxyPrint(FILE* out);
4701  #endif
4702  #ifdef DEBUG
4703    void JSGlobalProxyVerify();
4704  #endif
4705  
4706    // Layout description.
4707    static const int kContextOffset = JSObject::kHeaderSize;
4708    static const int kSize = kContextOffset + kPointerSize;
4709  
4710   private:
4711  
4712    DISALLOW_IMPLICIT_CONSTRUCTORS(JSGlobalProxy);
4713  };
4714  
4715  
4716  // Forward declaration.
4717  class JSBuiltinsObject;
4718  class JSGlobalPropertyCell;
4719  
4720  // Common super class for JavaScript global objects and the special
4721  // builtins global objects.
4722  class GlobalObject: public JSObject {
4723   public:
4724    // [builtins]: the object holding the runtime routines written in JS.
4725    DECL_ACCESSORS(builtins, JSBuiltinsObject)
4726  
4727    // [global context]: the global context corresponding to this global object.
4728    DECL_ACCESSORS(global_context, Context)
4729  
4730    // [global receiver]: the global receiver object of the context
4731    DECL_ACCESSORS(global_receiver, JSObject)
4732  
4733    // Retrieve the property cell used to store a property.
4734    JSGlobalPropertyCell* GetPropertyCell(LookupResult* result);
4735  
4736    // This is like GetProperty, but is used when you know the lookup won't fail
4737    // by throwing an exception.  This is for the debug and builtins global
4738    // objects, where it is known which properties can be expected to be present
4739    // on the object.
GetPropertyNoExceptionThrown(String * key)4740    Object* GetPropertyNoExceptionThrown(String* key) {
4741      Object* answer = GetProperty(key)->ToObjectUnchecked();
4742      return answer;
4743    }
4744  
4745    // Ensure that the global object has a cell for the given property name.
4746    MUST_USE_RESULT MaybeObject* EnsurePropertyCell(String* name);
4747  
4748    // Casting.
4749    static inline GlobalObject* cast(Object* obj);
4750  
4751    // Layout description.
4752    static const int kBuiltinsOffset = JSObject::kHeaderSize;
4753    static const int kGlobalContextOffset = kBuiltinsOffset + kPointerSize;
4754    static const int kGlobalReceiverOffset = kGlobalContextOffset + kPointerSize;
4755    static const int kHeaderSize = kGlobalReceiverOffset + kPointerSize;
4756  
4757   private:
4758    friend class AGCCVersionRequiresThisClassToHaveAFriendSoHereItIs;
4759  
4760    DISALLOW_IMPLICIT_CONSTRUCTORS(GlobalObject);
4761  };
4762  
4763  
4764  // JavaScript global object.
4765  class JSGlobalObject: public GlobalObject {
4766   public:
4767  
4768    // Casting.
4769    static inline JSGlobalObject* cast(Object* obj);
4770  
4771    // Dispatched behavior.
4772  #ifdef OBJECT_PRINT
JSGlobalObjectPrint()4773    inline void JSGlobalObjectPrint() {
4774      JSGlobalObjectPrint(stdout);
4775    }
4776    void JSGlobalObjectPrint(FILE* out);
4777  #endif
4778  #ifdef DEBUG
4779    void JSGlobalObjectVerify();
4780  #endif
4781  
4782    // Layout description.
4783    static const int kSize = GlobalObject::kHeaderSize;
4784  
4785   private:
4786    DISALLOW_IMPLICIT_CONSTRUCTORS(JSGlobalObject);
4787  };
4788  
4789  
4790  // Builtins global object which holds the runtime routines written in
4791  // JavaScript.
4792  class JSBuiltinsObject: public GlobalObject {
4793   public:
4794    // Accessors for the runtime routines written in JavaScript.
4795    inline Object* javascript_builtin(Builtins::JavaScript id);
4796    inline void set_javascript_builtin(Builtins::JavaScript id, Object* value);
4797  
4798    // Accessors for code of the runtime routines written in JavaScript.
4799    inline Code* javascript_builtin_code(Builtins::JavaScript id);
4800    inline void set_javascript_builtin_code(Builtins::JavaScript id, Code* value);
4801  
4802    // Casting.
4803    static inline JSBuiltinsObject* cast(Object* obj);
4804  
4805    // Dispatched behavior.
4806  #ifdef OBJECT_PRINT
JSBuiltinsObjectPrint()4807    inline void JSBuiltinsObjectPrint() {
4808      JSBuiltinsObjectPrint(stdout);
4809    }
4810    void JSBuiltinsObjectPrint(FILE* out);
4811  #endif
4812  #ifdef DEBUG
4813    void JSBuiltinsObjectVerify();
4814  #endif
4815  
4816    // Layout description.  The size of the builtins object includes
4817    // room for two pointers per runtime routine written in javascript
4818    // (function and code object).
4819    static const int kJSBuiltinsCount = Builtins::id_count;
4820    static const int kJSBuiltinsOffset = GlobalObject::kHeaderSize;
4821    static const int kJSBuiltinsCodeOffset =
4822        GlobalObject::kHeaderSize + (kJSBuiltinsCount * kPointerSize);
4823    static const int kSize =
4824        kJSBuiltinsCodeOffset + (kJSBuiltinsCount * kPointerSize);
4825  
OffsetOfFunctionWithId(Builtins::JavaScript id)4826    static int OffsetOfFunctionWithId(Builtins::JavaScript id) {
4827      return kJSBuiltinsOffset + id * kPointerSize;
4828    }
4829  
OffsetOfCodeWithId(Builtins::JavaScript id)4830    static int OffsetOfCodeWithId(Builtins::JavaScript id) {
4831      return kJSBuiltinsCodeOffset + id * kPointerSize;
4832    }
4833  
4834   private:
4835    DISALLOW_IMPLICIT_CONSTRUCTORS(JSBuiltinsObject);
4836  };
4837  
4838  
4839  // Representation for JS Wrapper objects, String, Number, Boolean, Date, etc.
4840  class JSValue: public JSObject {
4841   public:
4842    // [value]: the object being wrapped.
4843    DECL_ACCESSORS(value, Object)
4844  
4845    // Casting.
4846    static inline JSValue* cast(Object* obj);
4847  
4848    // Dispatched behavior.
4849  #ifdef OBJECT_PRINT
JSValuePrint()4850    inline void JSValuePrint() {
4851      JSValuePrint(stdout);
4852    }
4853    void JSValuePrint(FILE* out);
4854  #endif
4855  #ifdef DEBUG
4856    void JSValueVerify();
4857  #endif
4858  
4859    // Layout description.
4860    static const int kValueOffset = JSObject::kHeaderSize;
4861    static const int kSize = kValueOffset + kPointerSize;
4862  
4863   private:
4864    DISALLOW_IMPLICIT_CONSTRUCTORS(JSValue);
4865  };
4866  
4867  
4868  // Representation of message objects used for error reporting through
4869  // the API. The messages are formatted in JavaScript so this object is
4870  // a real JavaScript object. The information used for formatting the
4871  // error messages are not directly accessible from JavaScript to
4872  // prevent leaking information to user code called during error
4873  // formatting.
4874  class JSMessageObject: public JSObject {
4875   public:
4876    // [type]: the type of error message.
4877    DECL_ACCESSORS(type, String)
4878  
4879    // [arguments]: the arguments for formatting the error message.
4880    DECL_ACCESSORS(arguments, JSArray)
4881  
4882    // [script]: the script from which the error message originated.
4883    DECL_ACCESSORS(script, Object)
4884  
4885    // [stack_trace]: the stack trace for this error message.
4886    DECL_ACCESSORS(stack_trace, Object)
4887  
4888    // [stack_frames]: an array of stack frames for this error object.
4889    DECL_ACCESSORS(stack_frames, Object)
4890  
4891    // [start_position]: the start position in the script for the error message.
4892    inline int start_position();
4893    inline void set_start_position(int value);
4894  
4895    // [end_position]: the end position in the script for the error message.
4896    inline int end_position();
4897    inline void set_end_position(int value);
4898  
4899    // Casting.
4900    static inline JSMessageObject* cast(Object* obj);
4901  
4902    // Dispatched behavior.
4903  #ifdef OBJECT_PRINT
JSMessageObjectPrint()4904    inline void JSMessageObjectPrint() {
4905      JSMessageObjectPrint(stdout);
4906    }
4907    void JSMessageObjectPrint(FILE* out);
4908  #endif
4909  #ifdef DEBUG
4910    void JSMessageObjectVerify();
4911  #endif
4912  
4913    // Layout description.
4914    static const int kTypeOffset = JSObject::kHeaderSize;
4915    static const int kArgumentsOffset = kTypeOffset + kPointerSize;
4916    static const int kScriptOffset = kArgumentsOffset + kPointerSize;
4917    static const int kStackTraceOffset = kScriptOffset + kPointerSize;
4918    static const int kStackFramesOffset = kStackTraceOffset + kPointerSize;
4919    static const int kStartPositionOffset = kStackFramesOffset + kPointerSize;
4920    static const int kEndPositionOffset = kStartPositionOffset + kPointerSize;
4921    static const int kSize = kEndPositionOffset + kPointerSize;
4922  
4923    typedef FixedBodyDescriptor<HeapObject::kMapOffset,
4924                                kStackFramesOffset + kPointerSize,
4925                                kSize> BodyDescriptor;
4926  };
4927  
4928  
4929  // Regular expressions
4930  // The regular expression holds a single reference to a FixedArray in
4931  // the kDataOffset field.
4932  // The FixedArray contains the following data:
4933  // - tag : type of regexp implementation (not compiled yet, atom or irregexp)
4934  // - reference to the original source string
4935  // - reference to the original flag string
4936  // If it is an atom regexp
4937  // - a reference to a literal string to search for
4938  // If it is an irregexp regexp:
4939  // - a reference to code for ASCII inputs (bytecode or compiled).
4940  // - a reference to code for UC16 inputs (bytecode or compiled).
4941  // - max number of registers used by irregexp implementations.
4942  // - number of capture registers (output values) of the regexp.
4943  class JSRegExp: public JSObject {
4944   public:
4945    // Meaning of Type:
4946    // NOT_COMPILED: Initial value. No data has been stored in the JSRegExp yet.
4947    // ATOM: A simple string to match against using an indexOf operation.
4948    // IRREGEXP: Compiled with Irregexp.
4949    // IRREGEXP_NATIVE: Compiled to native code with Irregexp.
4950    enum Type { NOT_COMPILED, ATOM, IRREGEXP };
4951    enum Flag { NONE = 0, GLOBAL = 1, IGNORE_CASE = 2, MULTILINE = 4 };
4952  
4953    class Flags {
4954     public:
Flags(uint32_t value)4955      explicit Flags(uint32_t value) : value_(value) { }
is_global()4956      bool is_global() { return (value_ & GLOBAL) != 0; }
is_ignore_case()4957      bool is_ignore_case() { return (value_ & IGNORE_CASE) != 0; }
is_multiline()4958      bool is_multiline() { return (value_ & MULTILINE) != 0; }
value()4959      uint32_t value() { return value_; }
4960     private:
4961      uint32_t value_;
4962    };
4963  
4964    DECL_ACCESSORS(data, Object)
4965  
4966    inline Type TypeTag();
4967    inline int CaptureCount();
4968    inline Flags GetFlags();
4969    inline String* Pattern();
4970    inline Object* DataAt(int index);
4971    // Set implementation data after the object has been prepared.
4972    inline void SetDataAt(int index, Object* value);
code_index(bool is_ascii)4973    static int code_index(bool is_ascii) {
4974      if (is_ascii) {
4975        return kIrregexpASCIICodeIndex;
4976      } else {
4977        return kIrregexpUC16CodeIndex;
4978      }
4979    }
4980  
4981    static inline JSRegExp* cast(Object* obj);
4982  
4983    // Dispatched behavior.
4984  #ifdef DEBUG
4985    void JSRegExpVerify();
4986  #endif
4987  
4988    static const int kDataOffset = JSObject::kHeaderSize;
4989    static const int kSize = kDataOffset + kPointerSize;
4990  
4991    // Indices in the data array.
4992    static const int kTagIndex = 0;
4993    static const int kSourceIndex = kTagIndex + 1;
4994    static const int kFlagsIndex = kSourceIndex + 1;
4995    static const int kDataIndex = kFlagsIndex + 1;
4996    // The data fields are used in different ways depending on the
4997    // value of the tag.
4998    // Atom regexps (literal strings).
4999    static const int kAtomPatternIndex = kDataIndex;
5000  
5001    static const int kAtomDataSize = kAtomPatternIndex + 1;
5002  
5003    // Irregexp compiled code or bytecode for ASCII. If compilation
5004    // fails, this fields hold an exception object that should be
5005    // thrown if the regexp is used again.
5006    static const int kIrregexpASCIICodeIndex = kDataIndex;
5007    // Irregexp compiled code or bytecode for UC16.  If compilation
5008    // fails, this fields hold an exception object that should be
5009    // thrown if the regexp is used again.
5010    static const int kIrregexpUC16CodeIndex = kDataIndex + 1;
5011    // Maximal number of registers used by either ASCII or UC16.
5012    // Only used to check that there is enough stack space
5013    static const int kIrregexpMaxRegisterCountIndex = kDataIndex + 2;
5014    // Number of captures in the compiled regexp.
5015    static const int kIrregexpCaptureCountIndex = kDataIndex + 3;
5016  
5017    static const int kIrregexpDataSize = kIrregexpCaptureCountIndex + 1;
5018  
5019    // Offsets directly into the data fixed array.
5020    static const int kDataTagOffset =
5021        FixedArray::kHeaderSize + kTagIndex * kPointerSize;
5022    static const int kDataAsciiCodeOffset =
5023        FixedArray::kHeaderSize + kIrregexpASCIICodeIndex * kPointerSize;
5024    static const int kDataUC16CodeOffset =
5025        FixedArray::kHeaderSize + kIrregexpUC16CodeIndex * kPointerSize;
5026    static const int kIrregexpCaptureCountOffset =
5027        FixedArray::kHeaderSize + kIrregexpCaptureCountIndex * kPointerSize;
5028  
5029    // In-object fields.
5030    static const int kSourceFieldIndex = 0;
5031    static const int kGlobalFieldIndex = 1;
5032    static const int kIgnoreCaseFieldIndex = 2;
5033    static const int kMultilineFieldIndex = 3;
5034    static const int kLastIndexFieldIndex = 4;
5035    static const int kInObjectFieldCount = 5;
5036  };
5037  
5038  
5039  class CompilationCacheShape {
5040   public:
IsMatch(HashTableKey * key,Object * value)5041    static inline bool IsMatch(HashTableKey* key, Object* value) {
5042      return key->IsMatch(value);
5043    }
5044  
Hash(HashTableKey * key)5045    static inline uint32_t Hash(HashTableKey* key) {
5046      return key->Hash();
5047    }
5048  
HashForObject(HashTableKey * key,Object * object)5049    static inline uint32_t HashForObject(HashTableKey* key, Object* object) {
5050      return key->HashForObject(object);
5051    }
5052  
AsObject(HashTableKey * key)5053    MUST_USE_RESULT static MaybeObject* AsObject(HashTableKey* key) {
5054      return key->AsObject();
5055    }
5056  
5057    static const int kPrefixSize = 0;
5058    static const int kEntrySize = 2;
5059  };
5060  
5061  
5062  class CompilationCacheTable: public HashTable<CompilationCacheShape,
5063                                                HashTableKey*> {
5064   public:
5065    // Find cached value for a string key, otherwise return null.
5066    Object* Lookup(String* src);
5067    Object* LookupEval(String* src, Context* context, StrictModeFlag strict_mode);
5068    Object* LookupRegExp(String* source, JSRegExp::Flags flags);
5069    MaybeObject* Put(String* src, Object* value);
5070    MaybeObject* PutEval(String* src,
5071                         Context* context,
5072                         SharedFunctionInfo* value);
5073    MaybeObject* PutRegExp(String* src, JSRegExp::Flags flags, FixedArray* value);
5074  
5075    // Remove given value from cache.
5076    void Remove(Object* value);
5077  
5078    static inline CompilationCacheTable* cast(Object* obj);
5079  
5080   private:
5081    DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationCacheTable);
5082  };
5083  
5084  
5085  class CodeCache: public Struct {
5086   public:
5087    DECL_ACCESSORS(default_cache, FixedArray)
5088    DECL_ACCESSORS(normal_type_cache, Object)
5089  
5090    // Add the code object to the cache.
5091    MUST_USE_RESULT MaybeObject* Update(String* name, Code* code);
5092  
5093    // Lookup code object in the cache. Returns code object if found and undefined
5094    // if not.
5095    Object* Lookup(String* name, Code::Flags flags);
5096  
5097    // Get the internal index of a code object in the cache. Returns -1 if the
5098    // code object is not in that cache. This index can be used to later call
5099    // RemoveByIndex. The cache cannot be modified between a call to GetIndex and
5100    // RemoveByIndex.
5101    int GetIndex(Object* name, Code* code);
5102  
5103    // Remove an object from the cache with the provided internal index.
5104    void RemoveByIndex(Object* name, Code* code, int index);
5105  
5106    static inline CodeCache* cast(Object* obj);
5107  
5108  #ifdef OBJECT_PRINT
CodeCachePrint()5109    inline void CodeCachePrint() {
5110      CodeCachePrint(stdout);
5111    }
5112    void CodeCachePrint(FILE* out);
5113  #endif
5114  #ifdef DEBUG
5115    void CodeCacheVerify();
5116  #endif
5117  
5118    static const int kDefaultCacheOffset = HeapObject::kHeaderSize;
5119    static const int kNormalTypeCacheOffset =
5120        kDefaultCacheOffset + kPointerSize;
5121    static const int kSize = kNormalTypeCacheOffset + kPointerSize;
5122  
5123   private:
5124    MUST_USE_RESULT MaybeObject* UpdateDefaultCache(String* name, Code* code);
5125    MUST_USE_RESULT MaybeObject* UpdateNormalTypeCache(String* name, Code* code);
5126    Object* LookupDefaultCache(String* name, Code::Flags flags);
5127    Object* LookupNormalTypeCache(String* name, Code::Flags flags);
5128  
5129    // Code cache layout of the default cache. Elements are alternating name and
5130    // code objects for non normal load/store/call IC's.
5131    static const int kCodeCacheEntrySize = 2;
5132    static const int kCodeCacheEntryNameOffset = 0;
5133    static const int kCodeCacheEntryCodeOffset = 1;
5134  
5135    DISALLOW_IMPLICIT_CONSTRUCTORS(CodeCache);
5136  };
5137  
5138  
5139  class CodeCacheHashTableShape {
5140   public:
IsMatch(HashTableKey * key,Object * value)5141    static inline bool IsMatch(HashTableKey* key, Object* value) {
5142      return key->IsMatch(value);
5143    }
5144  
Hash(HashTableKey * key)5145    static inline uint32_t Hash(HashTableKey* key) {
5146      return key->Hash();
5147    }
5148  
HashForObject(HashTableKey * key,Object * object)5149    static inline uint32_t HashForObject(HashTableKey* key, Object* object) {
5150      return key->HashForObject(object);
5151    }
5152  
AsObject(HashTableKey * key)5153    MUST_USE_RESULT static MaybeObject* AsObject(HashTableKey* key) {
5154      return key->AsObject();
5155    }
5156  
5157    static const int kPrefixSize = 0;
5158    static const int kEntrySize = 2;
5159  };
5160  
5161  
5162  class CodeCacheHashTable: public HashTable<CodeCacheHashTableShape,
5163                                             HashTableKey*> {
5164   public:
5165    Object* Lookup(String* name, Code::Flags flags);
5166    MUST_USE_RESULT MaybeObject* Put(String* name, Code* code);
5167  
5168    int GetIndex(String* name, Code::Flags flags);
5169    void RemoveByIndex(int index);
5170  
5171    static inline CodeCacheHashTable* cast(Object* obj);
5172  
5173    // Initial size of the fixed array backing the hash table.
5174    static const int kInitialSize = 64;
5175  
5176   private:
5177    DISALLOW_IMPLICIT_CONSTRUCTORS(CodeCacheHashTable);
5178  };
5179  
5180  
5181  enum AllowNullsFlag {ALLOW_NULLS, DISALLOW_NULLS};
5182  enum RobustnessFlag {ROBUST_STRING_TRAVERSAL, FAST_STRING_TRAVERSAL};
5183  
5184  
5185  class StringHasher {
5186   public:
5187    explicit inline StringHasher(int length);
5188  
5189    // Returns true if the hash of this string can be computed without
5190    // looking at the contents.
5191    inline bool has_trivial_hash();
5192  
5193    // Add a character to the hash and update the array index calculation.
5194    inline void AddCharacter(uc32 c);
5195  
5196    // Adds a character to the hash but does not update the array index
5197    // calculation.  This can only be called when it has been verified
5198    // that the input is not an array index.
5199    inline void AddCharacterNoIndex(uc32 c);
5200  
5201    // Returns the value to store in the hash field of a string with
5202    // the given length and contents.
5203    uint32_t GetHashField();
5204  
5205    // Returns true if the characters seen so far make up a legal array
5206    // index.
is_array_index()5207    bool is_array_index() { return is_array_index_; }
5208  
is_valid()5209    bool is_valid() { return is_valid_; }
5210  
invalidate()5211    void invalidate() { is_valid_ = false; }
5212  
5213    // Calculated hash value for a string consisting of 1 to
5214    // String::kMaxArrayIndexSize digits with no leading zeros (except "0").
5215    // value is represented decimal value.
5216    static uint32_t MakeArrayIndexHash(uint32_t value, int length);
5217  
5218   private:
5219  
array_index()5220    uint32_t array_index() {
5221      ASSERT(is_array_index());
5222      return array_index_;
5223    }
5224  
5225    inline uint32_t GetHash();
5226  
5227    int length_;
5228    uint32_t raw_running_hash_;
5229    uint32_t array_index_;
5230    bool is_array_index_;
5231    bool is_first_char_;
5232    bool is_valid_;
5233    friend class TwoCharHashTableKey;
5234  };
5235  
5236  
5237  // Calculates string hash.
5238  template <typename schar>
5239  inline uint32_t HashSequentialString(const schar* chars, int length);
5240  
5241  
5242  // The characteristics of a string are stored in its map.  Retrieving these
5243  // few bits of information is moderately expensive, involving two memory
5244  // loads where the second is dependent on the first.  To improve efficiency
5245  // the shape of the string is given its own class so that it can be retrieved
5246  // once and used for several string operations.  A StringShape is small enough
5247  // to be passed by value and is immutable, but be aware that flattening a
5248  // string can potentially alter its shape.  Also be aware that a GC caused by
5249  // something else can alter the shape of a string due to ConsString
5250  // shortcutting.  Keeping these restrictions in mind has proven to be error-
5251  // prone and so we no longer put StringShapes in variables unless there is a
5252  // concrete performance benefit at that particular point in the code.
5253  class StringShape BASE_EMBEDDED {
5254   public:
5255    inline explicit StringShape(String* s);
5256    inline explicit StringShape(Map* s);
5257    inline explicit StringShape(InstanceType t);
5258    inline bool IsSequential();
5259    inline bool IsExternal();
5260    inline bool IsCons();
5261    inline bool IsExternalAscii();
5262    inline bool IsExternalTwoByte();
5263    inline bool IsSequentialAscii();
5264    inline bool IsSequentialTwoByte();
5265    inline bool IsSymbol();
5266    inline StringRepresentationTag representation_tag();
5267    inline uint32_t full_representation_tag();
5268    inline uint32_t size_tag();
5269  #ifdef DEBUG
type()5270    inline uint32_t type() { return type_; }
invalidate()5271    inline void invalidate() { valid_ = false; }
valid()5272    inline bool valid() { return valid_; }
5273  #else
invalidate()5274    inline void invalidate() { }
5275  #endif
5276   private:
5277    uint32_t type_;
5278  #ifdef DEBUG
set_valid()5279    inline void set_valid() { valid_ = true; }
5280    bool valid_;
5281  #else
set_valid()5282    inline void set_valid() { }
5283  #endif
5284  };
5285  
5286  
5287  // The String abstract class captures JavaScript string values:
5288  //
5289  // Ecma-262:
5290  //  4.3.16 String Value
5291  //    A string value is a member of the type String and is a finite
5292  //    ordered sequence of zero or more 16-bit unsigned integer values.
5293  //
5294  // All string values have a length field.
5295  class String: public HeapObject {
5296   public:
5297    // Get and set the length of the string.
5298    inline int length();
5299    inline void set_length(int value);
5300  
5301    // Get and set the hash field of the string.
5302    inline uint32_t hash_field();
5303    inline void set_hash_field(uint32_t value);
5304  
5305    inline bool IsAsciiRepresentation();
5306    inline bool IsTwoByteRepresentation();
5307  
5308    // Returns whether this string has ascii chars, i.e. all of them can
5309    // be ascii encoded.  This might be the case even if the string is
5310    // two-byte.  Such strings may appear when the embedder prefers
5311    // two-byte external representations even for ascii data.
5312    //
5313    // NOTE: this should be considered only a hint.  False negatives are
5314    // possible.
5315    inline bool HasOnlyAsciiChars();
5316  
5317    // Get and set individual two byte chars in the string.
5318    inline void Set(int index, uint16_t value);
5319    // Get individual two byte char in the string.  Repeated calls
5320    // to this method are not efficient unless the string is flat.
5321    inline uint16_t Get(int index);
5322  
5323    // Try to flatten the string.  Checks first inline to see if it is
5324    // necessary.  Does nothing if the string is not a cons string.
5325    // Flattening allocates a sequential string with the same data as
5326    // the given string and mutates the cons string to a degenerate
5327    // form, where the first component is the new sequential string and
5328    // the second component is the empty string.  If allocation fails,
5329    // this function returns a failure.  If flattening succeeds, this
5330    // function returns the sequential string that is now the first
5331    // component of the cons string.
5332    //
5333    // Degenerate cons strings are handled specially by the garbage
5334    // collector (see IsShortcutCandidate).
5335    //
5336    // Use FlattenString from Handles.cc to flatten even in case an
5337    // allocation failure happens.
5338    inline MaybeObject* TryFlatten(PretenureFlag pretenure = NOT_TENURED);
5339  
5340    // Convenience function.  Has exactly the same behavior as
5341    // TryFlatten(), except in the case of failure returns the original
5342    // string.
5343    inline String* TryFlattenGetString(PretenureFlag pretenure = NOT_TENURED);
5344  
5345    Vector<const char> ToAsciiVector();
5346    Vector<const uc16> ToUC16Vector();
5347  
5348    // Mark the string as an undetectable object. It only applies to
5349    // ascii and two byte string types.
5350    bool MarkAsUndetectable();
5351  
5352    // Return a substring.
5353    MUST_USE_RESULT MaybeObject* SubString(int from,
5354                                           int to,
5355                                           PretenureFlag pretenure = NOT_TENURED);
5356  
5357    // String equality operations.
5358    inline bool Equals(String* other);
5359    bool IsEqualTo(Vector<const char> str);
5360    bool IsAsciiEqualTo(Vector<const char> str);
5361    bool IsTwoByteEqualTo(Vector<const uc16> str);
5362  
5363    // Return a UTF8 representation of the string.  The string is null
5364    // terminated but may optionally contain nulls.  Length is returned
5365    // in length_output if length_output is not a null pointer  The string
5366    // should be nearly flat, otherwise the performance of this method may
5367    // be very slow (quadratic in the length).  Setting robustness_flag to
5368    // ROBUST_STRING_TRAVERSAL invokes behaviour that is robust  This means it
5369    // handles unexpected data without causing assert failures and it does not
5370    // do any heap allocations.  This is useful when printing stack traces.
5371    SmartPointer<char> ToCString(AllowNullsFlag allow_nulls,
5372                                 RobustnessFlag robustness_flag,
5373                                 int offset,
5374                                 int length,
5375                                 int* length_output = 0);
5376    SmartPointer<char> ToCString(
5377        AllowNullsFlag allow_nulls = DISALLOW_NULLS,
5378        RobustnessFlag robustness_flag = FAST_STRING_TRAVERSAL,
5379        int* length_output = 0);
5380  
5381    int Utf8Length();
5382  
5383    // Return a 16 bit Unicode representation of the string.
5384    // The string should be nearly flat, otherwise the performance of
5385    // of this method may be very bad.  Setting robustness_flag to
5386    // ROBUST_STRING_TRAVERSAL invokes behaviour that is robust  This means it
5387    // handles unexpected data without causing assert failures and it does not
5388    // do any heap allocations.  This is useful when printing stack traces.
5389    SmartPointer<uc16> ToWideCString(
5390        RobustnessFlag robustness_flag = FAST_STRING_TRAVERSAL);
5391  
5392    // Tells whether the hash code has been computed.
5393    inline bool HasHashCode();
5394  
5395    // Returns a hash value used for the property table
5396    inline uint32_t Hash();
5397  
5398    static uint32_t ComputeHashField(unibrow::CharacterStream* buffer,
5399                                     int length);
5400  
5401    static bool ComputeArrayIndex(unibrow::CharacterStream* buffer,
5402                                  uint32_t* index,
5403                                  int length);
5404  
5405    // Externalization.
5406    bool MakeExternal(v8::String::ExternalStringResource* resource);
5407    bool MakeExternal(v8::String::ExternalAsciiStringResource* resource);
5408  
5409    // Conversion.
5410    inline bool AsArrayIndex(uint32_t* index);
5411  
5412    // Casting.
5413    static inline String* cast(Object* obj);
5414  
5415    void PrintOn(FILE* out);
5416  
5417    // For use during stack traces.  Performs rudimentary sanity check.
5418    bool LooksValid();
5419  
5420    // Dispatched behavior.
5421    void StringShortPrint(StringStream* accumulator);
5422  #ifdef OBJECT_PRINT
StringPrint()5423    inline void StringPrint() {
5424      StringPrint(stdout);
5425    }
5426    void StringPrint(FILE* out);
5427  #endif
5428  #ifdef DEBUG
5429    void StringVerify();
5430  #endif
5431    inline bool IsFlat();
5432  
5433    // Layout description.
5434    static const int kLengthOffset = HeapObject::kHeaderSize;
5435    static const int kHashFieldOffset = kLengthOffset + kPointerSize;
5436    static const int kSize = kHashFieldOffset + kPointerSize;
5437  
5438    // Maximum number of characters to consider when trying to convert a string
5439    // value into an array index.
5440    static const int kMaxArrayIndexSize = 10;
5441  
5442    // Max ascii char code.
5443    static const int kMaxAsciiCharCode = unibrow::Utf8::kMaxOneByteChar;
5444    static const unsigned kMaxAsciiCharCodeU = unibrow::Utf8::kMaxOneByteChar;
5445    static const int kMaxUC16CharCode = 0xffff;
5446  
5447    // Minimum length for a cons string.
5448    static const int kMinNonFlatLength = 13;
5449  
5450    // Mask constant for checking if a string has a computed hash code
5451    // and if it is an array index.  The least significant bit indicates
5452    // whether a hash code has been computed.  If the hash code has been
5453    // computed the 2nd bit tells whether the string can be used as an
5454    // array index.
5455    static const int kHashNotComputedMask = 1;
5456    static const int kIsNotArrayIndexMask = 1 << 1;
5457    static const int kNofHashBitFields = 2;
5458  
5459    // Shift constant retrieving hash code from hash field.
5460    static const int kHashShift = kNofHashBitFields;
5461  
5462    // Array index strings this short can keep their index in the hash
5463    // field.
5464    static const int kMaxCachedArrayIndexLength = 7;
5465  
5466    // For strings which are array indexes the hash value has the string length
5467    // mixed into the hash, mainly to avoid a hash value of zero which would be
5468    // the case for the string '0'. 24 bits are used for the array index value.
5469    static const int kArrayIndexValueBits = 24;
5470    static const int kArrayIndexLengthBits =
5471        kBitsPerInt - kArrayIndexValueBits - kNofHashBitFields;
5472  
5473    STATIC_CHECK((kArrayIndexLengthBits > 0));
5474    STATIC_CHECK(kMaxArrayIndexSize < (1 << kArrayIndexLengthBits));
5475  
5476    static const int kArrayIndexHashLengthShift =
5477        kArrayIndexValueBits + kNofHashBitFields;
5478  
5479    static const int kArrayIndexHashMask = (1 << kArrayIndexHashLengthShift) - 1;
5480  
5481    static const int kArrayIndexValueMask =
5482        ((1 << kArrayIndexValueBits) - 1) << kHashShift;
5483  
5484    // Check that kMaxCachedArrayIndexLength + 1 is a power of two so we
5485    // could use a mask to test if the length of string is less than or equal to
5486    // kMaxCachedArrayIndexLength.
5487    STATIC_CHECK(IS_POWER_OF_TWO(kMaxCachedArrayIndexLength + 1));
5488  
5489    static const int kContainsCachedArrayIndexMask =
5490        (~kMaxCachedArrayIndexLength << kArrayIndexHashLengthShift) |
5491        kIsNotArrayIndexMask;
5492  
5493    // Value of empty hash field indicating that the hash is not computed.
5494    static const int kEmptyHashField =
5495        kIsNotArrayIndexMask | kHashNotComputedMask;
5496  
5497    // Value of hash field containing computed hash equal to zero.
5498    static const int kZeroHash = kIsNotArrayIndexMask;
5499  
5500    // Maximal string length.
5501    static const int kMaxLength = (1 << (32 - 2)) - 1;
5502  
5503    // Max length for computing hash. For strings longer than this limit the
5504    // string length is used as the hash value.
5505    static const int kMaxHashCalcLength = 16383;
5506  
5507    // Limit for truncation in short printing.
5508    static const int kMaxShortPrintLength = 1024;
5509  
5510    // Support for regular expressions.
5511    const uc16* GetTwoByteData();
5512    const uc16* GetTwoByteData(unsigned start);
5513  
5514    // Support for StringInputBuffer
5515    static const unibrow::byte* ReadBlock(String* input,
5516                                          unibrow::byte* util_buffer,
5517                                          unsigned capacity,
5518                                          unsigned* remaining,
5519                                          unsigned* offset);
5520    static const unibrow::byte* ReadBlock(String** input,
5521                                          unibrow::byte* util_buffer,
5522                                          unsigned capacity,
5523                                          unsigned* remaining,
5524                                          unsigned* offset);
5525  
5526    // Helper function for flattening strings.
5527    template <typename sinkchar>
5528    static void WriteToFlat(String* source,
5529                            sinkchar* sink,
5530                            int from,
5531                            int to);
5532  
IsAscii(const char * chars,int length)5533    static inline bool IsAscii(const char* chars, int length) {
5534      const char* limit = chars + length;
5535  #ifdef V8_HOST_CAN_READ_UNALIGNED
5536      ASSERT(kMaxAsciiCharCode == 0x7F);
5537      const uintptr_t non_ascii_mask = kUintptrAllBitsSet / 0xFF * 0x80;
5538      while (chars <= limit - sizeof(uintptr_t)) {
5539        if (*reinterpret_cast<const uintptr_t*>(chars) & non_ascii_mask) {
5540          return false;
5541        }
5542        chars += sizeof(uintptr_t);
5543      }
5544  #endif
5545      while (chars < limit) {
5546        if (static_cast<uint8_t>(*chars) > kMaxAsciiCharCodeU) return false;
5547        ++chars;
5548      }
5549      return true;
5550    }
5551  
IsAscii(const uc16 * chars,int length)5552    static inline bool IsAscii(const uc16* chars, int length) {
5553      const uc16* limit = chars + length;
5554      while (chars < limit) {
5555        if (*chars > kMaxAsciiCharCodeU) return false;
5556        ++chars;
5557      }
5558      return true;
5559    }
5560  
5561   protected:
5562    class ReadBlockBuffer {
5563     public:
ReadBlockBuffer(unibrow::byte * util_buffer_,unsigned cursor_,unsigned capacity_,unsigned remaining_)5564      ReadBlockBuffer(unibrow::byte* util_buffer_,
5565                      unsigned cursor_,
5566                      unsigned capacity_,
5567                      unsigned remaining_) :
5568        util_buffer(util_buffer_),
5569        cursor(cursor_),
5570        capacity(capacity_),
5571        remaining(remaining_) {
5572      }
5573      unibrow::byte* util_buffer;
5574      unsigned       cursor;
5575      unsigned       capacity;
5576      unsigned       remaining;
5577    };
5578  
5579    static inline const unibrow::byte* ReadBlock(String* input,
5580                                                 ReadBlockBuffer* buffer,
5581                                                 unsigned* offset,
5582                                                 unsigned max_chars);
5583    static void ReadBlockIntoBuffer(String* input,
5584                                    ReadBlockBuffer* buffer,
5585                                    unsigned* offset_ptr,
5586                                    unsigned max_chars);
5587  
5588   private:
5589    // Try to flatten the top level ConsString that is hiding behind this
5590    // string.  This is a no-op unless the string is a ConsString.  Flatten
5591    // mutates the ConsString and might return a failure.
5592    MUST_USE_RESULT MaybeObject* SlowTryFlatten(PretenureFlag pretenure);
5593  
5594    static inline bool IsHashFieldComputed(uint32_t field);
5595  
5596    // Slow case of String::Equals.  This implementation works on any strings
5597    // but it is most efficient on strings that are almost flat.
5598    bool SlowEquals(String* other);
5599  
5600    // Slow case of AsArrayIndex.
5601    bool SlowAsArrayIndex(uint32_t* index);
5602  
5603    // Compute and set the hash code.
5604    uint32_t ComputeAndSetHash();
5605  
5606    DISALLOW_IMPLICIT_CONSTRUCTORS(String);
5607  };
5608  
5609  
5610  // The SeqString abstract class captures sequential string values.
5611  class SeqString: public String {
5612   public:
5613  
5614    // Casting.
5615    static inline SeqString* cast(Object* obj);
5616  
5617   private:
5618    DISALLOW_IMPLICIT_CONSTRUCTORS(SeqString);
5619  };
5620  
5621  
5622  // The AsciiString class captures sequential ascii string objects.
5623  // Each character in the AsciiString is an ascii character.
5624  class SeqAsciiString: public SeqString {
5625   public:
5626    static const bool kHasAsciiEncoding = true;
5627  
5628    // Dispatched behavior.
5629    inline uint16_t SeqAsciiStringGet(int index);
5630    inline void SeqAsciiStringSet(int index, uint16_t value);
5631  
5632    // Get the address of the characters in this string.
5633    inline Address GetCharsAddress();
5634  
5635    inline char* GetChars();
5636  
5637    // Casting
5638    static inline SeqAsciiString* cast(Object* obj);
5639  
5640    // Garbage collection support.  This method is called by the
5641    // garbage collector to compute the actual size of an AsciiString
5642    // instance.
5643    inline int SeqAsciiStringSize(InstanceType instance_type);
5644  
5645    // Computes the size for an AsciiString instance of a given length.
SizeFor(int length)5646    static int SizeFor(int length) {
5647      return OBJECT_POINTER_ALIGN(kHeaderSize + length * kCharSize);
5648    }
5649  
5650    // Layout description.
5651    static const int kHeaderSize = String::kSize;
5652    static const int kAlignedSize = POINTER_SIZE_ALIGN(kHeaderSize);
5653  
5654    // Maximal memory usage for a single sequential ASCII string.
5655    static const int kMaxSize = 512 * MB;
5656    // Maximal length of a single sequential ASCII string.
5657    // Q.v. String::kMaxLength which is the maximal size of concatenated strings.
5658    static const int kMaxLength = (kMaxSize - kHeaderSize);
5659  
5660    // Support for StringInputBuffer.
5661    inline void SeqAsciiStringReadBlockIntoBuffer(ReadBlockBuffer* buffer,
5662                                                  unsigned* offset,
5663                                                  unsigned chars);
5664    inline const unibrow::byte* SeqAsciiStringReadBlock(unsigned* remaining,
5665                                                        unsigned* offset,
5666                                                        unsigned chars);
5667  
5668   private:
5669    DISALLOW_IMPLICIT_CONSTRUCTORS(SeqAsciiString);
5670  };
5671  
5672  
5673  // The TwoByteString class captures sequential unicode string objects.
5674  // Each character in the TwoByteString is a two-byte uint16_t.
5675  class SeqTwoByteString: public SeqString {
5676   public:
5677    static const bool kHasAsciiEncoding = false;
5678  
5679    // Dispatched behavior.
5680    inline uint16_t SeqTwoByteStringGet(int index);
5681    inline void SeqTwoByteStringSet(int index, uint16_t value);
5682  
5683    // Get the address of the characters in this string.
5684    inline Address GetCharsAddress();
5685  
5686    inline uc16* GetChars();
5687  
5688    // For regexp code.
5689    const uint16_t* SeqTwoByteStringGetData(unsigned start);
5690  
5691    // Casting
5692    static inline SeqTwoByteString* cast(Object* obj);
5693  
5694    // Garbage collection support.  This method is called by the
5695    // garbage collector to compute the actual size of a TwoByteString
5696    // instance.
5697    inline int SeqTwoByteStringSize(InstanceType instance_type);
5698  
5699    // Computes the size for a TwoByteString instance of a given length.
SizeFor(int length)5700    static int SizeFor(int length) {
5701      return OBJECT_POINTER_ALIGN(kHeaderSize + length * kShortSize);
5702    }
5703  
5704    // Layout description.
5705    static const int kHeaderSize = String::kSize;
5706    static const int kAlignedSize = POINTER_SIZE_ALIGN(kHeaderSize);
5707  
5708    // Maximal memory usage for a single sequential two-byte string.
5709    static const int kMaxSize = 512 * MB;
5710    // Maximal length of a single sequential two-byte string.
5711    // Q.v. String::kMaxLength which is the maximal size of concatenated strings.
5712    static const int kMaxLength = (kMaxSize - kHeaderSize) / sizeof(uint16_t);
5713  
5714    // Support for StringInputBuffer.
5715    inline void SeqTwoByteStringReadBlockIntoBuffer(ReadBlockBuffer* buffer,
5716                                                    unsigned* offset_ptr,
5717                                                    unsigned chars);
5718  
5719   private:
5720    DISALLOW_IMPLICIT_CONSTRUCTORS(SeqTwoByteString);
5721  };
5722  
5723  
5724  // The ConsString class describes string values built by using the
5725  // addition operator on strings.  A ConsString is a pair where the
5726  // first and second components are pointers to other string values.
5727  // One or both components of a ConsString can be pointers to other
5728  // ConsStrings, creating a binary tree of ConsStrings where the leaves
5729  // are non-ConsString string values.  The string value represented by
5730  // a ConsString can be obtained by concatenating the leaf string
5731  // values in a left-to-right depth-first traversal of the tree.
5732  class ConsString: public String {
5733   public:
5734    // First string of the cons cell.
5735    inline String* first();
5736    // Doesn't check that the result is a string, even in debug mode.  This is
5737    // useful during GC where the mark bits confuse the checks.
5738    inline Object* unchecked_first();
5739    inline void set_first(String* first,
5740                          WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
5741  
5742    // Second string of the cons cell.
5743    inline String* second();
5744    // Doesn't check that the result is a string, even in debug mode.  This is
5745    // useful during GC where the mark bits confuse the checks.
5746    inline Object* unchecked_second();
5747    inline void set_second(String* second,
5748                           WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
5749  
5750    // Dispatched behavior.
5751    uint16_t ConsStringGet(int index);
5752  
5753    // Casting.
5754    static inline ConsString* cast(Object* obj);
5755  
5756    // Layout description.
5757    static const int kFirstOffset = POINTER_SIZE_ALIGN(String::kSize);
5758    static const int kSecondOffset = kFirstOffset + kPointerSize;
5759    static const int kSize = kSecondOffset + kPointerSize;
5760  
5761    // Support for StringInputBuffer.
5762    inline const unibrow::byte* ConsStringReadBlock(ReadBlockBuffer* buffer,
5763                                                    unsigned* offset_ptr,
5764                                                    unsigned chars);
5765    inline void ConsStringReadBlockIntoBuffer(ReadBlockBuffer* buffer,
5766                                              unsigned* offset_ptr,
5767                                              unsigned chars);
5768  
5769    // Minimum length for a cons string.
5770    static const int kMinLength = 13;
5771  
5772    typedef FixedBodyDescriptor<kFirstOffset, kSecondOffset + kPointerSize, kSize>
5773            BodyDescriptor;
5774  
5775   private:
5776    DISALLOW_IMPLICIT_CONSTRUCTORS(ConsString);
5777  };
5778  
5779  
5780  // The ExternalString class describes string values that are backed by
5781  // a string resource that lies outside the V8 heap.  ExternalStrings
5782  // consist of the length field common to all strings, a pointer to the
5783  // external resource.  It is important to ensure (externally) that the
5784  // resource is not deallocated while the ExternalString is live in the
5785  // V8 heap.
5786  //
5787  // The API expects that all ExternalStrings are created through the
5788  // API.  Therefore, ExternalStrings should not be used internally.
5789  class ExternalString: public String {
5790   public:
5791    // Casting
5792    static inline ExternalString* cast(Object* obj);
5793  
5794    // Layout description.
5795    static const int kResourceOffset = POINTER_SIZE_ALIGN(String::kSize);
5796    static const int kSize = kResourceOffset + kPointerSize;
5797  
5798    STATIC_CHECK(kResourceOffset == Internals::kStringResourceOffset);
5799  
5800   private:
5801    DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalString);
5802  };
5803  
5804  
5805  // The ExternalAsciiString class is an external string backed by an
5806  // ASCII string.
5807  class ExternalAsciiString: public ExternalString {
5808   public:
5809    static const bool kHasAsciiEncoding = true;
5810  
5811    typedef v8::String::ExternalAsciiStringResource Resource;
5812  
5813    // The underlying resource.
5814    inline Resource* resource();
5815    inline void set_resource(Resource* buffer);
5816  
5817    // Dispatched behavior.
5818    uint16_t ExternalAsciiStringGet(int index);
5819  
5820    // Casting.
5821    static inline ExternalAsciiString* cast(Object* obj);
5822  
5823    // Garbage collection support.
5824    inline void ExternalAsciiStringIterateBody(ObjectVisitor* v);
5825  
5826    template<typename StaticVisitor>
5827    inline void ExternalAsciiStringIterateBody();
5828  
5829    // Support for StringInputBuffer.
5830    const unibrow::byte* ExternalAsciiStringReadBlock(unsigned* remaining,
5831                                                      unsigned* offset,
5832                                                      unsigned chars);
5833    inline void ExternalAsciiStringReadBlockIntoBuffer(ReadBlockBuffer* buffer,
5834                                                       unsigned* offset,
5835                                                       unsigned chars);
5836  
5837   private:
5838    DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalAsciiString);
5839  };
5840  
5841  
5842  // The ExternalTwoByteString class is an external string backed by a UTF-16
5843  // encoded string.
5844  class ExternalTwoByteString: public ExternalString {
5845   public:
5846    static const bool kHasAsciiEncoding = false;
5847  
5848    typedef v8::String::ExternalStringResource Resource;
5849  
5850    // The underlying string resource.
5851    inline Resource* resource();
5852    inline void set_resource(Resource* buffer);
5853  
5854    // Dispatched behavior.
5855    uint16_t ExternalTwoByteStringGet(int index);
5856  
5857    // For regexp code.
5858    const uint16_t* ExternalTwoByteStringGetData(unsigned start);
5859  
5860    // Casting.
5861    static inline ExternalTwoByteString* cast(Object* obj);
5862  
5863    // Garbage collection support.
5864    inline void ExternalTwoByteStringIterateBody(ObjectVisitor* v);
5865  
5866    template<typename StaticVisitor>
5867    inline void ExternalTwoByteStringIterateBody();
5868  
5869  
5870    // Support for StringInputBuffer.
5871    void ExternalTwoByteStringReadBlockIntoBuffer(ReadBlockBuffer* buffer,
5872                                                  unsigned* offset_ptr,
5873                                                  unsigned chars);
5874  
5875   private:
5876    DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalTwoByteString);
5877  };
5878  
5879  
5880  // Utility superclass for stack-allocated objects that must be updated
5881  // on gc.  It provides two ways for the gc to update instances, either
5882  // iterating or updating after gc.
5883  class Relocatable BASE_EMBEDDED {
5884   public:
5885    explicit inline Relocatable(Isolate* isolate);
5886    inline virtual ~Relocatable();
IterateInstance(ObjectVisitor * v)5887    virtual void IterateInstance(ObjectVisitor* v) { }
PostGarbageCollection()5888    virtual void PostGarbageCollection() { }
5889  
5890    static void PostGarbageCollectionProcessing();
5891    static int ArchiveSpacePerThread();
5892    static char* ArchiveState(char* to);
5893    static char* RestoreState(char* from);
5894    static void Iterate(ObjectVisitor* v);
5895    static void Iterate(ObjectVisitor* v, Relocatable* top);
5896    static char* Iterate(ObjectVisitor* v, char* t);
5897   private:
5898    Isolate* isolate_;
5899    Relocatable* prev_;
5900  };
5901  
5902  
5903  // A flat string reader provides random access to the contents of a
5904  // string independent of the character width of the string.  The handle
5905  // must be valid as long as the reader is being used.
5906  class FlatStringReader : public Relocatable {
5907   public:
5908    FlatStringReader(Isolate* isolate, Handle<String> str);
5909    FlatStringReader(Isolate* isolate, Vector<const char> input);
5910    void PostGarbageCollection();
5911    inline uc32 Get(int index);
length()5912    int length() { return length_; }
5913   private:
5914    String** str_;
5915    bool is_ascii_;
5916    int length_;
5917    const void* start_;
5918  };
5919  
5920  
5921  // Note that StringInputBuffers are not valid across a GC!  To fix this
5922  // it would have to store a String Handle instead of a String* and
5923  // AsciiStringReadBlock would have to be modified to use memcpy.
5924  //
5925  // StringInputBuffer is able to traverse any string regardless of how
5926  // deeply nested a sequence of ConsStrings it is made of.  However,
5927  // performance will be better if deep strings are flattened before they
5928  // are traversed.  Since flattening requires memory allocation this is
5929  // not always desirable, however (esp. in debugging situations).
5930  class StringInputBuffer: public unibrow::InputBuffer<String, String*, 1024> {
5931   public:
5932    virtual void Seek(unsigned pos);
StringInputBuffer()5933    inline StringInputBuffer(): unibrow::InputBuffer<String, String*, 1024>() {}
StringInputBuffer(String * backing)5934    explicit inline StringInputBuffer(String* backing):
5935        unibrow::InputBuffer<String, String*, 1024>(backing) {}
5936  };
5937  
5938  
5939  class SafeStringInputBuffer
5940    : public unibrow::InputBuffer<String, String**, 256> {
5941   public:
5942    virtual void Seek(unsigned pos);
SafeStringInputBuffer()5943    inline SafeStringInputBuffer()
5944        : unibrow::InputBuffer<String, String**, 256>() {}
SafeStringInputBuffer(String ** backing)5945    explicit inline SafeStringInputBuffer(String** backing)
5946        : unibrow::InputBuffer<String, String**, 256>(backing) {}
5947  };
5948  
5949  
5950  template <typename T>
5951  class VectorIterator {
5952   public:
VectorIterator(T * d,int l)5953    VectorIterator(T* d, int l) : data_(Vector<const T>(d, l)), index_(0) { }
VectorIterator(Vector<const T> data)5954    explicit VectorIterator(Vector<const T> data) : data_(data), index_(0) { }
GetNext()5955    T GetNext() { return data_[index_++]; }
has_more()5956    bool has_more() { return index_ < data_.length(); }
5957   private:
5958    Vector<const T> data_;
5959    int index_;
5960  };
5961  
5962  
5963  // The Oddball describes objects null, undefined, true, and false.
5964  class Oddball: public HeapObject {
5965   public:
5966    // [to_string]: Cached to_string computed at startup.
5967    DECL_ACCESSORS(to_string, String)
5968  
5969    // [to_number]: Cached to_number computed at startup.
5970    DECL_ACCESSORS(to_number, Object)
5971  
5972    inline byte kind();
5973    inline void set_kind(byte kind);
5974  
5975    // Casting.
5976    static inline Oddball* cast(Object* obj);
5977  
5978    // Dispatched behavior.
5979  #ifdef DEBUG
5980    void OddballVerify();
5981  #endif
5982  
5983    // Initialize the fields.
5984    MUST_USE_RESULT MaybeObject* Initialize(const char* to_string,
5985                                            Object* to_number,
5986                                            byte kind);
5987  
5988    // Layout description.
5989    static const int kToStringOffset = HeapObject::kHeaderSize;
5990    static const int kToNumberOffset = kToStringOffset + kPointerSize;
5991    static const int kKindOffset = kToNumberOffset + kPointerSize;
5992    static const int kSize = kKindOffset + kPointerSize;
5993  
5994    static const byte kFalse = 0;
5995    static const byte kTrue = 1;
5996    static const byte kNotBooleanMask = ~1;
5997    static const byte kTheHole = 2;
5998    static const byte kNull = 3;
5999    static const byte kArgumentMarker = 4;
6000    static const byte kUndefined = 5;
6001    static const byte kOther = 6;
6002  
6003    typedef FixedBodyDescriptor<kToStringOffset,
6004                                kToNumberOffset + kPointerSize,
6005                                kSize> BodyDescriptor;
6006  
6007   private:
6008    DISALLOW_IMPLICIT_CONSTRUCTORS(Oddball);
6009  };
6010  
6011  
6012  class JSGlobalPropertyCell: public HeapObject {
6013   public:
6014    // [value]: value of the global property.
6015    DECL_ACCESSORS(value, Object)
6016  
6017    // Casting.
6018    static inline JSGlobalPropertyCell* cast(Object* obj);
6019  
6020  #ifdef DEBUG
6021    void JSGlobalPropertyCellVerify();
6022  #endif
6023  #ifdef OBJECT_PRINT
JSGlobalPropertyCellPrint()6024    inline void JSGlobalPropertyCellPrint() {
6025      JSGlobalPropertyCellPrint(stdout);
6026    }
6027    void JSGlobalPropertyCellPrint(FILE* out);
6028  #endif
6029  
6030    // Layout description.
6031    static const int kValueOffset = HeapObject::kHeaderSize;
6032    static const int kSize = kValueOffset + kPointerSize;
6033  
6034    typedef FixedBodyDescriptor<kValueOffset,
6035                                kValueOffset + kPointerSize,
6036                                kSize> BodyDescriptor;
6037  
6038    // Returns the isolate/heap this cell object belongs to.
6039    inline Isolate* isolate();
6040    inline Heap* heap();
6041  
6042   private:
6043    DISALLOW_IMPLICIT_CONSTRUCTORS(JSGlobalPropertyCell);
6044  };
6045  
6046  
6047  
6048  // Proxy describes objects pointing from JavaScript to C structures.
6049  // Since they cannot contain references to JS HeapObjects they can be
6050  // placed in old_data_space.
6051  class Proxy: public HeapObject {
6052   public:
6053    // [proxy]: field containing the address.
6054    inline Address proxy();
6055    inline void set_proxy(Address value);
6056  
6057    // Casting.
6058    static inline Proxy* cast(Object* obj);
6059  
6060    // Dispatched behavior.
6061    inline void ProxyIterateBody(ObjectVisitor* v);
6062  
6063    template<typename StaticVisitor>
6064    inline void ProxyIterateBody();
6065  
6066  #ifdef OBJECT_PRINT
ProxyPrint()6067    inline void ProxyPrint() {
6068      ProxyPrint(stdout);
6069    }
6070    void ProxyPrint(FILE* out);
6071  #endif
6072  #ifdef DEBUG
6073    void ProxyVerify();
6074  #endif
6075  
6076    // Layout description.
6077  
6078    static const int kProxyOffset = HeapObject::kHeaderSize;
6079    static const int kSize = kProxyOffset + kPointerSize;
6080  
6081    STATIC_CHECK(kProxyOffset == Internals::kProxyProxyOffset);
6082  
6083   private:
6084    DISALLOW_IMPLICIT_CONSTRUCTORS(Proxy);
6085  };
6086  
6087  
6088  // The JSArray describes JavaScript Arrays
6089  //  Such an array can be in one of two modes:
6090  //    - fast, backing storage is a FixedArray and length <= elements.length();
6091  //       Please note: push and pop can be used to grow and shrink the array.
6092  //    - slow, backing storage is a HashTable with numbers as keys.
6093  class JSArray: public JSObject {
6094   public:
6095    // [length]: The length property.
6096    DECL_ACCESSORS(length, Object)
6097  
6098    // Overload the length setter to skip write barrier when the length
6099    // is set to a smi. This matches the set function on FixedArray.
6100    inline void set_length(Smi* length);
6101  
6102    MUST_USE_RESULT MaybeObject* JSArrayUpdateLengthFromIndex(uint32_t index,
6103                                                              Object* value);
6104  
6105    // Initialize the array with the given capacity. The function may
6106    // fail due to out-of-memory situations, but only if the requested
6107    // capacity is non-zero.
6108    MUST_USE_RESULT MaybeObject* Initialize(int capacity);
6109  
6110    // Set the content of the array to the content of storage.
6111    inline void SetContent(FixedArray* storage);
6112  
6113    // Casting.
6114    static inline JSArray* cast(Object* obj);
6115  
6116    // Uses handles.  Ensures that the fixed array backing the JSArray has at
6117    // least the stated size.
6118    inline void EnsureSize(int minimum_size_of_backing_fixed_array);
6119  
6120    // Dispatched behavior.
6121  #ifdef OBJECT_PRINT
JSArrayPrint()6122    inline void JSArrayPrint() {
6123      JSArrayPrint(stdout);
6124    }
6125    void JSArrayPrint(FILE* out);
6126  #endif
6127  #ifdef DEBUG
6128    void JSArrayVerify();
6129  #endif
6130  
6131    // Number of element slots to pre-allocate for an empty array.
6132    static const int kPreallocatedArrayElements = 4;
6133  
6134    // Layout description.
6135    static const int kLengthOffset = JSObject::kHeaderSize;
6136    static const int kSize = kLengthOffset + kPointerSize;
6137  
6138   private:
6139    // Expand the fixed array backing of a fast-case JSArray to at least
6140    // the requested size.
6141    void Expand(int minimum_size_of_backing_fixed_array);
6142  
6143    DISALLOW_IMPLICIT_CONSTRUCTORS(JSArray);
6144  };
6145  
6146  
6147  // JSRegExpResult is just a JSArray with a specific initial map.
6148  // This initial map adds in-object properties for "index" and "input"
6149  // properties, as assigned by RegExp.prototype.exec, which allows
6150  // faster creation of RegExp exec results.
6151  // This class just holds constants used when creating the result.
6152  // After creation the result must be treated as a JSArray in all regards.
6153  class JSRegExpResult: public JSArray {
6154   public:
6155    // Offsets of object fields.
6156    static const int kIndexOffset = JSArray::kSize;
6157    static const int kInputOffset = kIndexOffset + kPointerSize;
6158    static const int kSize = kInputOffset + kPointerSize;
6159    // Indices of in-object properties.
6160    static const int kIndexIndex = 0;
6161    static const int kInputIndex = 1;
6162   private:
6163    DISALLOW_IMPLICIT_CONSTRUCTORS(JSRegExpResult);
6164  };
6165  
6166  
6167  // An accessor must have a getter, but can have no setter.
6168  //
6169  // When setting a property, V8 searches accessors in prototypes.
6170  // If an accessor was found and it does not have a setter,
6171  // the request is ignored.
6172  //
6173  // If the accessor in the prototype has the READ_ONLY property attribute, then
6174  // a new value is added to the local object when the property is set.
6175  // This shadows the accessor in the prototype.
6176  class AccessorInfo: public Struct {
6177   public:
6178    DECL_ACCESSORS(getter, Object)
6179    DECL_ACCESSORS(setter, Object)
6180    DECL_ACCESSORS(data, Object)
6181    DECL_ACCESSORS(name, Object)
6182    DECL_ACCESSORS(flag, Smi)
6183  
6184    inline bool all_can_read();
6185    inline void set_all_can_read(bool value);
6186  
6187    inline bool all_can_write();
6188    inline void set_all_can_write(bool value);
6189  
6190    inline bool prohibits_overwriting();
6191    inline void set_prohibits_overwriting(bool value);
6192  
6193    inline PropertyAttributes property_attributes();
6194    inline void set_property_attributes(PropertyAttributes attributes);
6195  
6196    static inline AccessorInfo* cast(Object* obj);
6197  
6198  #ifdef OBJECT_PRINT
AccessorInfoPrint()6199    inline void AccessorInfoPrint() {
6200      AccessorInfoPrint(stdout);
6201    }
6202    void AccessorInfoPrint(FILE* out);
6203  #endif
6204  #ifdef DEBUG
6205    void AccessorInfoVerify();
6206  #endif
6207  
6208    static const int kGetterOffset = HeapObject::kHeaderSize;
6209    static const int kSetterOffset = kGetterOffset + kPointerSize;
6210    static const int kDataOffset = kSetterOffset + kPointerSize;
6211    static const int kNameOffset = kDataOffset + kPointerSize;
6212    static const int kFlagOffset = kNameOffset + kPointerSize;
6213    static const int kSize = kFlagOffset + kPointerSize;
6214  
6215   private:
6216    // Bit positions in flag.
6217    static const int kAllCanReadBit = 0;
6218    static const int kAllCanWriteBit = 1;
6219    static const int kProhibitsOverwritingBit = 2;
6220    class AttributesField: public BitField<PropertyAttributes, 3, 3> {};
6221  
6222    DISALLOW_IMPLICIT_CONSTRUCTORS(AccessorInfo);
6223  };
6224  
6225  
6226  class AccessCheckInfo: public Struct {
6227   public:
6228    DECL_ACCESSORS(named_callback, Object)
6229    DECL_ACCESSORS(indexed_callback, Object)
6230    DECL_ACCESSORS(data, Object)
6231  
6232    static inline AccessCheckInfo* cast(Object* obj);
6233  
6234  #ifdef OBJECT_PRINT
AccessCheckInfoPrint()6235    inline void AccessCheckInfoPrint() {
6236      AccessCheckInfoPrint(stdout);
6237    }
6238    void AccessCheckInfoPrint(FILE* out);
6239  #endif
6240  #ifdef DEBUG
6241    void AccessCheckInfoVerify();
6242  #endif
6243  
6244    static const int kNamedCallbackOffset   = HeapObject::kHeaderSize;
6245    static const int kIndexedCallbackOffset = kNamedCallbackOffset + kPointerSize;
6246    static const int kDataOffset = kIndexedCallbackOffset + kPointerSize;
6247    static const int kSize = kDataOffset + kPointerSize;
6248  
6249   private:
6250    DISALLOW_IMPLICIT_CONSTRUCTORS(AccessCheckInfo);
6251  };
6252  
6253  
6254  class InterceptorInfo: public Struct {
6255   public:
6256    DECL_ACCESSORS(getter, Object)
6257    DECL_ACCESSORS(setter, Object)
6258    DECL_ACCESSORS(query, Object)
6259    DECL_ACCESSORS(deleter, Object)
6260    DECL_ACCESSORS(enumerator, Object)
6261    DECL_ACCESSORS(data, Object)
6262  
6263    static inline InterceptorInfo* cast(Object* obj);
6264  
6265  #ifdef OBJECT_PRINT
InterceptorInfoPrint()6266    inline void InterceptorInfoPrint() {
6267      InterceptorInfoPrint(stdout);
6268    }
6269    void InterceptorInfoPrint(FILE* out);
6270  #endif
6271  #ifdef DEBUG
6272    void InterceptorInfoVerify();
6273  #endif
6274  
6275    static const int kGetterOffset = HeapObject::kHeaderSize;
6276    static const int kSetterOffset = kGetterOffset + kPointerSize;
6277    static const int kQueryOffset = kSetterOffset + kPointerSize;
6278    static const int kDeleterOffset = kQueryOffset + kPointerSize;
6279    static const int kEnumeratorOffset = kDeleterOffset + kPointerSize;
6280    static const int kDataOffset = kEnumeratorOffset + kPointerSize;
6281    static const int kSize = kDataOffset + kPointerSize;
6282  
6283   private:
6284    DISALLOW_IMPLICIT_CONSTRUCTORS(InterceptorInfo);
6285  };
6286  
6287  
6288  class CallHandlerInfo: public Struct {
6289   public:
6290    DECL_ACCESSORS(callback, Object)
6291    DECL_ACCESSORS(data, Object)
6292  
6293    static inline CallHandlerInfo* cast(Object* obj);
6294  
6295  #ifdef OBJECT_PRINT
CallHandlerInfoPrint()6296    inline void CallHandlerInfoPrint() {
6297      CallHandlerInfoPrint(stdout);
6298    }
6299    void CallHandlerInfoPrint(FILE* out);
6300  #endif
6301  #ifdef DEBUG
6302    void CallHandlerInfoVerify();
6303  #endif
6304  
6305    static const int kCallbackOffset = HeapObject::kHeaderSize;
6306    static const int kDataOffset = kCallbackOffset + kPointerSize;
6307    static const int kSize = kDataOffset + kPointerSize;
6308  
6309   private:
6310    DISALLOW_IMPLICIT_CONSTRUCTORS(CallHandlerInfo);
6311  };
6312  
6313  
6314  class TemplateInfo: public Struct {
6315   public:
6316    DECL_ACCESSORS(tag, Object)
6317    DECL_ACCESSORS(property_list, Object)
6318  
6319  #ifdef DEBUG
6320    void TemplateInfoVerify();
6321  #endif
6322  
6323    static const int kTagOffset          = HeapObject::kHeaderSize;
6324    static const int kPropertyListOffset = kTagOffset + kPointerSize;
6325    static const int kHeaderSize         = kPropertyListOffset + kPointerSize;
6326   protected:
6327    friend class AGCCVersionRequiresThisClassToHaveAFriendSoHereItIs;
6328    DISALLOW_IMPLICIT_CONSTRUCTORS(TemplateInfo);
6329  };
6330  
6331  
6332  class FunctionTemplateInfo: public TemplateInfo {
6333   public:
6334    DECL_ACCESSORS(serial_number, Object)
6335    DECL_ACCESSORS(call_code, Object)
6336    DECL_ACCESSORS(property_accessors, Object)
6337    DECL_ACCESSORS(prototype_template, Object)
6338    DECL_ACCESSORS(parent_template, Object)
6339    DECL_ACCESSORS(named_property_handler, Object)
6340    DECL_ACCESSORS(indexed_property_handler, Object)
6341    DECL_ACCESSORS(instance_template, Object)
6342    DECL_ACCESSORS(class_name, Object)
6343    DECL_ACCESSORS(signature, Object)
6344    DECL_ACCESSORS(instance_call_handler, Object)
6345    DECL_ACCESSORS(access_check_info, Object)
6346    DECL_ACCESSORS(flag, Smi)
6347  
6348    // Following properties use flag bits.
6349    DECL_BOOLEAN_ACCESSORS(hidden_prototype)
6350    DECL_BOOLEAN_ACCESSORS(undetectable)
6351    // If the bit is set, object instances created by this function
6352    // requires access check.
6353    DECL_BOOLEAN_ACCESSORS(needs_access_check)
6354  
6355    static inline FunctionTemplateInfo* cast(Object* obj);
6356  
6357  #ifdef OBJECT_PRINT
FunctionTemplateInfoPrint()6358    inline void FunctionTemplateInfoPrint() {
6359      FunctionTemplateInfoPrint(stdout);
6360    }
6361    void FunctionTemplateInfoPrint(FILE* out);
6362  #endif
6363  #ifdef DEBUG
6364    void FunctionTemplateInfoVerify();
6365  #endif
6366  
6367    static const int kSerialNumberOffset = TemplateInfo::kHeaderSize;
6368    static const int kCallCodeOffset = kSerialNumberOffset + kPointerSize;
6369    static const int kPropertyAccessorsOffset = kCallCodeOffset + kPointerSize;
6370    static const int kPrototypeTemplateOffset =
6371        kPropertyAccessorsOffset + kPointerSize;
6372    static const int kParentTemplateOffset =
6373        kPrototypeTemplateOffset + kPointerSize;
6374    static const int kNamedPropertyHandlerOffset =
6375        kParentTemplateOffset + kPointerSize;
6376    static const int kIndexedPropertyHandlerOffset =
6377        kNamedPropertyHandlerOffset + kPointerSize;
6378    static const int kInstanceTemplateOffset =
6379        kIndexedPropertyHandlerOffset + kPointerSize;
6380    static const int kClassNameOffset = kInstanceTemplateOffset + kPointerSize;
6381    static const int kSignatureOffset = kClassNameOffset + kPointerSize;
6382    static const int kInstanceCallHandlerOffset = kSignatureOffset + kPointerSize;
6383    static const int kAccessCheckInfoOffset =
6384        kInstanceCallHandlerOffset + kPointerSize;
6385    static const int kFlagOffset = kAccessCheckInfoOffset + kPointerSize;
6386    static const int kSize = kFlagOffset + kPointerSize;
6387  
6388   private:
6389    // Bit position in the flag, from least significant bit position.
6390    static const int kHiddenPrototypeBit   = 0;
6391    static const int kUndetectableBit      = 1;
6392    static const int kNeedsAccessCheckBit  = 2;
6393  
6394    DISALLOW_IMPLICIT_CONSTRUCTORS(FunctionTemplateInfo);
6395  };
6396  
6397  
6398  class ObjectTemplateInfo: public TemplateInfo {
6399   public:
6400    DECL_ACCESSORS(constructor, Object)
6401    DECL_ACCESSORS(internal_field_count, Object)
6402  
6403    static inline ObjectTemplateInfo* cast(Object* obj);
6404  
6405  #ifdef OBJECT_PRINT
ObjectTemplateInfoPrint()6406    inline void ObjectTemplateInfoPrint() {
6407      ObjectTemplateInfoPrint(stdout);
6408    }
6409    void ObjectTemplateInfoPrint(FILE* out);
6410  #endif
6411  #ifdef DEBUG
6412    void ObjectTemplateInfoVerify();
6413  #endif
6414  
6415    static const int kConstructorOffset = TemplateInfo::kHeaderSize;
6416    static const int kInternalFieldCountOffset =
6417        kConstructorOffset + kPointerSize;
6418    static const int kSize = kInternalFieldCountOffset + kPointerSize;
6419  };
6420  
6421  
6422  class SignatureInfo: public Struct {
6423   public:
6424    DECL_ACCESSORS(receiver, Object)
6425    DECL_ACCESSORS(args, Object)
6426  
6427    static inline SignatureInfo* cast(Object* obj);
6428  
6429  #ifdef OBJECT_PRINT
SignatureInfoPrint()6430    inline void SignatureInfoPrint() {
6431      SignatureInfoPrint(stdout);
6432    }
6433    void SignatureInfoPrint(FILE* out);
6434  #endif
6435  #ifdef DEBUG
6436    void SignatureInfoVerify();
6437  #endif
6438  
6439    static const int kReceiverOffset = Struct::kHeaderSize;
6440    static const int kArgsOffset     = kReceiverOffset + kPointerSize;
6441    static const int kSize           = kArgsOffset + kPointerSize;
6442  
6443   private:
6444    DISALLOW_IMPLICIT_CONSTRUCTORS(SignatureInfo);
6445  };
6446  
6447  
6448  class TypeSwitchInfo: public Struct {
6449   public:
6450    DECL_ACCESSORS(types, Object)
6451  
6452    static inline TypeSwitchInfo* cast(Object* obj);
6453  
6454  #ifdef OBJECT_PRINT
TypeSwitchInfoPrint()6455    inline void TypeSwitchInfoPrint() {
6456      TypeSwitchInfoPrint(stdout);
6457    }
6458    void TypeSwitchInfoPrint(FILE* out);
6459  #endif
6460  #ifdef DEBUG
6461    void TypeSwitchInfoVerify();
6462  #endif
6463  
6464    static const int kTypesOffset = Struct::kHeaderSize;
6465    static const int kSize        = kTypesOffset + kPointerSize;
6466  };
6467  
6468  
6469  #ifdef ENABLE_DEBUGGER_SUPPORT
6470  // The DebugInfo class holds additional information for a function being
6471  // debugged.
6472  class DebugInfo: public Struct {
6473   public:
6474    // The shared function info for the source being debugged.
6475    DECL_ACCESSORS(shared, SharedFunctionInfo)
6476    // Code object for the original code.
6477    DECL_ACCESSORS(original_code, Code)
6478    // Code object for the patched code. This code object is the code object
6479    // currently active for the function.
6480    DECL_ACCESSORS(code, Code)
6481    // Fixed array holding status information for each active break point.
6482    DECL_ACCESSORS(break_points, FixedArray)
6483  
6484    // Check if there is a break point at a code position.
6485    bool HasBreakPoint(int code_position);
6486    // Get the break point info object for a code position.
6487    Object* GetBreakPointInfo(int code_position);
6488    // Clear a break point.
6489    static void ClearBreakPoint(Handle<DebugInfo> debug_info,
6490                                int code_position,
6491                                Handle<Object> break_point_object);
6492    // Set a break point.
6493    static void SetBreakPoint(Handle<DebugInfo> debug_info, int code_position,
6494                              int source_position, int statement_position,
6495                              Handle<Object> break_point_object);
6496    // Get the break point objects for a code position.
6497    Object* GetBreakPointObjects(int code_position);
6498    // Find the break point info holding this break point object.
6499    static Object* FindBreakPointInfo(Handle<DebugInfo> debug_info,
6500                                      Handle<Object> break_point_object);
6501    // Get the number of break points for this function.
6502    int GetBreakPointCount();
6503  
6504    static inline DebugInfo* cast(Object* obj);
6505  
6506  #ifdef OBJECT_PRINT
DebugInfoPrint()6507    inline void DebugInfoPrint() {
6508      DebugInfoPrint(stdout);
6509    }
6510    void DebugInfoPrint(FILE* out);
6511  #endif
6512  #ifdef DEBUG
6513    void DebugInfoVerify();
6514  #endif
6515  
6516    static const int kSharedFunctionInfoIndex = Struct::kHeaderSize;
6517    static const int kOriginalCodeIndex = kSharedFunctionInfoIndex + kPointerSize;
6518    static const int kPatchedCodeIndex = kOriginalCodeIndex + kPointerSize;
6519    static const int kActiveBreakPointsCountIndex =
6520        kPatchedCodeIndex + kPointerSize;
6521    static const int kBreakPointsStateIndex =
6522        kActiveBreakPointsCountIndex + kPointerSize;
6523    static const int kSize = kBreakPointsStateIndex + kPointerSize;
6524  
6525   private:
6526    static const int kNoBreakPointInfo = -1;
6527  
6528    // Lookup the index in the break_points array for a code position.
6529    int GetBreakPointInfoIndex(int code_position);
6530  
6531    DISALLOW_IMPLICIT_CONSTRUCTORS(DebugInfo);
6532  };
6533  
6534  
6535  // The BreakPointInfo class holds information for break points set in a
6536  // function. The DebugInfo object holds a BreakPointInfo object for each code
6537  // position with one or more break points.
6538  class BreakPointInfo: public Struct {
6539   public:
6540    // The position in the code for the break point.
6541    DECL_ACCESSORS(code_position, Smi)
6542    // The position in the source for the break position.
6543    DECL_ACCESSORS(source_position, Smi)
6544    // The position in the source for the last statement before this break
6545    // position.
6546    DECL_ACCESSORS(statement_position, Smi)
6547    // List of related JavaScript break points.
6548    DECL_ACCESSORS(break_point_objects, Object)
6549  
6550    // Removes a break point.
6551    static void ClearBreakPoint(Handle<BreakPointInfo> info,
6552                                Handle<Object> break_point_object);
6553    // Set a break point.
6554    static void SetBreakPoint(Handle<BreakPointInfo> info,
6555                              Handle<Object> break_point_object);
6556    // Check if break point info has this break point object.
6557    static bool HasBreakPointObject(Handle<BreakPointInfo> info,
6558                                    Handle<Object> break_point_object);
6559    // Get the number of break points for this code position.
6560    int GetBreakPointCount();
6561  
6562    static inline BreakPointInfo* cast(Object* obj);
6563  
6564  #ifdef OBJECT_PRINT
BreakPointInfoPrint()6565    inline void BreakPointInfoPrint() {
6566      BreakPointInfoPrint(stdout);
6567    }
6568    void BreakPointInfoPrint(FILE* out);
6569  #endif
6570  #ifdef DEBUG
6571    void BreakPointInfoVerify();
6572  #endif
6573  
6574    static const int kCodePositionIndex = Struct::kHeaderSize;
6575    static const int kSourcePositionIndex = kCodePositionIndex + kPointerSize;
6576    static const int kStatementPositionIndex =
6577        kSourcePositionIndex + kPointerSize;
6578    static const int kBreakPointObjectsIndex =
6579        kStatementPositionIndex + kPointerSize;
6580    static const int kSize = kBreakPointObjectsIndex + kPointerSize;
6581  
6582   private:
6583    DISALLOW_IMPLICIT_CONSTRUCTORS(BreakPointInfo);
6584  };
6585  #endif  // ENABLE_DEBUGGER_SUPPORT
6586  
6587  
6588  #undef DECL_BOOLEAN_ACCESSORS
6589  #undef DECL_ACCESSORS
6590  
6591  
6592  // Abstract base class for visiting, and optionally modifying, the
6593  // pointers contained in Objects. Used in GC and serialization/deserialization.
6594  class ObjectVisitor BASE_EMBEDDED {
6595   public:
~ObjectVisitor()6596    virtual ~ObjectVisitor() {}
6597  
6598    // Visits a contiguous arrays of pointers in the half-open range
6599    // [start, end). Any or all of the values may be modified on return.
6600    virtual void VisitPointers(Object** start, Object** end) = 0;
6601  
6602    // To allow lazy clearing of inline caches the visitor has
6603    // a rich interface for iterating over Code objects..
6604  
6605    // Visits a code target in the instruction stream.
6606    virtual void VisitCodeTarget(RelocInfo* rinfo);
6607  
6608    // Visits a code entry in a JS function.
6609    virtual void VisitCodeEntry(Address entry_address);
6610  
6611    // Visits a global property cell reference in the instruction stream.
6612    virtual void VisitGlobalPropertyCell(RelocInfo* rinfo);
6613  
6614    // Visits a runtime entry in the instruction stream.
VisitRuntimeEntry(RelocInfo * rinfo)6615    virtual void VisitRuntimeEntry(RelocInfo* rinfo) {}
6616  
6617    // Visits the resource of an ASCII or two-byte string.
VisitExternalAsciiString(v8::String::ExternalAsciiStringResource ** resource)6618    virtual void VisitExternalAsciiString(
6619        v8::String::ExternalAsciiStringResource** resource) {}
VisitExternalTwoByteString(v8::String::ExternalStringResource ** resource)6620    virtual void VisitExternalTwoByteString(
6621        v8::String::ExternalStringResource** resource) {}
6622  
6623    // Visits a debug call target in the instruction stream.
6624    virtual void VisitDebugTarget(RelocInfo* rinfo);
6625  
6626    // Handy shorthand for visiting a single pointer.
VisitPointer(Object ** p)6627    virtual void VisitPointer(Object** p) { VisitPointers(p, p + 1); }
6628  
6629    // Visits a contiguous arrays of external references (references to the C++
6630    // heap) in the half-open range [start, end). Any or all of the values
6631    // may be modified on return.
VisitExternalReferences(Address * start,Address * end)6632    virtual void VisitExternalReferences(Address* start, Address* end) {}
6633  
VisitExternalReference(Address * p)6634    inline void VisitExternalReference(Address* p) {
6635      VisitExternalReferences(p, p + 1);
6636    }
6637  
6638    // Visits a handle that has an embedder-assigned class ID.
VisitEmbedderReference(Object ** p,uint16_t class_id)6639    virtual void VisitEmbedderReference(Object** p, uint16_t class_id) {}
6640  
6641  #ifdef DEBUG
6642    // Intended for serialization/deserialization checking: insert, or
6643    // check for the presence of, a tag at this position in the stream.
Synchronize(const char * tag)6644    virtual void Synchronize(const char* tag) {}
6645  #else
Synchronize(const char * tag)6646    inline void Synchronize(const char* tag) {}
6647  #endif
6648  };
6649  
6650  
6651  class StructBodyDescriptor : public
6652    FlexibleBodyDescriptor<HeapObject::kHeaderSize> {
6653   public:
SizeOf(Map * map,HeapObject * object)6654    static inline int SizeOf(Map* map, HeapObject* object) {
6655      return map->instance_size();
6656    }
6657  };
6658  
6659  
6660  // BooleanBit is a helper class for setting and getting a bit in an
6661  // integer or Smi.
6662  class BooleanBit : public AllStatic {
6663   public:
get(Smi * smi,int bit_position)6664    static inline bool get(Smi* smi, int bit_position) {
6665      return get(smi->value(), bit_position);
6666    }
6667  
get(int value,int bit_position)6668    static inline bool get(int value, int bit_position) {
6669      return (value & (1 << bit_position)) != 0;
6670    }
6671  
set(Smi * smi,int bit_position,bool v)6672    static inline Smi* set(Smi* smi, int bit_position, bool v) {
6673      return Smi::FromInt(set(smi->value(), bit_position, v));
6674    }
6675  
set(int value,int bit_position,bool v)6676    static inline int set(int value, int bit_position, bool v) {
6677      if (v) {
6678        value |= (1 << bit_position);
6679      } else {
6680        value &= ~(1 << bit_position);
6681      }
6682      return value;
6683    }
6684  };
6685  
6686  } }  // namespace v8::internal
6687  
6688  #endif  // V8_OBJECTS_H_
6689