The data contained in this repository can be downloaded to your computer using one of several clients.
Please see the documentation of your version control software client for more information.

Please select the desired protocol below to get the URL.

This URL has Read-Only access.

Statistics
| Branch: | Revision:

main_repo / deps / v8 / src / objects.h @ f230a1cf

History | View | Annotate | Download (393 KB)

1
// Copyright 2012 the V8 project authors. All rights reserved.
2
// Redistribution and use in source and binary forms, with or without
3
// modification, are permitted provided that the following conditions are
4
// met:
5
//
6
//     * Redistributions of source code must retain the above copyright
7
//       notice, this list of conditions and the following disclaimer.
8
//     * Redistributions in binary form must reproduce the above
9
//       copyright notice, this list of conditions and the following
10
//       disclaimer in the documentation and/or other materials provided
11
//       with the distribution.
12
//     * Neither the name of Google Inc. nor the names of its
13
//       contributors may be used to endorse or promote products derived
14
//       from this software without specific prior written permission.
15
//
16
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27

    
28
#ifndef V8_OBJECTS_H_
29
#define V8_OBJECTS_H_
30

    
31
#include "allocation.h"
32
#include "assert-scope.h"
33
#include "builtins.h"
34
#include "elements-kind.h"
35
#include "flags.h"
36
#include "list.h"
37
#include "property-details.h"
38
#include "smart-pointers.h"
39
#include "unicode-inl.h"
40
#if V8_TARGET_ARCH_ARM
41
#include "arm/constants-arm.h"
42
#elif V8_TARGET_ARCH_MIPS
43
#include "mips/constants-mips.h"
44
#endif
45
#include "v8checks.h"
46
#include "zone.h"
47

    
48

    
49
//
50
// Most object types in the V8 JavaScript are described in this file.
51
//
52
// Inheritance hierarchy:
53
// - MaybeObject    (an object or a failure)
54
//   - Failure      (immediate for marking failed operation)
55
//   - Object
56
//     - Smi          (immediate small integer)
57
//     - HeapObject   (superclass for everything allocated in the heap)
58
//       - JSReceiver  (suitable for property access)
59
//         - JSObject
60
//           - JSArray
61
//           - JSArrayBuffer
62
//           - JSArrayBufferView
63
//             - JSTypedArray
64
//             - JSDataView
65
//           - JSSet
66
//           - JSMap
67
//           - JSWeakCollection
68
//             - JSWeakMap
69
//             - JSWeakSet
70
//           - JSRegExp
71
//           - JSFunction
72
//           - JSGeneratorObject
73
//           - JSModule
74
//           - GlobalObject
75
//             - JSGlobalObject
76
//             - JSBuiltinsObject
77
//           - JSGlobalProxy
78
//           - JSValue
79
//             - JSDate
80
//           - JSMessageObject
81
//         - JSProxy
82
//           - JSFunctionProxy
83
//       - FixedArrayBase
84
//         - ByteArray
85
//         - FixedArray
86
//           - DescriptorArray
87
//           - HashTable
88
//             - Dictionary
89
//             - StringTable
90
//             - CompilationCacheTable
91
//             - CodeCacheHashTable
92
//             - MapCache
93
//           - Context
94
//           - JSFunctionResultCache
95
//           - ScopeInfo
96
//           - TransitionArray
97
//         - FixedDoubleArray
98
//         - ExternalArray
99
//           - ExternalPixelArray
100
//           - ExternalByteArray
101
//           - ExternalUnsignedByteArray
102
//           - ExternalShortArray
103
//           - ExternalUnsignedShortArray
104
//           - ExternalIntArray
105
//           - ExternalUnsignedIntArray
106
//           - ExternalFloatArray
107
//       - Name
108
//         - String
109
//           - SeqString
110
//             - SeqOneByteString
111
//             - SeqTwoByteString
112
//           - SlicedString
113
//           - ConsString
114
//           - ExternalString
115
//             - ExternalAsciiString
116
//             - ExternalTwoByteString
117
//           - InternalizedString
118
//             - SeqInternalizedString
119
//               - SeqOneByteInternalizedString
120
//               - SeqTwoByteInternalizedString
121
//             - ConsInternalizedString
122
//             - ExternalInternalizedString
123
//               - ExternalAsciiInternalizedString
124
//               - ExternalTwoByteInternalizedString
125
//         - Symbol
126
//       - HeapNumber
127
//       - Cell
128
//         - PropertyCell
129
//       - Code
130
//       - Map
131
//       - Oddball
132
//       - Foreign
133
//       - SharedFunctionInfo
134
//       - Struct
135
//         - Box
136
//         - DeclaredAccessorDescriptor
137
//         - AccessorInfo
138
//           - DeclaredAccessorInfo
139
//           - ExecutableAccessorInfo
140
//         - AccessorPair
141
//         - AccessCheckInfo
142
//         - InterceptorInfo
143
//         - CallHandlerInfo
144
//         - TemplateInfo
145
//           - FunctionTemplateInfo
146
//           - ObjectTemplateInfo
147
//         - Script
148
//         - SignatureInfo
149
//         - TypeSwitchInfo
150
//         - DebugInfo
151
//         - BreakPointInfo
152
//         - CodeCache
153
//
154
// Formats of Object*:
155
//  Smi:        [31 bit signed int] 0
156
//  HeapObject: [32 bit direct pointer] (4 byte aligned) | 01
157
//  Failure:    [30 bit signed int] 11
158

    
159
namespace v8 {
160
namespace internal {
161

    
162
enum KeyedAccessStoreMode {
163
  STANDARD_STORE,
164
  STORE_TRANSITION_SMI_TO_OBJECT,
165
  STORE_TRANSITION_SMI_TO_DOUBLE,
166
  STORE_TRANSITION_DOUBLE_TO_OBJECT,
167
  STORE_TRANSITION_HOLEY_SMI_TO_OBJECT,
168
  STORE_TRANSITION_HOLEY_SMI_TO_DOUBLE,
169
  STORE_TRANSITION_HOLEY_DOUBLE_TO_OBJECT,
170
  STORE_AND_GROW_NO_TRANSITION,
171
  STORE_AND_GROW_TRANSITION_SMI_TO_OBJECT,
172
  STORE_AND_GROW_TRANSITION_SMI_TO_DOUBLE,
173
  STORE_AND_GROW_TRANSITION_DOUBLE_TO_OBJECT,
174
  STORE_AND_GROW_TRANSITION_HOLEY_SMI_TO_OBJECT,
175
  STORE_AND_GROW_TRANSITION_HOLEY_SMI_TO_DOUBLE,
176
  STORE_AND_GROW_TRANSITION_HOLEY_DOUBLE_TO_OBJECT,
177
  STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS,
178
  STORE_NO_TRANSITION_HANDLE_COW
179
};
180

    
181

    
182
static const int kGrowICDelta = STORE_AND_GROW_NO_TRANSITION -
183
    STANDARD_STORE;
184
STATIC_ASSERT(STANDARD_STORE == 0);
185
STATIC_ASSERT(kGrowICDelta ==
186
              STORE_AND_GROW_TRANSITION_SMI_TO_OBJECT -
187
              STORE_TRANSITION_SMI_TO_OBJECT);
188
STATIC_ASSERT(kGrowICDelta ==
189
              STORE_AND_GROW_TRANSITION_SMI_TO_DOUBLE -
190
              STORE_TRANSITION_SMI_TO_DOUBLE);
191
STATIC_ASSERT(kGrowICDelta ==
192
              STORE_AND_GROW_TRANSITION_DOUBLE_TO_OBJECT -
193
              STORE_TRANSITION_DOUBLE_TO_OBJECT);
194

    
195

    
196
static inline KeyedAccessStoreMode GetGrowStoreMode(
197
    KeyedAccessStoreMode store_mode) {
198
  if (store_mode < STORE_AND_GROW_NO_TRANSITION) {
199
    store_mode = static_cast<KeyedAccessStoreMode>(
200
        static_cast<int>(store_mode) + kGrowICDelta);
201
  }
202
  return store_mode;
203
}
204

    
205

    
206
static inline bool IsTransitionStoreMode(KeyedAccessStoreMode store_mode) {
207
  return store_mode > STANDARD_STORE &&
208
      store_mode <= STORE_AND_GROW_TRANSITION_HOLEY_DOUBLE_TO_OBJECT &&
209
      store_mode != STORE_AND_GROW_NO_TRANSITION;
210
}
211

    
212

    
213
static inline KeyedAccessStoreMode GetNonTransitioningStoreMode(
214
    KeyedAccessStoreMode store_mode) {
215
  if (store_mode >= STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) {
216
    return store_mode;
217
  }
218
  if (store_mode >= STORE_AND_GROW_NO_TRANSITION) {
219
    return STORE_AND_GROW_NO_TRANSITION;
220
  }
221
  return STANDARD_STORE;
222
}
223

    
224

    
225
static inline bool IsGrowStoreMode(KeyedAccessStoreMode store_mode) {
226
  return store_mode >= STORE_AND_GROW_NO_TRANSITION &&
227
      store_mode <= STORE_AND_GROW_TRANSITION_HOLEY_DOUBLE_TO_OBJECT;
228
}
229

    
230

    
231
// Setter that skips the write barrier if mode is SKIP_WRITE_BARRIER.
232
enum WriteBarrierMode { SKIP_WRITE_BARRIER, UPDATE_WRITE_BARRIER };
233

    
234

    
235
// Indicates whether a value can be loaded as a constant.
236
enum StoreMode {
237
  ALLOW_AS_CONSTANT,
238
  FORCE_FIELD
239
};
240

    
241

    
242
// PropertyNormalizationMode is used to specify whether to keep
243
// inobject properties when normalizing properties of a JSObject.
244
enum PropertyNormalizationMode {
245
  CLEAR_INOBJECT_PROPERTIES,
246
  KEEP_INOBJECT_PROPERTIES
247
};
248

    
249

    
250
// NormalizedMapSharingMode is used to specify whether a map may be shared
251
// by different objects with normalized properties.
252
enum NormalizedMapSharingMode {
253
  UNIQUE_NORMALIZED_MAP,
254
  SHARED_NORMALIZED_MAP
255
};
256

    
257

    
258
// Indicates whether a get method should implicitly create the object looked up.
259
enum CreationFlag {
260
  ALLOW_CREATION,
261
  OMIT_CREATION
262
};
263

    
264

    
265
// Indicates whether transitions can be added to a source map or not.
266
enum TransitionFlag {
267
  INSERT_TRANSITION,
268
  OMIT_TRANSITION
269
};
270

    
271

    
272
enum DebugExtraICState {
273
  DEBUG_BREAK,
274
  DEBUG_PREPARE_STEP_IN
275
};
276

    
277

    
278
// Indicates whether the transition is simple: the target map of the transition
279
// either extends the current map with a new property, or it modifies the
280
// property that was added last to the current map.
281
enum SimpleTransitionFlag {
282
  SIMPLE_TRANSITION,
283
  FULL_TRANSITION
284
};
285

    
286

    
287
// Indicates whether we are only interested in the descriptors of a particular
288
// map, or in all descriptors in the descriptor array.
289
enum DescriptorFlag {
290
  ALL_DESCRIPTORS,
291
  OWN_DESCRIPTORS
292
};
293

    
294
// The GC maintains a bit of information, the MarkingParity, which toggles
295
// from odd to even and back every time marking is completed. Incremental
296
// marking can visit an object twice during a marking phase, so algorithms that
297
// that piggy-back on marking can use the parity to ensure that they only
298
// perform an operation on an object once per marking phase: they record the
299
// MarkingParity when they visit an object, and only re-visit the object when it
300
// is marked again and the MarkingParity changes.
301
enum MarkingParity {
302
  NO_MARKING_PARITY,
303
  ODD_MARKING_PARITY,
304
  EVEN_MARKING_PARITY
305
};
306

    
307
// Instance size sentinel for objects of variable size.
308
const int kVariableSizeSentinel = 0;
309

    
310
const int kStubMajorKeyBits = 6;
311
const int kStubMinorKeyBits = kBitsPerInt - kSmiTagSize - kStubMajorKeyBits;
312

    
313
// All Maps have a field instance_type containing a InstanceType.
314
// It describes the type of the instances.
315
//
316
// As an example, a JavaScript object is a heap object and its map
317
// instance_type is JS_OBJECT_TYPE.
318
//
319
// The names of the string instance types are intended to systematically
320
// mirror their encoding in the instance_type field of the map.  The default
321
// encoding is considered TWO_BYTE.  It is not mentioned in the name.  ASCII
322
// encoding is mentioned explicitly in the name.  Likewise, the default
323
// representation is considered sequential.  It is not mentioned in the
324
// name.  The other representations (e.g. CONS, EXTERNAL) are explicitly
325
// mentioned.  Finally, the string is either a STRING_TYPE (if it is a normal
326
// string) or a INTERNALIZED_STRING_TYPE (if it is a internalized string).
327
//
328
// NOTE: The following things are some that depend on the string types having
329
// instance_types that are less than those of all other types:
330
// HeapObject::Size, HeapObject::IterateBody, the typeof operator, and
331
// Object::IsString.
332
//
333
// NOTE: Everything following JS_VALUE_TYPE is considered a
334
// JSObject for GC purposes. The first four entries here have typeof
335
// 'object', whereas JS_FUNCTION_TYPE has typeof 'function'.
336
#define INSTANCE_TYPE_LIST(V)                                                  \
337
  V(STRING_TYPE)                                                               \
338
  V(ASCII_STRING_TYPE)                                                         \
339
  V(CONS_STRING_TYPE)                                                          \
340
  V(CONS_ASCII_STRING_TYPE)                                                    \
341
  V(SLICED_STRING_TYPE)                                                        \
342
  V(SLICED_ASCII_STRING_TYPE)                                                  \
343
  V(EXTERNAL_STRING_TYPE)                                                      \
344
  V(EXTERNAL_ASCII_STRING_TYPE)                                                \
345
  V(EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE)                                   \
346
  V(SHORT_EXTERNAL_STRING_TYPE)                                                \
347
  V(SHORT_EXTERNAL_ASCII_STRING_TYPE)                                          \
348
  V(SHORT_EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE)                             \
349
                                                                               \
350
  V(INTERNALIZED_STRING_TYPE)                                                  \
351
  V(ASCII_INTERNALIZED_STRING_TYPE)                                            \
352
  V(CONS_INTERNALIZED_STRING_TYPE)                                             \
353
  V(CONS_ASCII_INTERNALIZED_STRING_TYPE)                                       \
354
  V(EXTERNAL_INTERNALIZED_STRING_TYPE)                                         \
355
  V(EXTERNAL_ASCII_INTERNALIZED_STRING_TYPE)                                   \
356
  V(EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE)                      \
357
  V(SHORT_EXTERNAL_INTERNALIZED_STRING_TYPE)                                   \
358
  V(SHORT_EXTERNAL_ASCII_INTERNALIZED_STRING_TYPE)                             \
359
  V(SHORT_EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE)                \
360
                                                                               \
361
  V(SYMBOL_TYPE)                                                               \
362
  V(MAP_TYPE)                                                                  \
363
  V(CODE_TYPE)                                                                 \
364
  V(ODDBALL_TYPE)                                                              \
365
  V(CELL_TYPE)                                                                 \
366
  V(PROPERTY_CELL_TYPE)                                                        \
367
                                                                               \
368
  V(HEAP_NUMBER_TYPE)                                                          \
369
  V(FOREIGN_TYPE)                                                              \
370
  V(BYTE_ARRAY_TYPE)                                                           \
371
  V(FREE_SPACE_TYPE)                                                           \
372
  /* Note: the order of these external array */                                \
373
  /* types is relied upon in */                                                \
374
  /* Object::IsExternalArray(). */                                             \
375
  V(EXTERNAL_BYTE_ARRAY_TYPE)                                                  \
376
  V(EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)                                         \
377
  V(EXTERNAL_SHORT_ARRAY_TYPE)                                                 \
378
  V(EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)                                        \
379
  V(EXTERNAL_INT_ARRAY_TYPE)                                                   \
380
  V(EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)                                          \
381
  V(EXTERNAL_FLOAT_ARRAY_TYPE)                                                 \
382
  V(EXTERNAL_DOUBLE_ARRAY_TYPE)                                                \
383
  V(EXTERNAL_PIXEL_ARRAY_TYPE)                                                 \
384
  V(FILLER_TYPE)                                                               \
385
                                                                               \
386
  V(DECLARED_ACCESSOR_DESCRIPTOR_TYPE)                                         \
387
  V(DECLARED_ACCESSOR_INFO_TYPE)                                               \
388
  V(EXECUTABLE_ACCESSOR_INFO_TYPE)                                             \
389
  V(ACCESSOR_PAIR_TYPE)                                                        \
390
  V(ACCESS_CHECK_INFO_TYPE)                                                    \
391
  V(INTERCEPTOR_INFO_TYPE)                                                     \
392
  V(CALL_HANDLER_INFO_TYPE)                                                    \
393
  V(FUNCTION_TEMPLATE_INFO_TYPE)                                               \
394
  V(OBJECT_TEMPLATE_INFO_TYPE)                                                 \
395
  V(SIGNATURE_INFO_TYPE)                                                       \
396
  V(TYPE_SWITCH_INFO_TYPE)                                                     \
397
  V(ALLOCATION_MEMENTO_TYPE)                                                   \
398
  V(ALLOCATION_SITE_TYPE)                                                      \
399
  V(SCRIPT_TYPE)                                                               \
400
  V(CODE_CACHE_TYPE)                                                           \
401
  V(POLYMORPHIC_CODE_CACHE_TYPE)                                               \
402
  V(TYPE_FEEDBACK_INFO_TYPE)                                                   \
403
  V(ALIASED_ARGUMENTS_ENTRY_TYPE)                                              \
404
  V(BOX_TYPE)                                                                  \
405
                                                                               \
406
  V(FIXED_ARRAY_TYPE)                                                          \
407
  V(FIXED_DOUBLE_ARRAY_TYPE)                                                   \
408
  V(CONSTANT_POOL_ARRAY_TYPE)                                                  \
409
  V(SHARED_FUNCTION_INFO_TYPE)                                                 \
410
                                                                               \
411
  V(JS_MESSAGE_OBJECT_TYPE)                                                    \
412
                                                                               \
413
  V(JS_VALUE_TYPE)                                                             \
414
  V(JS_DATE_TYPE)                                                              \
415
  V(JS_OBJECT_TYPE)                                                            \
416
  V(JS_CONTEXT_EXTENSION_OBJECT_TYPE)                                          \
417
  V(JS_GENERATOR_OBJECT_TYPE)                                                  \
418
  V(JS_MODULE_TYPE)                                                            \
419
  V(JS_GLOBAL_OBJECT_TYPE)                                                     \
420
  V(JS_BUILTINS_OBJECT_TYPE)                                                   \
421
  V(JS_GLOBAL_PROXY_TYPE)                                                      \
422
  V(JS_ARRAY_TYPE)                                                             \
423
  V(JS_ARRAY_BUFFER_TYPE)                                                      \
424
  V(JS_TYPED_ARRAY_TYPE)                                                       \
425
  V(JS_DATA_VIEW_TYPE)                                                         \
426
  V(JS_PROXY_TYPE)                                                             \
427
  V(JS_SET_TYPE)                                                               \
428
  V(JS_MAP_TYPE)                                                               \
429
  V(JS_WEAK_MAP_TYPE)                                                          \
430
  V(JS_WEAK_SET_TYPE)                                                          \
431
  V(JS_REGEXP_TYPE)                                                            \
432
                                                                               \
433
  V(JS_FUNCTION_TYPE)                                                          \
434
  V(JS_FUNCTION_PROXY_TYPE)                                                    \
435
  V(DEBUG_INFO_TYPE)                                                           \
436
  V(BREAK_POINT_INFO_TYPE)
437

    
438

    
439
// Since string types are not consecutive, this macro is used to
440
// iterate over them.
441
#define STRING_TYPE_LIST(V)                                                    \
442
  V(STRING_TYPE,                                                               \
443
    kVariableSizeSentinel,                                                     \
444
    string,                                                                    \
445
    String)                                                                    \
446
  V(ASCII_STRING_TYPE,                                                         \
447
    kVariableSizeSentinel,                                                     \
448
    ascii_string,                                                              \
449
    AsciiString)                                                               \
450
  V(CONS_STRING_TYPE,                                                          \
451
    ConsString::kSize,                                                         \
452
    cons_string,                                                               \
453
    ConsString)                                                                \
454
  V(CONS_ASCII_STRING_TYPE,                                                    \
455
    ConsString::kSize,                                                         \
456
    cons_ascii_string,                                                         \
457
    ConsAsciiString)                                                           \
458
  V(SLICED_STRING_TYPE,                                                        \
459
    SlicedString::kSize,                                                       \
460
    sliced_string,                                                             \
461
    SlicedString)                                                              \
462
  V(SLICED_ASCII_STRING_TYPE,                                                  \
463
    SlicedString::kSize,                                                       \
464
    sliced_ascii_string,                                                       \
465
    SlicedAsciiString)                                                         \
466
  V(EXTERNAL_STRING_TYPE,                                                      \
467
    ExternalTwoByteString::kSize,                                              \
468
    external_string,                                                           \
469
    ExternalString)                                                            \
470
  V(EXTERNAL_ASCII_STRING_TYPE,                                                \
471
    ExternalAsciiString::kSize,                                                \
472
    external_ascii_string,                                                     \
473
    ExternalAsciiString)                                                       \
474
  V(EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE,                                   \
475
    ExternalTwoByteString::kSize,                                              \
476
    external_string_with_one_bytei_data,                                       \
477
    ExternalStringWithOneByteData)                                             \
478
  V(SHORT_EXTERNAL_STRING_TYPE,                                                \
479
    ExternalTwoByteString::kShortSize,                                         \
480
    short_external_string,                                                     \
481
    ShortExternalString)                                                       \
482
  V(SHORT_EXTERNAL_ASCII_STRING_TYPE,                                          \
483
    ExternalAsciiString::kShortSize,                                           \
484
    short_external_ascii_string,                                               \
485
    ShortExternalAsciiString)                                                  \
486
  V(SHORT_EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE,                             \
487
    ExternalTwoByteString::kShortSize,                                         \
488
    short_external_string_with_one_byte_data,                                  \
489
    ShortExternalStringWithOneByteData)                                        \
490
                                                                               \
491
  V(INTERNALIZED_STRING_TYPE,                                                  \
492
    kVariableSizeSentinel,                                                     \
493
    internalized_string,                                                       \
494
    InternalizedString)                                                        \
495
  V(ASCII_INTERNALIZED_STRING_TYPE,                                            \
496
    kVariableSizeSentinel,                                                     \
497
    ascii_internalized_string,                                                 \
498
    AsciiInternalizedString)                                                   \
499
  V(CONS_INTERNALIZED_STRING_TYPE,                                             \
500
    ConsString::kSize,                                                         \
501
    cons_internalized_string,                                                  \
502
    ConsInternalizedString)                                                    \
503
  V(CONS_ASCII_INTERNALIZED_STRING_TYPE,                                       \
504
    ConsString::kSize,                                                         \
505
    cons_ascii_internalized_string,                                            \
506
    ConsAsciiInternalizedString)                                               \
507
  V(EXTERNAL_INTERNALIZED_STRING_TYPE,                                         \
508
    ExternalTwoByteString::kSize,                                              \
509
    external_internalized_string,                                              \
510
    ExternalInternalizedString)                                                \
511
  V(EXTERNAL_ASCII_INTERNALIZED_STRING_TYPE,                                   \
512
    ExternalAsciiString::kSize,                                                \
513
    external_ascii_internalized_string,                                        \
514
    ExternalAsciiInternalizedString)                                           \
515
  V(EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE,                      \
516
    ExternalTwoByteString::kSize,                                              \
517
    external_internalized_string_with_one_byte_data,                           \
518
    ExternalInternalizedStringWithOneByteData)                                 \
519
  V(SHORT_EXTERNAL_INTERNALIZED_STRING_TYPE,                                   \
520
    ExternalTwoByteString::kShortSize,                                         \
521
    short_external_internalized_string,                                        \
522
    ShortExternalInternalizedString)                                           \
523
  V(SHORT_EXTERNAL_ASCII_INTERNALIZED_STRING_TYPE,                             \
524
    ExternalAsciiString::kShortSize,                                           \
525
    short_external_ascii_internalized_string,                                  \
526
    ShortExternalAsciiInternalizedString)                                      \
527
  V(SHORT_EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE,                \
528
    ExternalTwoByteString::kShortSize,                                         \
529
    short_external_internalized_string_with_one_byte_data,                     \
530
    ShortExternalInternalizedStringWithOneByteData)                            \
531

    
532
// A struct is a simple object a set of object-valued fields.  Including an
533
// object type in this causes the compiler to generate most of the boilerplate
534
// code for the class including allocation and garbage collection routines,
535
// casts and predicates.  All you need to define is the class, methods and
536
// object verification routines.  Easy, no?
537
//
538
// Note that for subtle reasons related to the ordering or numerical values of
539
// type tags, elements in this list have to be added to the INSTANCE_TYPE_LIST
540
// manually.
541
#define STRUCT_LIST_ALL(V)                                                     \
542
  V(BOX, Box, box)                                                             \
543
  V(DECLARED_ACCESSOR_DESCRIPTOR,                                              \
544
    DeclaredAccessorDescriptor,                                                \
545
    declared_accessor_descriptor)                                              \
546
  V(DECLARED_ACCESSOR_INFO, DeclaredAccessorInfo, declared_accessor_info)      \
547
  V(EXECUTABLE_ACCESSOR_INFO, ExecutableAccessorInfo, executable_accessor_info)\
548
  V(ACCESSOR_PAIR, AccessorPair, accessor_pair)                                \
549
  V(ACCESS_CHECK_INFO, AccessCheckInfo, access_check_info)                     \
550
  V(INTERCEPTOR_INFO, InterceptorInfo, interceptor_info)                       \
551
  V(CALL_HANDLER_INFO, CallHandlerInfo, call_handler_info)                     \
552
  V(FUNCTION_TEMPLATE_INFO, FunctionTemplateInfo, function_template_info)      \
553
  V(OBJECT_TEMPLATE_INFO, ObjectTemplateInfo, object_template_info)            \
554
  V(SIGNATURE_INFO, SignatureInfo, signature_info)                             \
555
  V(TYPE_SWITCH_INFO, TypeSwitchInfo, type_switch_info)                        \
556
  V(SCRIPT, Script, script)                                                    \
557
  V(ALLOCATION_SITE, AllocationSite, allocation_site)                          \
558
  V(ALLOCATION_MEMENTO, AllocationMemento, allocation_memento)                 \
559
  V(CODE_CACHE, CodeCache, code_cache)                                         \
560
  V(POLYMORPHIC_CODE_CACHE, PolymorphicCodeCache, polymorphic_code_cache)      \
561
  V(TYPE_FEEDBACK_INFO, TypeFeedbackInfo, type_feedback_info)                  \
562
  V(ALIASED_ARGUMENTS_ENTRY, AliasedArgumentsEntry, aliased_arguments_entry)
563

    
564
#ifdef ENABLE_DEBUGGER_SUPPORT
565
#define STRUCT_LIST_DEBUGGER(V)                                                \
566
  V(DEBUG_INFO, DebugInfo, debug_info)                                         \
567
  V(BREAK_POINT_INFO, BreakPointInfo, break_point_info)
568
#else
569
#define STRUCT_LIST_DEBUGGER(V)
570
#endif
571

    
572
#define STRUCT_LIST(V)                                                         \
573
  STRUCT_LIST_ALL(V)                                                           \
574
  STRUCT_LIST_DEBUGGER(V)
575

    
576
// We use the full 8 bits of the instance_type field to encode heap object
577
// instance types.  The high-order bit (bit 7) is set if the object is not a
578
// string, and cleared if it is a string.
579
const uint32_t kIsNotStringMask = 0x80;
580
const uint32_t kStringTag = 0x0;
581
const uint32_t kNotStringTag = 0x80;
582

    
583
// Bit 6 indicates that the object is an internalized string (if set) or not.
584
// Bit 7 has to be clear as well.
585
const uint32_t kIsNotInternalizedMask = 0x40;
586
const uint32_t kNotInternalizedTag = 0x40;
587
const uint32_t kInternalizedTag = 0x0;
588

    
589
// If bit 7 is clear then bit 2 indicates whether the string consists of
590
// two-byte characters or one-byte characters.
591
const uint32_t kStringEncodingMask = 0x4;
592
const uint32_t kTwoByteStringTag = 0x0;
593
const uint32_t kOneByteStringTag = 0x4;
594

    
595
// If bit 7 is clear, the low-order 2 bits indicate the representation
596
// of the string.
597
const uint32_t kStringRepresentationMask = 0x03;
598
enum StringRepresentationTag {
599
  kSeqStringTag = 0x0,
600
  kConsStringTag = 0x1,
601
  kExternalStringTag = 0x2,
602
  kSlicedStringTag = 0x3
603
};
604
const uint32_t kIsIndirectStringMask = 0x1;
605
const uint32_t kIsIndirectStringTag = 0x1;
606
STATIC_ASSERT((kSeqStringTag & kIsIndirectStringMask) == 0);
607
STATIC_ASSERT((kExternalStringTag & kIsIndirectStringMask) == 0);
608
STATIC_ASSERT(
609
    (kConsStringTag & kIsIndirectStringMask) == kIsIndirectStringTag);
610
STATIC_ASSERT(
611
    (kSlicedStringTag & kIsIndirectStringMask) == kIsIndirectStringTag);
612

    
613
// Use this mask to distinguish between cons and slice only after making
614
// sure that the string is one of the two (an indirect string).
615
const uint32_t kSlicedNotConsMask = kSlicedStringTag & ~kConsStringTag;
616
STATIC_ASSERT(IS_POWER_OF_TWO(kSlicedNotConsMask) && kSlicedNotConsMask != 0);
617

    
618
// If bit 7 is clear, then bit 3 indicates whether this two-byte
619
// string actually contains one byte data.
620
const uint32_t kOneByteDataHintMask = 0x08;
621
const uint32_t kOneByteDataHintTag = 0x08;
622

    
623
// If bit 7 is clear and string representation indicates an external string,
624
// then bit 4 indicates whether the data pointer is cached.
625
const uint32_t kShortExternalStringMask = 0x10;
626
const uint32_t kShortExternalStringTag = 0x10;
627

    
628

    
629
// A ConsString with an empty string as the right side is a candidate
630
// for being shortcut by the garbage collector unless it is internalized.
631
// It's not common to have non-flat internalized strings, so we do not
632
// shortcut them thereby avoiding turning internalized strings into strings.
633
// See heap.cc and mark-compact.cc.
634
const uint32_t kShortcutTypeMask =
635
    kIsNotStringMask |
636
    kIsNotInternalizedMask |
637
    kStringRepresentationMask;
638
const uint32_t kShortcutTypeTag = kConsStringTag | kNotInternalizedTag;
639

    
640

    
641
enum InstanceType {
642
  // String types.
643
  INTERNALIZED_STRING_TYPE = kTwoByteStringTag | kSeqStringTag
644
      | kInternalizedTag,
645
  ASCII_INTERNALIZED_STRING_TYPE = kOneByteStringTag | kSeqStringTag
646
      | kInternalizedTag,
647
  CONS_INTERNALIZED_STRING_TYPE = kTwoByteStringTag | kConsStringTag
648
      | kInternalizedTag,
649
  CONS_ASCII_INTERNALIZED_STRING_TYPE = kOneByteStringTag | kConsStringTag
650
      | kInternalizedTag,
651
  EXTERNAL_INTERNALIZED_STRING_TYPE = kTwoByteStringTag | kExternalStringTag
652
      | kInternalizedTag,
653
  EXTERNAL_ASCII_INTERNALIZED_STRING_TYPE = kOneByteStringTag
654
      | kExternalStringTag | kInternalizedTag,
655
  EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE =
656
      EXTERNAL_INTERNALIZED_STRING_TYPE | kOneByteDataHintTag
657
      | kInternalizedTag,
658
  SHORT_EXTERNAL_INTERNALIZED_STRING_TYPE =
659
      EXTERNAL_INTERNALIZED_STRING_TYPE | kShortExternalStringTag
660
      | kInternalizedTag,
661
  SHORT_EXTERNAL_ASCII_INTERNALIZED_STRING_TYPE =
662
      EXTERNAL_ASCII_INTERNALIZED_STRING_TYPE | kShortExternalStringTag
663
      | kInternalizedTag,
664
  SHORT_EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE =
665
      EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE
666
      | kShortExternalStringTag | kInternalizedTag,
667

    
668
  STRING_TYPE = INTERNALIZED_STRING_TYPE | kNotInternalizedTag,
669
  ASCII_STRING_TYPE = ASCII_INTERNALIZED_STRING_TYPE | kNotInternalizedTag,
670
  CONS_STRING_TYPE = CONS_INTERNALIZED_STRING_TYPE | kNotInternalizedTag,
671
  CONS_ASCII_STRING_TYPE =
672
      CONS_ASCII_INTERNALIZED_STRING_TYPE | kNotInternalizedTag,
673

    
674
  SLICED_STRING_TYPE =
675
      kTwoByteStringTag | kSlicedStringTag | kNotInternalizedTag,
676
  SLICED_ASCII_STRING_TYPE =
677
      kOneByteStringTag | kSlicedStringTag | kNotInternalizedTag,
678
  EXTERNAL_STRING_TYPE =
679
  EXTERNAL_INTERNALIZED_STRING_TYPE | kNotInternalizedTag,
680
  EXTERNAL_ASCII_STRING_TYPE =
681
  EXTERNAL_ASCII_INTERNALIZED_STRING_TYPE | kNotInternalizedTag,
682
  EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE =
683
      EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE
684
      | kNotInternalizedTag,
685
  SHORT_EXTERNAL_STRING_TYPE =
686
      SHORT_EXTERNAL_INTERNALIZED_STRING_TYPE | kNotInternalizedTag,
687
  SHORT_EXTERNAL_ASCII_STRING_TYPE =
688
      SHORT_EXTERNAL_ASCII_INTERNALIZED_STRING_TYPE | kNotInternalizedTag,
689
  SHORT_EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE =
690
      SHORT_EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE
691
      | kNotInternalizedTag,
692

    
693
  // Non-string names
694
  SYMBOL_TYPE = kNotStringTag,  // LAST_NAME_TYPE, FIRST_NONSTRING_TYPE
695

    
696
  // Objects allocated in their own spaces (never in new space).
697
  MAP_TYPE,
698
  CODE_TYPE,
699
  ODDBALL_TYPE,
700
  CELL_TYPE,
701
  PROPERTY_CELL_TYPE,
702

    
703
  // "Data", objects that cannot contain non-map-word pointers to heap
704
  // objects.
705
  HEAP_NUMBER_TYPE,
706
  FOREIGN_TYPE,
707
  BYTE_ARRAY_TYPE,
708
  FREE_SPACE_TYPE,
709
  EXTERNAL_BYTE_ARRAY_TYPE,  // FIRST_EXTERNAL_ARRAY_TYPE
710
  EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE,
711
  EXTERNAL_SHORT_ARRAY_TYPE,
712
  EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE,
713
  EXTERNAL_INT_ARRAY_TYPE,
714
  EXTERNAL_UNSIGNED_INT_ARRAY_TYPE,
715
  EXTERNAL_FLOAT_ARRAY_TYPE,
716
  EXTERNAL_DOUBLE_ARRAY_TYPE,
717
  EXTERNAL_PIXEL_ARRAY_TYPE,  // LAST_EXTERNAL_ARRAY_TYPE
718
  FIXED_DOUBLE_ARRAY_TYPE,
719
  CONSTANT_POOL_ARRAY_TYPE,
720
  FILLER_TYPE,  // LAST_DATA_TYPE
721

    
722
  // Structs.
723
  DECLARED_ACCESSOR_DESCRIPTOR_TYPE,
724
  DECLARED_ACCESSOR_INFO_TYPE,
725
  EXECUTABLE_ACCESSOR_INFO_TYPE,
726
  ACCESSOR_PAIR_TYPE,
727
  ACCESS_CHECK_INFO_TYPE,
728
  INTERCEPTOR_INFO_TYPE,
729
  CALL_HANDLER_INFO_TYPE,
730
  FUNCTION_TEMPLATE_INFO_TYPE,
731
  OBJECT_TEMPLATE_INFO_TYPE,
732
  SIGNATURE_INFO_TYPE,
733
  TYPE_SWITCH_INFO_TYPE,
734
  ALLOCATION_SITE_TYPE,
735
  ALLOCATION_MEMENTO_TYPE,
736
  SCRIPT_TYPE,
737
  CODE_CACHE_TYPE,
738
  POLYMORPHIC_CODE_CACHE_TYPE,
739
  TYPE_FEEDBACK_INFO_TYPE,
740
  ALIASED_ARGUMENTS_ENTRY_TYPE,
741
  BOX_TYPE,
742
  // The following two instance types are only used when ENABLE_DEBUGGER_SUPPORT
743
  // is defined. However as include/v8.h contain some of the instance type
744
  // constants always having them avoids them getting different numbers
745
  // depending on whether ENABLE_DEBUGGER_SUPPORT is defined or not.
746
  DEBUG_INFO_TYPE,
747
  BREAK_POINT_INFO_TYPE,
748

    
749
  FIXED_ARRAY_TYPE,
750
  SHARED_FUNCTION_INFO_TYPE,
751

    
752
  JS_MESSAGE_OBJECT_TYPE,
753

    
754
  // All the following types are subtypes of JSReceiver, which corresponds to
755
  // objects in the JS sense. The first and the last type in this range are
756
  // the two forms of function. This organization enables using the same
757
  // compares for checking the JS_RECEIVER/SPEC_OBJECT range and the
758
  // NONCALLABLE_JS_OBJECT range.
759
  JS_FUNCTION_PROXY_TYPE,  // FIRST_JS_RECEIVER_TYPE, FIRST_JS_PROXY_TYPE
760
  JS_PROXY_TYPE,  // LAST_JS_PROXY_TYPE
761

    
762
  JS_VALUE_TYPE,  // FIRST_JS_OBJECT_TYPE
763
  JS_DATE_TYPE,
764
  JS_OBJECT_TYPE,
765
  JS_CONTEXT_EXTENSION_OBJECT_TYPE,
766
  JS_GENERATOR_OBJECT_TYPE,
767
  JS_MODULE_TYPE,
768
  JS_GLOBAL_OBJECT_TYPE,
769
  JS_BUILTINS_OBJECT_TYPE,
770
  JS_GLOBAL_PROXY_TYPE,
771
  JS_ARRAY_TYPE,
772
  JS_ARRAY_BUFFER_TYPE,
773
  JS_TYPED_ARRAY_TYPE,
774
  JS_DATA_VIEW_TYPE,
775
  JS_SET_TYPE,
776
  JS_MAP_TYPE,
777
  JS_WEAK_MAP_TYPE,
778
  JS_WEAK_SET_TYPE,
779

    
780
  JS_REGEXP_TYPE,
781

    
782
  JS_FUNCTION_TYPE,  // LAST_JS_OBJECT_TYPE, LAST_JS_RECEIVER_TYPE
783

    
784
  // Pseudo-types
785
  FIRST_TYPE = 0x0,
786
  LAST_TYPE = JS_FUNCTION_TYPE,
787
  FIRST_NAME_TYPE = FIRST_TYPE,
788
  LAST_NAME_TYPE = SYMBOL_TYPE,
789
  FIRST_UNIQUE_NAME_TYPE = INTERNALIZED_STRING_TYPE,
790
  LAST_UNIQUE_NAME_TYPE = SYMBOL_TYPE,
791
  FIRST_NONSTRING_TYPE = SYMBOL_TYPE,
792
  // Boundaries for testing for an external array.
793
  FIRST_EXTERNAL_ARRAY_TYPE = EXTERNAL_BYTE_ARRAY_TYPE,
794
  LAST_EXTERNAL_ARRAY_TYPE = EXTERNAL_PIXEL_ARRAY_TYPE,
795
  // Boundary for promotion to old data space/old pointer space.
796
  LAST_DATA_TYPE = FILLER_TYPE,
797
  // Boundary for objects represented as JSReceiver (i.e. JSObject or JSProxy).
798
  // Note that there is no range for JSObject or JSProxy, since their subtypes
799
  // are not continuous in this enum! The enum ranges instead reflect the
800
  // external class names, where proxies are treated as either ordinary objects,
801
  // or functions.
802
  FIRST_JS_RECEIVER_TYPE = JS_FUNCTION_PROXY_TYPE,
803
  LAST_JS_RECEIVER_TYPE = LAST_TYPE,
804
  // Boundaries for testing the types represented as JSObject
805
  FIRST_JS_OBJECT_TYPE = JS_VALUE_TYPE,
806
  LAST_JS_OBJECT_TYPE = LAST_TYPE,
807
  // Boundaries for testing the types represented as JSProxy
808
  FIRST_JS_PROXY_TYPE = JS_FUNCTION_PROXY_TYPE,
809
  LAST_JS_PROXY_TYPE = JS_PROXY_TYPE,
810
  // Boundaries for testing whether the type is a JavaScript object.
811
  FIRST_SPEC_OBJECT_TYPE = FIRST_JS_RECEIVER_TYPE,
812
  LAST_SPEC_OBJECT_TYPE = LAST_JS_RECEIVER_TYPE,
813
  // Boundaries for testing the types for which typeof is "object".
814
  FIRST_NONCALLABLE_SPEC_OBJECT_TYPE = JS_PROXY_TYPE,
815
  LAST_NONCALLABLE_SPEC_OBJECT_TYPE = JS_REGEXP_TYPE,
816
  // Note that the types for which typeof is "function" are not continuous.
817
  // Define this so that we can put assertions on discrete checks.
818
  NUM_OF_CALLABLE_SPEC_OBJECT_TYPES = 2
819
};
820

    
821
const int kExternalArrayTypeCount =
822
    LAST_EXTERNAL_ARRAY_TYPE - FIRST_EXTERNAL_ARRAY_TYPE + 1;
823

    
824
STATIC_CHECK(JS_OBJECT_TYPE == Internals::kJSObjectType);
825
STATIC_CHECK(FIRST_NONSTRING_TYPE == Internals::kFirstNonstringType);
826
STATIC_CHECK(ODDBALL_TYPE == Internals::kOddballType);
827
STATIC_CHECK(FOREIGN_TYPE == Internals::kForeignType);
828

    
829

    
830
#define FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(V) \
831
  V(FAST_ELEMENTS_SUB_TYPE)                   \
832
  V(DICTIONARY_ELEMENTS_SUB_TYPE)             \
833
  V(FAST_PROPERTIES_SUB_TYPE)                 \
834
  V(DICTIONARY_PROPERTIES_SUB_TYPE)           \
835
  V(MAP_CODE_CACHE_SUB_TYPE)                  \
836
  V(SCOPE_INFO_SUB_TYPE)                      \
837
  V(STRING_TABLE_SUB_TYPE)                    \
838
  V(DESCRIPTOR_ARRAY_SUB_TYPE)                \
839
  V(TRANSITION_ARRAY_SUB_TYPE)
840

    
841
enum FixedArraySubInstanceType {
842
#define DEFINE_FIXED_ARRAY_SUB_INSTANCE_TYPE(name) name,
843
  FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(DEFINE_FIXED_ARRAY_SUB_INSTANCE_TYPE)
844
#undef DEFINE_FIXED_ARRAY_SUB_INSTANCE_TYPE
845
  LAST_FIXED_ARRAY_SUB_TYPE = TRANSITION_ARRAY_SUB_TYPE
846
};
847

    
848

    
849
enum CompareResult {
850
  LESS      = -1,
851
  EQUAL     =  0,
852
  GREATER   =  1,
853

    
854
  NOT_EQUAL = GREATER
855
};
856

    
857

    
858
#define DECL_BOOLEAN_ACCESSORS(name)   \
859
  inline bool name();                  \
860
  inline void set_##name(bool value);  \
861

    
862

    
863
#define DECL_ACCESSORS(name, type)                                      \
864
  inline type* name();                                                  \
865
  inline void set_##name(type* value,                                   \
866
                         WriteBarrierMode mode = UPDATE_WRITE_BARRIER); \
867

    
868
class AccessorPair;
869
class AllocationSite;
870
class AllocationSiteContext;
871
class DictionaryElementsAccessor;
872
class ElementsAccessor;
873
class Failure;
874
class FixedArrayBase;
875
class ObjectVisitor;
876
class StringStream;
877
class Type;
878

    
879
struct ValueInfo : public Malloced {
880
  ValueInfo() : type(FIRST_TYPE), ptr(NULL), str(NULL), number(0) { }
881
  InstanceType type;
882
  Object* ptr;
883
  const char* str;
884
  double number;
885
};
886

    
887

    
888
// A template-ized version of the IsXXX functions.
889
template <class C> inline bool Is(Object* obj);
890

    
891
#ifdef VERIFY_HEAP
892
#define DECLARE_VERIFIER(Name) void Name##Verify();
893
#else
894
#define DECLARE_VERIFIER(Name)
895
#endif
896

    
897
#ifdef OBJECT_PRINT
898
#define DECLARE_PRINTER(Name) void Name##Print(FILE* out = stdout);
899
#else
900
#define DECLARE_PRINTER(Name)
901
#endif
902

    
903
class MaybeObject BASE_EMBEDDED {
904
 public:
905
  inline bool IsFailure();
906
  inline bool IsRetryAfterGC();
907
  inline bool IsOutOfMemory();
908
  inline bool IsException();
909
  INLINE(bool IsTheHole());
910
  INLINE(bool IsUninitialized());
911
  inline bool ToObject(Object** obj) {
912
    if (IsFailure()) return false;
913
    *obj = reinterpret_cast<Object*>(this);
914
    return true;
915
  }
916
  inline Failure* ToFailureUnchecked() {
917
    ASSERT(IsFailure());
918
    return reinterpret_cast<Failure*>(this);
919
  }
920
  inline Object* ToObjectUnchecked() {
921
    // TODO(jkummerow): Turn this back into an ASSERT when we can be certain
922
    // that it never fires in Release mode in the wild.
923
    CHECK(!IsFailure());
924
    return reinterpret_cast<Object*>(this);
925
  }
926
  inline Object* ToObjectChecked() {
927
    CHECK(!IsFailure());
928
    return reinterpret_cast<Object*>(this);
929
  }
930

    
931
  template<typename T>
932
  inline bool To(T** obj) {
933
    if (IsFailure()) return false;
934
    *obj = T::cast(reinterpret_cast<Object*>(this));
935
    return true;
936
  }
937

    
938
  template<typename T>
939
    inline bool ToHandle(Handle<T>* obj, Isolate* isolate) {
940
    if (IsFailure()) return false;
941
    *obj = handle(T::cast(reinterpret_cast<Object*>(this)), isolate);
942
    return true;
943
  }
944

    
945
#ifdef OBJECT_PRINT
946
  // Prints this object with details.
947
  void Print();
948
  void Print(FILE* out);
949
  void PrintLn();
950
  void PrintLn(FILE* out);
951
#endif
952
#ifdef VERIFY_HEAP
953
  // Verifies the object.
954
  void Verify();
955
#endif
956
};
957

    
958

    
959
#define OBJECT_TYPE_LIST(V)                    \
960
  V(Smi)                                       \
961
  V(HeapObject)                                \
962
  V(Number)                                    \
963

    
964
#define HEAP_OBJECT_TYPE_LIST(V)               \
965
  V(HeapNumber)                                \
966
  V(Name)                                      \
967
  V(UniqueName)                                \
968
  V(String)                                    \
969
  V(SeqString)                                 \
970
  V(ExternalString)                            \
971
  V(ConsString)                                \
972
  V(SlicedString)                              \
973
  V(ExternalTwoByteString)                     \
974
  V(ExternalAsciiString)                       \
975
  V(SeqTwoByteString)                          \
976
  V(SeqOneByteString)                          \
977
  V(InternalizedString)                        \
978
  V(Symbol)                                    \
979
                                               \
980
  V(ExternalArray)                             \
981
  V(ExternalByteArray)                         \
982
  V(ExternalUnsignedByteArray)                 \
983
  V(ExternalShortArray)                        \
984
  V(ExternalUnsignedShortArray)                \
985
  V(ExternalIntArray)                          \
986
  V(ExternalUnsignedIntArray)                  \
987
  V(ExternalFloatArray)                        \
988
  V(ExternalDoubleArray)                       \
989
  V(ExternalPixelArray)                        \
990
  V(ByteArray)                                 \
991
  V(FreeSpace)                                 \
992
  V(JSReceiver)                                \
993
  V(JSObject)                                  \
994
  V(JSContextExtensionObject)                  \
995
  V(JSGeneratorObject)                         \
996
  V(JSModule)                                  \
997
  V(Map)                                       \
998
  V(DescriptorArray)                           \
999
  V(TransitionArray)                           \
1000
  V(DeoptimizationInputData)                   \
1001
  V(DeoptimizationOutputData)                  \
1002
  V(DependentCode)                             \
1003
  V(TypeFeedbackCells)                         \
1004
  V(FixedArray)                                \
1005
  V(FixedDoubleArray)                          \
1006
  V(ConstantPoolArray)                         \
1007
  V(Context)                                   \
1008
  V(NativeContext)                             \
1009
  V(ScopeInfo)                                 \
1010
  V(JSFunction)                                \
1011
  V(Code)                                      \
1012
  V(Oddball)                                   \
1013
  V(SharedFunctionInfo)                        \
1014
  V(JSValue)                                   \
1015
  V(JSDate)                                    \
1016
  V(JSMessageObject)                           \
1017
  V(StringWrapper)                             \
1018
  V(Foreign)                                   \
1019
  V(Boolean)                                   \
1020
  V(JSArray)                                   \
1021
  V(JSArrayBuffer)                             \
1022
  V(JSArrayBufferView)                         \
1023
  V(JSTypedArray)                              \
1024
  V(JSDataView)                                \
1025
  V(JSProxy)                                   \
1026
  V(JSFunctionProxy)                           \
1027
  V(JSSet)                                     \
1028
  V(JSMap)                                     \
1029
  V(JSWeakCollection)                          \
1030
  V(JSWeakMap)                                 \
1031
  V(JSWeakSet)                                 \
1032
  V(JSRegExp)                                  \
1033
  V(HashTable)                                 \
1034
  V(Dictionary)                                \
1035
  V(StringTable)                               \
1036
  V(JSFunctionResultCache)                     \
1037
  V(NormalizedMapCache)                        \
1038
  V(CompilationCacheTable)                     \
1039
  V(CodeCacheHashTable)                        \
1040
  V(PolymorphicCodeCacheHashTable)             \
1041
  V(MapCache)                                  \
1042
  V(Primitive)                                 \
1043
  V(GlobalObject)                              \
1044
  V(JSGlobalObject)                            \
1045
  V(JSBuiltinsObject)                          \
1046
  V(JSGlobalProxy)                             \
1047
  V(UndetectableObject)                        \
1048
  V(AccessCheckNeeded)                         \
1049
  V(Cell)                                      \
1050
  V(PropertyCell)                              \
1051
  V(ObjectHashTable)                           \
1052
  V(WeakHashTable)
1053

    
1054

    
1055
#define ERROR_MESSAGES_LIST(V) \
1056
  V(kNoReason, "no reason")                                                   \
1057
                                                                              \
1058
  V(k32BitValueInRegisterIsNotZeroExtended,                                   \
1059
    "32 bit value in register is not zero-extended")                          \
1060
  V(kAlignmentMarkerExpected, "alignment marker expected")                    \
1061
  V(kAllocationIsNotDoubleAligned, "Allocation is not double aligned")        \
1062
  V(kAPICallReturnedInvalidObject, "API call returned invalid object")        \
1063
  V(kArgumentsObjectValueInATestContext,                                      \
1064
    "arguments object value in a test context")                               \
1065
  V(kArrayBoilerplateCreationFailed, "array boilerplate creation failed")     \
1066
  V(kArrayIndexConstantValueTooBig, "array index constant value too big")     \
1067
  V(kAssignmentToArguments, "assignment to arguments")                        \
1068
  V(kAssignmentToLetVariableBeforeInitialization,                             \
1069
    "assignment to let variable before initialization")                       \
1070
  V(kAssignmentToLOOKUPVariable, "assignment to LOOKUP variable")             \
1071
  V(kAssignmentToParameterFunctionUsesArgumentsObject,                        \
1072
    "assignment to parameter, function uses arguments object")                \
1073
  V(kAssignmentToParameterInArgumentsObject,                                  \
1074
    "assignment to parameter in arguments object")                            \
1075
  V(kAttemptToUseUndefinedCache, "Attempt to use undefined cache")            \
1076
  V(kBadValueContextForArgumentsObjectValue,                                  \
1077
    "bad value context for arguments object value")                           \
1078
  V(kBadValueContextForArgumentsValue,                                        \
1079
    "bad value context for arguments value")                                  \
1080
  V(kBailedOutDueToDependencyChange, "bailed out due to dependency change")   \
1081
  V(kBailoutWasNotPrepared, "bailout was not prepared")                       \
1082
  V(kBinaryStubGenerateFloatingPointCode,                                     \
1083
    "BinaryStub_GenerateFloatingPointCode")                                   \
1084
  V(kBothRegistersWereSmisInSelectNonSmi,                                     \
1085
    "Both registers were smis in SelectNonSmi")                               \
1086
  V(kCallToAJavaScriptRuntimeFunction,                                        \
1087
    "call to a JavaScript runtime function")                                  \
1088
  V(kCannotTranslatePositionInChangedArea,                                    \
1089
    "Cannot translate position in changed area")                              \
1090
  V(kCodeGenerationFailed, "code generation failed")                          \
1091
  V(kCodeObjectNotProperlyPatched, "code object not properly patched")        \
1092
  V(kCompoundAssignmentToLookupSlot, "compound assignment to lookup slot")    \
1093
  V(kContextAllocatedArguments, "context-allocated arguments")                \
1094
  V(kDebuggerIsActive, "debugger is active")                                  \
1095
  V(kDebuggerStatement, "DebuggerStatement")                                  \
1096
  V(kDeclarationInCatchContext, "Declaration in catch context")               \
1097
  V(kDeclarationInWithContext, "Declaration in with context")                 \
1098
  V(kDefaultNaNModeNotSet, "Default NaN mode not set")                        \
1099
  V(kDeleteWithGlobalVariable, "delete with global variable")                 \
1100
  V(kDeleteWithNonGlobalVariable, "delete with non-global variable")          \
1101
  V(kDestinationOfCopyNotAligned, "Destination of copy not aligned")          \
1102
  V(kDontDeleteCellsCannotContainTheHole,                                     \
1103
    "DontDelete cells can't contain the hole")                                \
1104
  V(kDoPushArgumentNotImplementedForDoubleType,                               \
1105
    "DoPushArgument not implemented for double type")                         \
1106
  V(kEmitLoadRegisterUnsupportedDoubleImmediate,                              \
1107
    "EmitLoadRegister: Unsupported double immediate")                         \
1108
  V(kEval, "eval")                                                            \
1109
  V(kExpected0AsASmiSentinel, "Expected 0 as a Smi sentinel")                 \
1110
  V(kExpectedAlignmentMarker, "expected alignment marker")                    \
1111
  V(kExpectedAllocationSiteInCell,                                            \
1112
    "Expected AllocationSite in property cell")                               \
1113
  V(kExpectedPropertyCellInRegisterA2,                                        \
1114
    "Expected property cell in register a2")                                  \
1115
  V(kExpectedPropertyCellInRegisterEbx,                                       \
1116
    "Expected property cell in register ebx")                                 \
1117
  V(kExpectedPropertyCellInRegisterRbx,                                       \
1118
    "Expected property cell in register rbx")                                 \
1119
  V(kExpectingAlignmentForCopyBytes,                                          \
1120
    "Expecting alignment for CopyBytes")                                      \
1121
  V(kExportDeclaration, "Export declaration")                                 \
1122
  V(kExternalStringExpectedButNotFound,                                       \
1123
    "external string expected, but not found")                                \
1124
  V(kFailedBailedOutLastTime, "failed/bailed out last time")                  \
1125
  V(kForInStatementIsNotFastCase, "ForInStatement is not fast case")          \
1126
  V(kForInStatementOptimizationIsDisabled,                                    \
1127
    "ForInStatement optimization is disabled")                                \
1128
  V(kForInStatementWithNonLocalEachVariable,                                  \
1129
    "ForInStatement with non-local each variable")                            \
1130
  V(kForOfStatement, "ForOfStatement")                                        \
1131
  V(kFrameIsExpectedToBeAligned, "frame is expected to be aligned")           \
1132
  V(kFunctionCallsEval, "function calls eval")                                \
1133
  V(kFunctionIsAGenerator, "function is a generator")                         \
1134
  V(kFunctionWithIllegalRedeclaration, "function with illegal redeclaration") \
1135
  V(kGeneratedCodeIsTooLarge, "Generated code is too large")                  \
1136
  V(kGeneratorFailedToResume, "Generator failed to resume")                   \
1137
  V(kGenerator, "generator")                                                  \
1138
  V(kGlobalFunctionsMustHaveInitialMap,                                       \
1139
    "Global functions must have initial map")                                 \
1140
  V(kHeapNumberMapRegisterClobbered, "HeapNumberMap register clobbered")      \
1141
  V(kImportDeclaration, "Import declaration")                                 \
1142
  V(kImproperObjectOnPrototypeChainForStore,                                  \
1143
    "improper object on prototype chain for store")                           \
1144
  V(kIndexIsNegative, "Index is negative")                                    \
1145
  V(kIndexIsTooLarge, "Index is too large")                                   \
1146
  V(kInlinedRuntimeFunctionClassOf, "inlined runtime function: ClassOf")      \
1147
  V(kInlinedRuntimeFunctionFastAsciiArrayJoin,                                \
1148
    "inlined runtime function: FastAsciiArrayJoin")                           \
1149
  V(kInlinedRuntimeFunctionGeneratorNext,                                     \
1150
    "inlined runtime function: GeneratorNext")                                \
1151
  V(kInlinedRuntimeFunctionGeneratorThrow,                                    \
1152
    "inlined runtime function: GeneratorThrow")                               \
1153
  V(kInlinedRuntimeFunctionGetFromCache,                                      \
1154
    "inlined runtime function: GetFromCache")                                 \
1155
  V(kInlinedRuntimeFunctionIsNonNegativeSmi,                                  \
1156
    "inlined runtime function: IsNonNegativeSmi")                             \
1157
  V(kInlinedRuntimeFunctionIsRegExpEquivalent,                                \
1158
    "inlined runtime function: IsRegExpEquivalent")                           \
1159
  V(kInlinedRuntimeFunctionIsStringWrapperSafeForDefaultValueOf,              \
1160
    "inlined runtime function: IsStringWrapperSafeForDefaultValueOf")         \
1161
  V(kInliningBailedOut, "inlining bailed out")                                \
1162
  V(kInputGPRIsExpectedToHaveUpper32Cleared,                                  \
1163
    "input GPR is expected to have upper32 cleared")                          \
1164
  V(kInstanceofStubUnexpectedCallSiteCacheCheck,                              \
1165
    "InstanceofStub unexpected call site cache (check)")                      \
1166
  V(kInstanceofStubUnexpectedCallSiteCacheCmp1,                               \
1167
    "InstanceofStub unexpected call site cache (cmp 1)")                      \
1168
  V(kInstanceofStubUnexpectedCallSiteCacheCmp2,                               \
1169
    "InstanceofStub unexpected call site cache (cmp 2)")                      \
1170
  V(kInstanceofStubUnexpectedCallSiteCacheMov,                                \
1171
    "InstanceofStub unexpected call site cache (mov)")                        \
1172
  V(kInteger32ToSmiFieldWritingToNonSmiLocation,                              \
1173
    "Integer32ToSmiField writing to non-smi location")                        \
1174
  V(kInvalidCaptureReferenced, "Invalid capture referenced")                  \
1175
  V(kInvalidElementsKindForInternalArrayOrInternalPackedArray,                \
1176
    "Invalid ElementsKind for InternalArray or InternalPackedArray")          \
1177
  V(kInvalidHandleScopeLevel, "Invalid HandleScope level")                    \
1178
  V(kInvalidLeftHandSideInAssignment, "invalid left-hand side in assignment") \
1179
  V(kInvalidLhsInCompoundAssignment, "invalid lhs in compound assignment")    \
1180
  V(kInvalidLhsInCountOperation, "invalid lhs in count operation")            \
1181
  V(kInvalidMinLength, "Invalid min_length")                                  \
1182
  V(kJSGlobalObjectNativeContextShouldBeANativeContext,                       \
1183
    "JSGlobalObject::native_context should be a native context")              \
1184
  V(kJSGlobalProxyContextShouldNotBeNull,                                     \
1185
    "JSGlobalProxy::context() should not be null")                            \
1186
  V(kJSObjectWithFastElementsMapHasSlowElements,                              \
1187
    "JSObject with fast elements map has slow elements")                      \
1188
  V(kLetBindingReInitialization, "Let binding re-initialization")             \
1189
  V(kLiveBytesCountOverflowChunkSize, "Live Bytes Count overflow chunk size") \
1190
  V(kLiveEditFrameDroppingIsNotSupportedOnArm,                                \
1191
    "LiveEdit frame dropping is not supported on arm")                        \
1192
  V(kLiveEditFrameDroppingIsNotSupportedOnMips,                               \
1193
    "LiveEdit frame dropping is not supported on mips")                       \
1194
  V(kLiveEdit, "LiveEdit")                                                    \
1195
  V(kLookupVariableInCountOperation,                                          \
1196
    "lookup variable in count operation")                                     \
1197
  V(kMapIsNoLongerInEax, "Map is no longer in eax")                           \
1198
  V(kModuleDeclaration, "Module declaration")                                 \
1199
  V(kModuleLiteral, "Module literal")                                         \
1200
  V(kModulePath, "Module path")                                               \
1201
  V(kModuleStatement, "Module statement")                                     \
1202
  V(kModuleVariable, "Module variable")                                       \
1203
  V(kModuleUrl, "Module url")                                                 \
1204
  V(kNativeFunctionLiteral, "Native function literal")                        \
1205
  V(kNoCasesLeft, "no cases left")                                            \
1206
  V(kNoEmptyArraysHereInEmitFastAsciiArrayJoin,                               \
1207
    "No empty arrays here in EmitFastAsciiArrayJoin")                         \
1208
  V(kNonInitializerAssignmentToConst,                                         \
1209
    "non-initializer assignment to const")                                    \
1210
  V(kNonSmiIndex, "Non-smi index")                                            \
1211
  V(kNonSmiKeyInArrayLiteral, "Non-smi key in array literal")                 \
1212
  V(kNonSmiValue, "Non-smi value")                                            \
1213
  V(kNotEnoughVirtualRegistersForValues,                                      \
1214
    "not enough virtual registers for values")                                \
1215
  V(kNotEnoughSpillSlotsForOsr,                                               \
1216
    "not enough spill slots for OSR")                                         \
1217
  V(kNotEnoughVirtualRegistersRegalloc,                                       \
1218
    "not enough virtual registers (regalloc)")                                \
1219
  V(kObjectFoundInSmiOnlyArray, "object found in smi-only array")             \
1220
  V(kObjectLiteralWithComplexProperty,                                        \
1221
    "Object literal with complex property")                                   \
1222
  V(kOddballInStringTableIsNotUndefinedOrTheHole,                             \
1223
    "oddball in string table is not undefined or the hole")                   \
1224
  V(kOperandIsASmiAndNotAName, "Operand is a smi and not a name")             \
1225
  V(kOperandIsASmiAndNotAString, "Operand is a smi and not a string")         \
1226
  V(kOperandIsASmi, "Operand is a smi")                                       \
1227
  V(kOperandIsNotAName, "Operand is not a name")                              \
1228
  V(kOperandIsNotANumber, "Operand is not a number")                          \
1229
  V(kOperandIsNotASmi, "Operand is not a smi")                                \
1230
  V(kOperandIsNotAString, "Operand is not a string")                          \
1231
  V(kOperandIsNotSmi, "Operand is not smi")                                   \
1232
  V(kOperandNotANumber, "Operand not a number")                               \
1233
  V(kOptimizedTooManyTimes, "optimized too many times")                       \
1234
  V(kOutOfVirtualRegistersWhileTryingToAllocateTempRegister,                  \
1235
    "Out of virtual registers while trying to allocate temp register")        \
1236
  V(kParseScopeError, "parse/scope error")                                    \
1237
  V(kPossibleDirectCallToEval, "possible direct call to eval")                \
1238
  V(kPropertyAllocationCountFailed, "Property allocation count failed")       \
1239
  V(kReceivedInvalidReturnAddress, "Received invalid return address")         \
1240
  V(kReferenceToAVariableWhichRequiresDynamicLookup,                          \
1241
    "reference to a variable which requires dynamic lookup")                  \
1242
  V(kReferenceToGlobalLexicalVariable,                                        \
1243
    "reference to global lexical variable")                                   \
1244
  V(kReferenceToUninitializedVariable, "reference to uninitialized variable") \
1245
  V(kRegisterDidNotMatchExpectedRoot, "Register did not match expected root") \
1246
  V(kRegisterWasClobbered, "register was clobbered")                          \
1247
  V(kScopedBlock, "ScopedBlock")                                              \
1248
  V(kSmiAdditionOverflow, "Smi addition overflow")                            \
1249
  V(kSmiSubtractionOverflow, "Smi subtraction overflow")                      \
1250
  V(kStackFrameTypesMustMatch, "stack frame types must match")                \
1251
  V(kSwitchStatementMixedOrNonLiteralSwitchLabels,                            \
1252
    "SwitchStatement: mixed or non-literal switch labels")                    \
1253
  V(kSwitchStatementTooManyClauses, "SwitchStatement: too many clauses")      \
1254
  V(kTheInstructionShouldBeALui, "The instruction should be a lui")           \
1255
  V(kTheInstructionShouldBeAnOri, "The instruction should be an ori")         \
1256
  V(kTheInstructionToPatchShouldBeALoadFromPc,                                \
1257
    "The instruction to patch should be a load from pc")                      \
1258
  V(kTheInstructionToPatchShouldBeALui,                                       \
1259
    "The instruction to patch should be a lui")                               \
1260
  V(kTheInstructionToPatchShouldBeAnOri,                                      \
1261
    "The instruction to patch should be an ori")                              \
1262
  V(kTooManyParametersLocals, "too many parameters/locals")                   \
1263
  V(kTooManyParameters, "too many parameters")                                \
1264
  V(kTooManySpillSlotsNeededForOSR, "Too many spill slots needed for OSR")    \
1265
  V(kToOperandIsDoubleRegisterUnimplemented,                                  \
1266
    "ToOperand IsDoubleRegister unimplemented")                               \
1267
  V(kToOperandUnsupportedDoubleImmediate,                                     \
1268
    "ToOperand Unsupported double immediate")                                 \
1269
  V(kTryCatchStatement, "TryCatchStatement")                                  \
1270
  V(kTryFinallyStatement, "TryFinallyStatement")                              \
1271
  V(kUnableToEncodeValueAsSmi, "Unable to encode value as smi")               \
1272
  V(kUnalignedAllocationInNewSpace, "Unaligned allocation in new space")      \
1273
  V(kUndefinedValueNotLoaded, "Undefined value not loaded")                   \
1274
  V(kUndoAllocationOfNonAllocatedMemory,                                      \
1275
    "Undo allocation of non allocated memory")                                \
1276
  V(kUnexpectedAllocationTop, "Unexpected allocation top")                    \
1277
  V(kUnexpectedElementsKindInArrayConstructor,                                \
1278
    "Unexpected ElementsKind in array constructor")                           \
1279
  V(kUnexpectedFallthroughFromCharCodeAtSlowCase,                             \
1280
    "Unexpected fallthrough from CharCodeAt slow case")                       \
1281
  V(kUnexpectedFallthroughFromCharFromCodeSlowCase,                           \
1282
    "Unexpected fallthrough from CharFromCode slow case")                     \
1283
  V(kUnexpectedFallThroughFromStringComparison,                               \
1284
    "Unexpected fall-through from string comparison")                         \
1285
  V(kUnexpectedFallThroughInBinaryStubGenerateFloatingPointCode,              \
1286
    "Unexpected fall-through in BinaryStub_GenerateFloatingPointCode")        \
1287
  V(kUnexpectedFallthroughToCharCodeAtSlowCase,                               \
1288
    "Unexpected fallthrough to CharCodeAt slow case")                         \
1289
  V(kUnexpectedFallthroughToCharFromCodeSlowCase,                             \
1290
    "Unexpected fallthrough to CharFromCode slow case")                       \
1291
  V(kUnexpectedFPUStackDepthAfterInstruction,                                 \
1292
    "Unexpected FPU stack depth after instruction")                           \
1293
  V(kUnexpectedInitialMapForArrayFunction1,                                   \
1294
    "Unexpected initial map for Array function (1)")                          \
1295
  V(kUnexpectedInitialMapForArrayFunction2,                                   \
1296
    "Unexpected initial map for Array function (2)")                          \
1297
  V(kUnexpectedInitialMapForArrayFunction,                                    \
1298
    "Unexpected initial map for Array function")                              \
1299
  V(kUnexpectedInitialMapForInternalArrayFunction,                            \
1300
    "Unexpected initial map for InternalArray function")                      \
1301
  V(kUnexpectedLevelAfterReturnFromApiCall,                                   \
1302
    "Unexpected level after return from api call")                            \
1303
  V(kUnexpectedNumberOfPreAllocatedPropertyFields,                            \
1304
    "Unexpected number of pre-allocated property fields")                     \
1305
  V(kUnexpectedStringFunction, "Unexpected String function")                  \
1306
  V(kUnexpectedStringType, "Unexpected string type")                          \
1307
  V(kUnexpectedStringWrapperInstanceSize,                                     \
1308
    "Unexpected string wrapper instance size")                                \
1309
  V(kUnexpectedTypeForRegExpDataFixedArrayExpected,                           \
1310
    "Unexpected type for RegExp data, FixedArray expected")                   \
1311
  V(kUnexpectedUnusedPropertiesOfStringWrapper,                               \
1312
    "Unexpected unused properties of string wrapper")                         \
1313
  V(kUninitializedKSmiConstantRegister, "Uninitialized kSmiConstantRegister") \
1314
  V(kUnknown, "unknown")                                                      \
1315
  V(kUnsupportedConstCompoundAssignment,                                      \
1316
    "unsupported const compound assignment")                                  \
1317
  V(kUnsupportedCountOperationWithConst,                                      \
1318
    "unsupported count operation with const")                                 \
1319
  V(kUnsupportedDoubleImmediate, "unsupported double immediate")              \
1320
  V(kUnsupportedLetCompoundAssignment, "unsupported let compound assignment") \
1321
  V(kUnsupportedLookupSlotInDeclaration,                                      \
1322
    "unsupported lookup slot in declaration")                                 \
1323
  V(kUnsupportedNonPrimitiveCompare, "Unsupported non-primitive compare")     \
1324
  V(kUnsupportedPhiUseOfArguments, "Unsupported phi use of arguments")        \
1325
  V(kUnsupportedPhiUseOfConstVariable,                                        \
1326
    "Unsupported phi use of const variable")                                  \
1327
  V(kUnsupportedTaggedImmediate, "unsupported tagged immediate")              \
1328
  V(kVariableResolvedToWithContext, "Variable resolved to with context")      \
1329
  V(kWeShouldNotHaveAnEmptyLexicalContext,                                    \
1330
    "we should not have an empty lexical context")                            \
1331
  V(kWithStatement, "WithStatement")                                          \
1332
  V(kWrongAddressOrValuePassedToRecordWrite,                                  \
1333
    "Wrong address or value passed to RecordWrite")                           \
1334
  V(kYield, "Yield")
1335

    
1336

    
1337
#define ERROR_MESSAGES_CONSTANTS(C, T) C,
1338
enum BailoutReason {
1339
  ERROR_MESSAGES_LIST(ERROR_MESSAGES_CONSTANTS)
1340
  kLastErrorMessage
1341
};
1342
#undef ERROR_MESSAGES_CONSTANTS
1343

    
1344

    
1345
const char* GetBailoutReason(BailoutReason reason);
1346

    
1347

    
1348
// Object is the abstract superclass for all classes in the
1349
// object hierarchy.
1350
// Object does not use any virtual functions to avoid the
1351
// allocation of the C++ vtable.
1352
// Since Smi and Failure are subclasses of Object no
1353
// data members can be present in Object.
1354
class Object : public MaybeObject {
1355
 public:
1356
  // Type testing.
1357
  bool IsObject() { return true; }
1358

    
1359
#define IS_TYPE_FUNCTION_DECL(type_)  inline bool Is##type_();
1360
  OBJECT_TYPE_LIST(IS_TYPE_FUNCTION_DECL)
1361
  HEAP_OBJECT_TYPE_LIST(IS_TYPE_FUNCTION_DECL)
1362
#undef IS_TYPE_FUNCTION_DECL
1363

    
1364
  inline bool IsFixedArrayBase();
1365
  inline bool IsExternal();
1366
  inline bool IsAccessorInfo();
1367

    
1368
  // Returns true if this object is an instance of the specified
1369
  // function template.
1370
  inline bool IsInstanceOf(FunctionTemplateInfo* type);
1371

    
1372
  inline bool IsStruct();
1373
#define DECLARE_STRUCT_PREDICATE(NAME, Name, name) inline bool Is##Name();
1374
  STRUCT_LIST(DECLARE_STRUCT_PREDICATE)
1375
#undef DECLARE_STRUCT_PREDICATE
1376

    
1377
  INLINE(bool IsSpecObject());
1378
  INLINE(bool IsSpecFunction());
1379

    
1380
  // Oddball testing.
1381
  INLINE(bool IsUndefined());
1382
  INLINE(bool IsNull());
1383
  INLINE(bool IsTheHole());  // Shadows MaybeObject's implementation.
1384
  INLINE(bool IsUninitialized());
1385
  INLINE(bool IsTrue());
1386
  INLINE(bool IsFalse());
1387
  inline bool IsArgumentsMarker();
1388
  inline bool NonFailureIsHeapObject();
1389

    
1390
  // Filler objects (fillers and free space objects).
1391
  inline bool IsFiller();
1392

    
1393
  // Extract the number.
1394
  inline double Number();
1395
  inline bool IsNaN();
1396
  bool ToInt32(int32_t* value);
1397
  bool ToUint32(uint32_t* value);
1398

    
1399
  // Indicates whether OptimalRepresentation can do its work, or whether it
1400
  // always has to return Representation::Tagged().
1401
  enum ValueType {
1402
    OPTIMAL_REPRESENTATION,
1403
    FORCE_TAGGED
1404
  };
1405

    
1406
  inline Representation OptimalRepresentation(
1407
      ValueType type = OPTIMAL_REPRESENTATION) {
1408
    if (!FLAG_track_fields) return Representation::Tagged();
1409
    if (type == FORCE_TAGGED) return Representation::Tagged();
1410
    if (IsSmi()) {
1411
      return Representation::Smi();
1412
    } else if (FLAG_track_double_fields && IsHeapNumber()) {
1413
      return Representation::Double();
1414
    } else if (FLAG_track_computed_fields && IsUninitialized()) {
1415
      return Representation::None();
1416
    } else if (FLAG_track_heap_object_fields) {
1417
      ASSERT(IsHeapObject());
1418
      return Representation::HeapObject();
1419
    } else {
1420
      return Representation::Tagged();
1421
    }
1422
  }
1423

    
1424
  inline bool FitsRepresentation(Representation representation) {
1425
    if (FLAG_track_fields && representation.IsNone()) {
1426
      return false;
1427
    } else if (FLAG_track_fields && representation.IsSmi()) {
1428
      return IsSmi();
1429
    } else if (FLAG_track_double_fields && representation.IsDouble()) {
1430
      return IsNumber();
1431
    } else if (FLAG_track_heap_object_fields && representation.IsHeapObject()) {
1432
      return IsHeapObject();
1433
    }
1434
    return true;
1435
  }
1436

    
1437
  inline MaybeObject* AllocateNewStorageFor(Heap* heap,
1438
                                            Representation representation);
1439

    
1440
  // Returns true if the object is of the correct type to be used as a
1441
  // implementation of a JSObject's elements.
1442
  inline bool HasValidElements();
1443

    
1444
  inline bool HasSpecificClassOf(String* name);
1445

    
1446
  MUST_USE_RESULT MaybeObject* ToObject(Isolate* isolate);  // ECMA-262 9.9.
1447
  bool BooleanValue();                                      // ECMA-262 9.2.
1448

    
1449
  // Convert to a JSObject if needed.
1450
  // native_context is used when creating wrapper object.
1451
  MUST_USE_RESULT MaybeObject* ToObject(Context* native_context);
1452

    
1453
  // Converts this to a Smi if possible.
1454
  // Failure is returned otherwise.
1455
  MUST_USE_RESULT inline MaybeObject* ToSmi();
1456

    
1457
  void Lookup(Name* name, LookupResult* result);
1458

    
1459
  // Property access.
1460
  MUST_USE_RESULT inline MaybeObject* GetProperty(Name* key);
1461
  MUST_USE_RESULT inline MaybeObject* GetProperty(
1462
      Name* key,
1463
      PropertyAttributes* attributes);
1464

    
1465
  // TODO(yangguo): this should eventually replace the non-handlified version.
1466
  static Handle<Object> GetPropertyWithReceiver(Handle<Object> object,
1467
                                                Handle<Object> receiver,
1468
                                                Handle<Name> name,
1469
                                                PropertyAttributes* attributes);
1470
  MUST_USE_RESULT MaybeObject* GetPropertyWithReceiver(
1471
      Object* receiver,
1472
      Name* key,
1473
      PropertyAttributes* attributes);
1474

    
1475
  static Handle<Object> GetProperty(Handle<Object> object,
1476
                                    Handle<Name> key);
1477
  static Handle<Object> GetProperty(Handle<Object> object,
1478
                                    Handle<Object> receiver,
1479
                                    LookupResult* result,
1480
                                    Handle<Name> key,
1481
                                    PropertyAttributes* attributes);
1482

    
1483
  MUST_USE_RESULT static MaybeObject* GetPropertyOrFail(
1484
      Handle<Object> object,
1485
      Handle<Object> receiver,
1486
      LookupResult* result,
1487
      Handle<Name> key,
1488
      PropertyAttributes* attributes);
1489

    
1490
  MUST_USE_RESULT MaybeObject* GetProperty(Object* receiver,
1491
                                           LookupResult* result,
1492
                                           Name* key,
1493
                                           PropertyAttributes* attributes);
1494

    
1495
  MUST_USE_RESULT MaybeObject* GetPropertyWithDefinedGetter(Object* receiver,
1496
                                                            JSReceiver* getter);
1497

    
1498
  static Handle<Object> GetElement(Isolate* isolate,
1499
                                   Handle<Object> object,
1500
                                   uint32_t index);
1501
  MUST_USE_RESULT inline MaybeObject* GetElement(Isolate* isolate,
1502
                                                 uint32_t index);
1503
  // For use when we know that no exception can be thrown.
1504
  inline Object* GetElementNoExceptionThrown(Isolate* isolate, uint32_t index);
1505
  MUST_USE_RESULT MaybeObject* GetElementWithReceiver(Isolate* isolate,
1506
                                                      Object* receiver,
1507
                                                      uint32_t index);
1508

    
1509
  // Return the object's prototype (might be Heap::null_value()).
1510
  Object* GetPrototype(Isolate* isolate);
1511

    
1512
  // Returns the permanent hash code associated with this object depending on
1513
  // the actual object type.  Might return a failure in case no hash was
1514
  // created yet or GC was caused by creation.
1515
  MUST_USE_RESULT MaybeObject* GetHash(CreationFlag flag);
1516

    
1517
  // Checks whether this object has the same value as the given one.  This
1518
  // function is implemented according to ES5, section 9.12 and can be used
1519
  // to implement the Harmony "egal" function.
1520
  bool SameValue(Object* other);
1521

    
1522
  // Tries to convert an object to an array index.  Returns true and sets
1523
  // the output parameter if it succeeds.
1524
  inline bool ToArrayIndex(uint32_t* index);
1525

    
1526
  // Returns true if this is a JSValue containing a string and the index is
1527
  // < the length of the string.  Used to implement [] on strings.
1528
  inline bool IsStringObjectWithCharacterAt(uint32_t index);
1529

    
1530
#ifdef VERIFY_HEAP
1531
  // Verify a pointer is a valid object pointer.
1532
  static void VerifyPointer(Object* p);
1533
#endif
1534

    
1535
  inline void VerifyApiCallResultType();
1536

    
1537
  // Prints this object without details.
1538
  void ShortPrint(FILE* out = stdout);
1539

    
1540
  // Prints this object without details to a message accumulator.
1541
  void ShortPrint(StringStream* accumulator);
1542

    
1543
  // Casting: This cast is only needed to satisfy macros in objects-inl.h.
1544
  static Object* cast(Object* value) { return value; }
1545

    
1546
  // Layout description.
1547
  static const int kHeaderSize = 0;  // Object does not take up any space.
1548

    
1549
 private:
1550
  DISALLOW_IMPLICIT_CONSTRUCTORS(Object);
1551
};
1552

    
1553

    
1554
// Smi represents integer Numbers that can be stored in 31 bits.
1555
// Smis are immediate which means they are NOT allocated in the heap.
1556
// The this pointer has the following format: [31 bit signed int] 0
1557
// For long smis it has the following format:
1558
//     [32 bit signed int] [31 bits zero padding] 0
1559
// Smi stands for small integer.
1560
class Smi: public Object {
1561
 public:
1562
  // Returns the integer value.
1563
  inline int value();
1564

    
1565
  // Convert a value to a Smi object.
1566
  static inline Smi* FromInt(int value);
1567

    
1568
  static inline Smi* FromIntptr(intptr_t value);
1569

    
1570
  // Returns whether value can be represented in a Smi.
1571
  static inline bool IsValid(intptr_t value);
1572

    
1573
  // Casting.
1574
  static inline Smi* cast(Object* object);
1575

    
1576
  // Dispatched behavior.
1577
  void SmiPrint(FILE* out = stdout);
1578
  void SmiPrint(StringStream* accumulator);
1579

    
1580
  DECLARE_VERIFIER(Smi)
1581

    
1582
  static const int kMinValue =
1583
      (static_cast<unsigned int>(-1)) << (kSmiValueSize - 1);
1584
  static const int kMaxValue = -(kMinValue + 1);
1585

    
1586
 private:
1587
  DISALLOW_IMPLICIT_CONSTRUCTORS(Smi);
1588
};
1589

    
1590

    
1591
// Failure is used for reporting out of memory situations and
1592
// propagating exceptions through the runtime system.  Failure objects
1593
// are transient and cannot occur as part of the object graph.
1594
//
1595
// Failures are a single word, encoded as follows:
1596
// +-------------------------+---+--+--+
1597
// |.........unused..........|sss|tt|11|
1598
// +-------------------------+---+--+--+
1599
//                          7 6 4 32 10
1600
//
1601
//
1602
// The low two bits, 0-1, are the failure tag, 11.  The next two bits,
1603
// 2-3, are a failure type tag 'tt' with possible values:
1604
//   00 RETRY_AFTER_GC
1605
//   01 EXCEPTION
1606
//   10 INTERNAL_ERROR
1607
//   11 OUT_OF_MEMORY_EXCEPTION
1608
//
1609
// The next three bits, 4-6, are an allocation space tag 'sss'.  The
1610
// allocation space tag is 000 for all failure types except
1611
// RETRY_AFTER_GC.  For RETRY_AFTER_GC, the possible values are the
1612
// allocation spaces (the encoding is found in globals.h).
1613

    
1614
// Failure type tag info.
1615
const int kFailureTypeTagSize = 2;
1616
const int kFailureTypeTagMask = (1 << kFailureTypeTagSize) - 1;
1617

    
1618
class Failure: public MaybeObject {
1619
 public:
1620
  // RuntimeStubs assumes EXCEPTION = 1 in the compiler-generated code.
1621
  enum Type {
1622
    RETRY_AFTER_GC = 0,
1623
    EXCEPTION = 1,       // Returning this marker tells the real exception
1624
                         // is in Isolate::pending_exception.
1625
    INTERNAL_ERROR = 2,
1626
    OUT_OF_MEMORY_EXCEPTION = 3
1627
  };
1628

    
1629
  inline Type type() const;
1630

    
1631
  // Returns the space that needs to be collected for RetryAfterGC failures.
1632
  inline AllocationSpace allocation_space() const;
1633

    
1634
  inline bool IsInternalError() const;
1635
  inline bool IsOutOfMemoryException() const;
1636

    
1637
  static inline Failure* RetryAfterGC(AllocationSpace space);
1638
  static inline Failure* RetryAfterGC();  // NEW_SPACE
1639
  static inline Failure* Exception();
1640
  static inline Failure* InternalError();
1641
  // TODO(jkummerow): The value is temporary instrumentation. Remove it
1642
  // when it has served its purpose.
1643
  static inline Failure* OutOfMemoryException(intptr_t value);
1644
  // Casting.
1645
  static inline Failure* cast(MaybeObject* object);
1646

    
1647
  // Dispatched behavior.
1648
  void FailurePrint(FILE* out = stdout);
1649
  void FailurePrint(StringStream* accumulator);
1650

    
1651
  DECLARE_VERIFIER(Failure)
1652

    
1653
 private:
1654
  inline intptr_t value() const;
1655
  static inline Failure* Construct(Type type, intptr_t value = 0);
1656

    
1657
  DISALLOW_IMPLICIT_CONSTRUCTORS(Failure);
1658
};
1659

    
1660

    
1661
// Heap objects typically have a map pointer in their first word.  However,
1662
// during GC other data (e.g. mark bits, forwarding addresses) is sometimes
1663
// encoded in the first word.  The class MapWord is an abstraction of the
1664
// value in a heap object's first word.
1665
class MapWord BASE_EMBEDDED {
1666
 public:
1667
  // Normal state: the map word contains a map pointer.
1668

    
1669
  // Create a map word from a map pointer.
1670
  static inline MapWord FromMap(Map* map);
1671

    
1672
  // View this map word as a map pointer.
1673
  inline Map* ToMap();
1674

    
1675

    
1676
  // Scavenge collection: the map word of live objects in the from space
1677
  // contains a forwarding address (a heap object pointer in the to space).
1678

    
1679
  // True if this map word is a forwarding address for a scavenge
1680
  // collection.  Only valid during a scavenge collection (specifically,
1681
  // when all map words are heap object pointers, i.e. not during a full GC).
1682
  inline bool IsForwardingAddress();
1683

    
1684
  // Create a map word from a forwarding address.
1685
  static inline MapWord FromForwardingAddress(HeapObject* object);
1686

    
1687
  // View this map word as a forwarding address.
1688
  inline HeapObject* ToForwardingAddress();
1689

    
1690
  static inline MapWord FromRawValue(uintptr_t value) {
1691
    return MapWord(value);
1692
  }
1693

    
1694
  inline uintptr_t ToRawValue() {
1695
    return value_;
1696
  }
1697

    
1698
 private:
1699
  // HeapObject calls the private constructor and directly reads the value.
1700
  friend class HeapObject;
1701

    
1702
  explicit MapWord(uintptr_t value) : value_(value) {}
1703

    
1704
  uintptr_t value_;
1705
};
1706

    
1707

    
1708
// HeapObject is the superclass for all classes describing heap allocated
1709
// objects.
1710
class HeapObject: public Object {
1711
 public:
1712
  // [map]: Contains a map which contains the object's reflective
1713
  // information.
1714
  inline Map* map();
1715
  inline void set_map(Map* value);
1716
  // The no-write-barrier version.  This is OK if the object is white and in
1717
  // new space, or if the value is an immortal immutable object, like the maps
1718
  // of primitive (non-JS) objects like strings, heap numbers etc.
1719
  inline void set_map_no_write_barrier(Map* value);
1720

    
1721
  // During garbage collection, the map word of a heap object does not
1722
  // necessarily contain a map pointer.
1723
  inline MapWord map_word();
1724
  inline void set_map_word(MapWord map_word);
1725

    
1726
  // The Heap the object was allocated in. Used also to access Isolate.
1727
  inline Heap* GetHeap();
1728

    
1729
  // Convenience method to get current isolate.
1730
  inline Isolate* GetIsolate();
1731

    
1732
  // Converts an address to a HeapObject pointer.
1733
  static inline HeapObject* FromAddress(Address address);
1734

    
1735
  // Returns the address of this HeapObject.
1736
  inline Address address();
1737

    
1738
  // Iterates over pointers contained in the object (including the Map)
1739
  void Iterate(ObjectVisitor* v);
1740

    
1741
  // Iterates over all pointers contained in the object except the
1742
  // first map pointer.  The object type is given in the first
1743
  // parameter. This function does not access the map pointer in the
1744
  // object, and so is safe to call while the map pointer is modified.
1745
  void IterateBody(InstanceType type, int object_size, ObjectVisitor* v);
1746

    
1747
  // Returns the heap object's size in bytes
1748
  inline int Size();
1749

    
1750
  // Given a heap object's map pointer, returns the heap size in bytes
1751
  // Useful when the map pointer field is used for other purposes.
1752
  // GC internal.
1753
  inline int SizeFromMap(Map* map);
1754

    
1755
  // Returns the field at offset in obj, as a read/write Object* reference.
1756
  // Does no checking, and is safe to use during GC, while maps are invalid.
1757
  // Does not invoke write barrier, so should only be assigned to
1758
  // during marking GC.
1759
  static inline Object** RawField(HeapObject* obj, int offset);
1760

    
1761
  // Adds the |code| object related to |name| to the code cache of this map. If
1762
  // this map is a dictionary map that is shared, the map copied and installed
1763
  // onto the object.
1764
  static void UpdateMapCodeCache(Handle<HeapObject> object,
1765
                                 Handle<Name> name,
1766
                                 Handle<Code> code);
1767

    
1768
  // Casting.
1769
  static inline HeapObject* cast(Object* obj);
1770

    
1771
  // Return the write barrier mode for this. Callers of this function
1772
  // must be able to present a reference to an DisallowHeapAllocation
1773
  // object as a sign that they are not going to use this function
1774
  // from code that allocates and thus invalidates the returned write
1775
  // barrier mode.
1776
  inline WriteBarrierMode GetWriteBarrierMode(
1777
      const DisallowHeapAllocation& promise);
1778

    
1779
  // Dispatched behavior.
1780
  void HeapObjectShortPrint(StringStream* accumulator);
1781
#ifdef OBJECT_PRINT
1782
  void PrintHeader(FILE* out, const char* id);
1783
#endif
1784
  DECLARE_PRINTER(HeapObject)
1785
  DECLARE_VERIFIER(HeapObject)
1786
#ifdef VERIFY_HEAP
1787
  inline void VerifyObjectField(int offset);
1788
  inline void VerifySmiField(int offset);
1789

    
1790
  // Verify a pointer is a valid HeapObject pointer that points to object
1791
  // areas in the heap.
1792
  static void VerifyHeapPointer(Object* p);
1793
#endif
1794

    
1795
  // Layout description.
1796
  // First field in a heap object is map.
1797
  static const int kMapOffset = Object::kHeaderSize;
1798
  static const int kHeaderSize = kMapOffset + kPointerSize;
1799

    
1800
  STATIC_CHECK(kMapOffset == Internals::kHeapObjectMapOffset);
1801

    
1802
 protected:
1803
  // helpers for calling an ObjectVisitor to iterate over pointers in the
1804
  // half-open range [start, end) specified as integer offsets
1805
  inline void IteratePointers(ObjectVisitor* v, int start, int end);
1806
  // as above, for the single element at "offset"
1807
  inline void IteratePointer(ObjectVisitor* v, int offset);
1808

    
1809
 private:
1810
  DISALLOW_IMPLICIT_CONSTRUCTORS(HeapObject);
1811
};
1812

    
1813

    
1814
// This class describes a body of an object of a fixed size
1815
// in which all pointer fields are located in the [start_offset, end_offset)
1816
// interval.
1817
template<int start_offset, int end_offset, int size>
1818
class FixedBodyDescriptor {
1819
 public:
1820
  static const int kStartOffset = start_offset;
1821
  static const int kEndOffset = end_offset;
1822
  static const int kSize = size;
1823

    
1824
  static inline void IterateBody(HeapObject* obj, ObjectVisitor* v);
1825

    
1826
  template<typename StaticVisitor>
1827
  static inline void IterateBody(HeapObject* obj) {
1828
    StaticVisitor::VisitPointers(HeapObject::RawField(obj, start_offset),
1829
                                 HeapObject::RawField(obj, end_offset));
1830
  }
1831
};
1832

    
1833

    
1834
// This class describes a body of an object of a variable size
1835
// in which all pointer fields are located in the [start_offset, object_size)
1836
// interval.
1837
template<int start_offset>
1838
class FlexibleBodyDescriptor {
1839
 public:
1840
  static const int kStartOffset = start_offset;
1841

    
1842
  static inline void IterateBody(HeapObject* obj,
1843
                                 int object_size,
1844
                                 ObjectVisitor* v);
1845

    
1846
  template<typename StaticVisitor>
1847
  static inline void IterateBody(HeapObject* obj, int object_size) {
1848
    StaticVisitor::VisitPointers(HeapObject::RawField(obj, start_offset),
1849
                                 HeapObject::RawField(obj, object_size));
1850
  }
1851
};
1852

    
1853

    
1854
// The HeapNumber class describes heap allocated numbers that cannot be
1855
// represented in a Smi (small integer)
1856
class HeapNumber: public HeapObject {
1857
 public:
1858
  // [value]: number value.
1859
  inline double value();
1860
  inline void set_value(double value);
1861

    
1862
  // Casting.
1863
  static inline HeapNumber* cast(Object* obj);
1864

    
1865
  // Dispatched behavior.
1866
  bool HeapNumberBooleanValue();
1867

    
1868
  void HeapNumberPrint(FILE* out = stdout);
1869
  void HeapNumberPrint(StringStream* accumulator);
1870
  DECLARE_VERIFIER(HeapNumber)
1871

    
1872
  inline int get_exponent();
1873
  inline int get_sign();
1874

    
1875
  // Layout description.
1876
  static const int kValueOffset = HeapObject::kHeaderSize;
1877
  // IEEE doubles are two 32 bit words.  The first is just mantissa, the second
1878
  // is a mixture of sign, exponent and mantissa.  Our current platforms are all
1879
  // little endian apart from non-EABI arm which is little endian with big
1880
  // endian floating point word ordering!
1881
  static const int kMantissaOffset = kValueOffset;
1882
  static const int kExponentOffset = kValueOffset + 4;
1883

    
1884
  static const int kSize = kValueOffset + kDoubleSize;
1885
  static const uint32_t kSignMask = 0x80000000u;
1886
  static const uint32_t kExponentMask = 0x7ff00000u;
1887
  static const uint32_t kMantissaMask = 0xfffffu;
1888
  static const int kMantissaBits = 52;
1889
  static const int kExponentBits = 11;
1890
  static const int kExponentBias = 1023;
1891
  static const int kExponentShift = 20;
1892
  static const int kInfinityOrNanExponent =
1893
      (kExponentMask >> kExponentShift) - kExponentBias;
1894
  static const int kMantissaBitsInTopWord = 20;
1895
  static const int kNonMantissaBitsInTopWord = 12;
1896

    
1897
 private:
1898
  DISALLOW_IMPLICIT_CONSTRUCTORS(HeapNumber);
1899
};
1900

    
1901

    
1902
enum EnsureElementsMode {
1903
  DONT_ALLOW_DOUBLE_ELEMENTS,
1904
  ALLOW_COPIED_DOUBLE_ELEMENTS,
1905
  ALLOW_CONVERTED_DOUBLE_ELEMENTS
1906
};
1907

    
1908

    
1909
// Indicates whether a property should be set or (re)defined.  Setting of a
1910
// property causes attributes to remain unchanged, writability to be checked
1911
// and callbacks to be called.  Defining of a property causes attributes to
1912
// be updated and callbacks to be overridden.
1913
enum SetPropertyMode {
1914
  SET_PROPERTY,
1915
  DEFINE_PROPERTY
1916
};
1917

    
1918

    
1919
// Indicator for one component of an AccessorPair.
1920
enum AccessorComponent {
1921
  ACCESSOR_GETTER,
1922
  ACCESSOR_SETTER
1923
};
1924

    
1925

    
1926
// JSReceiver includes types on which properties can be defined, i.e.,
1927
// JSObject and JSProxy.
1928
class JSReceiver: public HeapObject {
1929
 public:
1930
  enum DeleteMode {
1931
    NORMAL_DELETION,
1932
    STRICT_DELETION,
1933
    FORCE_DELETION
1934
  };
1935

    
1936
  // A non-keyed store is of the form a.x = foo or a["x"] = foo whereas
1937
  // a keyed store is of the form a[expression] = foo.
1938
  enum StoreFromKeyed {
1939
    MAY_BE_STORE_FROM_KEYED,
1940
    CERTAINLY_NOT_STORE_FROM_KEYED
1941
  };
1942

    
1943
  // Internal properties (e.g. the hidden properties dictionary) might
1944
  // be added even though the receiver is non-extensible.
1945
  enum ExtensibilityCheck {
1946
    PERFORM_EXTENSIBILITY_CHECK,
1947
    OMIT_EXTENSIBILITY_CHECK
1948
  };
1949

    
1950
  // Casting.
1951
  static inline JSReceiver* cast(Object* obj);
1952

    
1953
  // Implementation of [[Put]], ECMA-262 5th edition, section 8.12.5.
1954
  static Handle<Object> SetProperty(Handle<JSReceiver> object,
1955
                                    Handle<Name> key,
1956
                                    Handle<Object> value,
1957
                                    PropertyAttributes attributes,
1958
                                    StrictModeFlag strict_mode,
1959
                                    StoreFromKeyed store_mode =
1960
                                        MAY_BE_STORE_FROM_KEYED);
1961
  static Handle<Object> SetElement(Handle<JSReceiver> object,
1962
                                   uint32_t index,
1963
                                   Handle<Object> value,
1964
                                   PropertyAttributes attributes,
1965
                                   StrictModeFlag strict_mode);
1966

    
1967
  // Implementation of [[HasProperty]], ECMA-262 5th edition, section 8.12.6.
1968
  static inline bool HasProperty(Handle<JSReceiver> object, Handle<Name> name);
1969
  static inline bool HasLocalProperty(Handle<JSReceiver>, Handle<Name> name);
1970
  static inline bool HasElement(Handle<JSReceiver> object, uint32_t index);
1971
  static inline bool HasLocalElement(Handle<JSReceiver> object, uint32_t index);
1972

    
1973
  // Implementation of [[Delete]], ECMA-262 5th edition, section 8.12.7.
1974
  static Handle<Object> DeleteProperty(Handle<JSReceiver> object,
1975
                                       Handle<Name> name,
1976
                                       DeleteMode mode = NORMAL_DELETION);
1977
  static Handle<Object> DeleteElement(Handle<JSReceiver> object,
1978
                                      uint32_t index,
1979
                                      DeleteMode mode = NORMAL_DELETION);
1980

    
1981
  // Tests for the fast common case for property enumeration.
1982
  bool IsSimpleEnum();
1983

    
1984
  // Returns the class name ([[Class]] property in the specification).
1985
  String* class_name();
1986

    
1987
  // Returns the constructor name (the name (possibly, inferred name) of the
1988
  // function that was used to instantiate the object).
1989
  String* constructor_name();
1990

    
1991
  inline PropertyAttributes GetPropertyAttribute(Name* name);
1992
  PropertyAttributes GetPropertyAttributeWithReceiver(JSReceiver* receiver,
1993
                                                      Name* name);
1994
  PropertyAttributes GetLocalPropertyAttribute(Name* name);
1995

    
1996
  inline PropertyAttributes GetElementAttribute(uint32_t index);
1997
  inline PropertyAttributes GetLocalElementAttribute(uint32_t index);
1998

    
1999
  // Return the object's prototype (might be Heap::null_value()).
2000
  inline Object* GetPrototype();
2001

    
2002
  // Return the constructor function (may be Heap::null_value()).
2003
  inline Object* GetConstructor();
2004

    
2005
  // Retrieves a permanent object identity hash code. The undefined value might
2006
  // be returned in case no hash was created yet and OMIT_CREATION was used.
2007
  inline MUST_USE_RESULT MaybeObject* GetIdentityHash(CreationFlag flag);
2008

    
2009
  // Lookup a property.  If found, the result is valid and has
2010
  // detailed information.
2011
  void LocalLookup(Name* name, LookupResult* result,
2012
                   bool search_hidden_prototypes = false);
2013
  void Lookup(Name* name, LookupResult* result);
2014

    
2015
 protected:
2016
  Smi* GenerateIdentityHash();
2017

    
2018
  static Handle<Object> SetPropertyWithDefinedSetter(Handle<JSReceiver> object,
2019
                                                     Handle<JSReceiver> setter,
2020
                                                     Handle<Object> value);
2021

    
2022
 private:
2023
  PropertyAttributes GetPropertyAttributeForResult(JSReceiver* receiver,
2024
                                                   LookupResult* result,
2025
                                                   Name* name,
2026
                                                   bool continue_search);
2027

    
2028
  static Handle<Object> SetProperty(Handle<JSReceiver> receiver,
2029
                                    LookupResult* result,
2030
                                    Handle<Name> key,
2031
                                    Handle<Object> value,
2032
                                    PropertyAttributes attributes,
2033
                                    StrictModeFlag strict_mode,
2034
                                    StoreFromKeyed store_from_keyed);
2035

    
2036
  DISALLOW_IMPLICIT_CONSTRUCTORS(JSReceiver);
2037
};
2038

    
2039
// The JSObject describes real heap allocated JavaScript objects with
2040
// properties.
2041
// Note that the map of JSObject changes during execution to enable inline
2042
// caching.
2043
class JSObject: public JSReceiver {
2044
 public:
2045
  // [properties]: Backing storage for properties.
2046
  // properties is a FixedArray in the fast case and a Dictionary in the
2047
  // slow case.
2048
  DECL_ACCESSORS(properties, FixedArray)  // Get and set fast properties.
2049
  inline void initialize_properties();
2050
  inline bool HasFastProperties();
2051
  inline NameDictionary* property_dictionary();  // Gets slow properties.
2052

    
2053
  // [elements]: The elements (properties with names that are integers).
2054
  //
2055
  // Elements can be in two general modes: fast and slow. Each mode
2056
  // corrensponds to a set of object representations of elements that
2057
  // have something in common.
2058
  //
2059
  // In the fast mode elements is a FixedArray and so each element can
2060
  // be quickly accessed. This fact is used in the generated code. The
2061
  // elements array can have one of three maps in this mode:
2062
  // fixed_array_map, non_strict_arguments_elements_map or
2063
  // fixed_cow_array_map (for copy-on-write arrays). In the latter case
2064
  // the elements array may be shared by a few objects and so before
2065
  // writing to any element the array must be copied. Use
2066
  // EnsureWritableFastElements in this case.
2067
  //
2068
  // In the slow mode the elements is either a NumberDictionary, an
2069
  // ExternalArray, or a FixedArray parameter map for a (non-strict)
2070
  // arguments object.
2071
  DECL_ACCESSORS(elements, FixedArrayBase)
2072
  inline void initialize_elements();
2073
  MUST_USE_RESULT inline MaybeObject* ResetElements();
2074
  inline ElementsKind GetElementsKind();
2075
  inline ElementsAccessor* GetElementsAccessor();
2076
  // Returns true if an object has elements of FAST_SMI_ELEMENTS ElementsKind.
2077
  inline bool HasFastSmiElements();
2078
  // Returns true if an object has elements of FAST_ELEMENTS ElementsKind.
2079
  inline bool HasFastObjectElements();
2080
  // Returns true if an object has elements of FAST_ELEMENTS or
2081
  // FAST_SMI_ONLY_ELEMENTS.
2082
  inline bool HasFastSmiOrObjectElements();
2083
  // Returns true if an object has any of the fast elements kinds.
2084
  inline bool HasFastElements();
2085
  // Returns true if an object has elements of FAST_DOUBLE_ELEMENTS
2086
  // ElementsKind.
2087
  inline bool HasFastDoubleElements();
2088
  // Returns true if an object has elements of FAST_HOLEY_*_ELEMENTS
2089
  // ElementsKind.
2090
  inline bool HasFastHoleyElements();
2091
  inline bool HasNonStrictArgumentsElements();
2092
  inline bool HasDictionaryElements();
2093
  inline bool HasExternalPixelElements();
2094
  inline bool HasExternalArrayElements();
2095
  inline bool HasExternalByteElements();
2096
  inline bool HasExternalUnsignedByteElements();
2097
  inline bool HasExternalShortElements();
2098
  inline bool HasExternalUnsignedShortElements();
2099
  inline bool HasExternalIntElements();
2100
  inline bool HasExternalUnsignedIntElements();
2101
  inline bool HasExternalFloatElements();
2102
  inline bool HasExternalDoubleElements();
2103
  bool HasFastArgumentsElements();
2104
  bool HasDictionaryArgumentsElements();
2105
  inline SeededNumberDictionary* element_dictionary();  // Gets slow elements.
2106

    
2107
  inline bool ShouldTrackAllocationInfo();
2108

    
2109
  inline void set_map_and_elements(
2110
      Map* map,
2111
      FixedArrayBase* value,
2112
      WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
2113

    
2114
  // Requires: HasFastElements().
2115
  static Handle<FixedArray> EnsureWritableFastElements(
2116
      Handle<JSObject> object);
2117
  MUST_USE_RESULT inline MaybeObject* EnsureWritableFastElements();
2118

    
2119
  // Collects elements starting at index 0.
2120
  // Undefined values are placed after non-undefined values.
2121
  // Returns the number of non-undefined values.
2122
  static Handle<Object> PrepareElementsForSort(Handle<JSObject> object,
2123
                                               uint32_t limit);
2124
  // As PrepareElementsForSort, but only on objects where elements is
2125
  // a dictionary, and it will stay a dictionary.
2126
  static Handle<Object> PrepareSlowElementsForSort(Handle<JSObject> object,
2127
                                                   uint32_t limit);
2128
  MUST_USE_RESULT MaybeObject* PrepareSlowElementsForSort(uint32_t limit);
2129

    
2130
  static Handle<Object> GetPropertyWithCallback(Handle<JSObject> object,
2131
                                                Handle<Object> receiver,
2132
                                                Handle<Object> structure,
2133
                                                Handle<Name> name);
2134

    
2135
  static Handle<Object> SetPropertyWithCallback(
2136
      Handle<JSObject> object,
2137
      Handle<Object> structure,
2138
      Handle<Name> name,
2139
      Handle<Object> value,
2140
      Handle<JSObject> holder,
2141
      StrictModeFlag strict_mode);
2142

    
2143
  static Handle<Object> SetPropertyWithInterceptor(
2144
      Handle<JSObject> object,
2145
      Handle<Name> name,
2146
      Handle<Object> value,
2147
      PropertyAttributes attributes,
2148
      StrictModeFlag strict_mode);
2149

    
2150
  static Handle<Object> SetPropertyForResult(
2151
      Handle<JSObject> object,
2152
      LookupResult* result,
2153
      Handle<Name> name,
2154
      Handle<Object> value,
2155
      PropertyAttributes attributes,
2156
      StrictModeFlag strict_mode,
2157
      StoreFromKeyed store_mode = MAY_BE_STORE_FROM_KEYED);
2158

    
2159
  static Handle<Object> SetLocalPropertyIgnoreAttributes(
2160
      Handle<JSObject> object,
2161
      Handle<Name> key,
2162
      Handle<Object> value,
2163
      PropertyAttributes attributes,
2164
      ValueType value_type = OPTIMAL_REPRESENTATION,
2165
      StoreMode mode = ALLOW_AS_CONSTANT,
2166
      ExtensibilityCheck extensibility_check = PERFORM_EXTENSIBILITY_CHECK);
2167

    
2168
  static inline Handle<String> ExpectedTransitionKey(Handle<Map> map);
2169
  static inline Handle<Map> ExpectedTransitionTarget(Handle<Map> map);
2170

    
2171
  // Try to follow an existing transition to a field with attributes NONE. The
2172
  // return value indicates whether the transition was successful.
2173
  static inline Handle<Map> FindTransitionToField(Handle<Map> map,
2174
                                                  Handle<Name> key);
2175

    
2176
  // Extend the receiver with a single fast property appeared first in the
2177
  // passed map. This also extends the property backing store if necessary.
2178
  static void AllocateStorageForMap(Handle<JSObject> object, Handle<Map> map);
2179

    
2180
  // Migrates the given object to a map whose field representations are the
2181
  // lowest upper bound of all known representations for that field.
2182
  static void MigrateInstance(Handle<JSObject> instance);
2183

    
2184
  // Migrates the given object only if the target map is already available,
2185
  // or returns an empty handle if such a map is not yet available.
2186
  static Handle<Object> TryMigrateInstance(Handle<JSObject> instance);
2187

    
2188
  // Can cause GC.
2189
  MUST_USE_RESULT MaybeObject* SetLocalPropertyIgnoreAttributesTrampoline(
2190
      Name* key,
2191
      Object* value,
2192
      PropertyAttributes attributes,
2193
      ValueType value_type = OPTIMAL_REPRESENTATION,
2194
      StoreMode mode = ALLOW_AS_CONSTANT,
2195
      ExtensibilityCheck extensibility_check = PERFORM_EXTENSIBILITY_CHECK);
2196

    
2197
  // Retrieve a value in a normalized object given a lookup result.
2198
  // Handles the special representation of JS global objects.
2199
  Object* GetNormalizedProperty(LookupResult* result);
2200

    
2201
  // Sets the property value in a normalized object given a lookup result.
2202
  // Handles the special representation of JS global objects.
2203
  static void SetNormalizedProperty(Handle<JSObject> object,
2204
                                    LookupResult* result,
2205
                                    Handle<Object> value);
2206

    
2207
  // Sets the property value in a normalized object given (key, value, details).
2208
  // Handles the special representation of JS global objects.
2209
  static void SetNormalizedProperty(Handle<JSObject> object,
2210
                                    Handle<Name> key,
2211
                                    Handle<Object> value,
2212
                                    PropertyDetails details);
2213

    
2214
  static void OptimizeAsPrototype(Handle<JSObject> object);
2215

    
2216
  // Retrieve interceptors.
2217
  InterceptorInfo* GetNamedInterceptor();
2218
  InterceptorInfo* GetIndexedInterceptor();
2219

    
2220
  // Used from JSReceiver.
2221
  PropertyAttributes GetPropertyAttributePostInterceptor(JSObject* receiver,
2222
                                                         Name* name,
2223
                                                         bool continue_search);
2224
  PropertyAttributes GetPropertyAttributeWithInterceptor(JSObject* receiver,
2225
                                                         Name* name,
2226
                                                         bool continue_search);
2227
  PropertyAttributes GetPropertyAttributeWithFailedAccessCheck(
2228
      Object* receiver,
2229
      LookupResult* result,
2230
      Name* name,
2231
      bool continue_search);
2232
  PropertyAttributes GetElementAttributeWithReceiver(JSReceiver* receiver,
2233
                                                     uint32_t index,
2234
                                                     bool continue_search);
2235

    
2236
  // Retrieves an AccessorPair property from the given object. Might return
2237
  // undefined if the property doesn't exist or is of a different kind.
2238
  static Handle<Object> GetAccessor(Handle<JSObject> object,
2239
                                    Handle<Name> name,
2240
                                    AccessorComponent component);
2241

    
2242
  // Defines an AccessorPair property on the given object.
2243
  // TODO(mstarzinger): Rename to SetAccessor() and return empty handle on
2244
  // exception instead of letting callers check for scheduled exception.
2245
  static void DefineAccessor(Handle<JSObject> object,
2246
                             Handle<Name> name,
2247
                             Handle<Object> getter,
2248
                             Handle<Object> setter,
2249
                             PropertyAttributes attributes,
2250
                             v8::AccessControl access_control = v8::DEFAULT);
2251

    
2252
  // Defines an AccessorInfo property on the given object.
2253
  static Handle<Object> SetAccessor(Handle<JSObject> object,
2254
                                    Handle<AccessorInfo> info);
2255

    
2256
  static Handle<Object> GetPropertyWithInterceptor(
2257
      Handle<JSObject> object,
2258
      Handle<Object> receiver,
2259
      Handle<Name> name,
2260
      PropertyAttributes* attributes);
2261
  static Handle<Object> GetPropertyPostInterceptor(
2262
      Handle<JSObject> object,
2263
      Handle<Object> receiver,
2264
      Handle<Name> name,
2265
      PropertyAttributes* attributes);
2266
  MUST_USE_RESULT MaybeObject* GetLocalPropertyPostInterceptor(
2267
      Object* receiver,
2268
      Name* name,
2269
      PropertyAttributes* attributes);
2270

    
2271
  // Returns true if this is an instance of an api function and has
2272
  // been modified since it was created.  May give false positives.
2273
  bool IsDirty();
2274

    
2275
  // If the receiver is a JSGlobalProxy this method will return its prototype,
2276
  // otherwise the result is the receiver itself.
2277
  inline Object* BypassGlobalProxy();
2278

    
2279
  // Accessors for hidden properties object.
2280
  //
2281
  // Hidden properties are not local properties of the object itself.
2282
  // Instead they are stored in an auxiliary structure kept as a local
2283
  // property with a special name Heap::hidden_string(). But if the
2284
  // receiver is a JSGlobalProxy then the auxiliary object is a property
2285
  // of its prototype, and if it's a detached proxy, then you can't have
2286
  // hidden properties.
2287

    
2288
  // Sets a hidden property on this object. Returns this object if successful,
2289
  // undefined if called on a detached proxy.
2290
  static Handle<Object> SetHiddenProperty(Handle<JSObject> obj,
2291
                                          Handle<Name> key,
2292
                                          Handle<Object> value);
2293
  // Returns a failure if a GC is required.
2294
  MUST_USE_RESULT MaybeObject* SetHiddenProperty(Name* key, Object* value);
2295
  // Gets the value of a hidden property with the given key. Returns the hole
2296
  // if the property doesn't exist (or if called on a detached proxy),
2297
  // otherwise returns the value set for the key.
2298
  Object* GetHiddenProperty(Name* key);
2299
  // Deletes a hidden property. Deleting a non-existing property is
2300
  // considered successful.
2301
  static void DeleteHiddenProperty(Handle<JSObject> object,
2302
                                   Handle<Name> key);
2303
  // Returns true if the object has a property with the hidden string as name.
2304
  bool HasHiddenProperties();
2305

    
2306
  static int GetIdentityHash(Handle<JSObject> object);
2307
  static void SetIdentityHash(Handle<JSObject> object, Smi* hash);
2308

    
2309
  inline void ValidateElements();
2310

    
2311
  // Makes sure that this object can contain HeapObject as elements.
2312
  static inline void EnsureCanContainHeapObjectElements(Handle<JSObject> obj);
2313

    
2314
  // Makes sure that this object can contain the specified elements.
2315
  MUST_USE_RESULT inline MaybeObject* EnsureCanContainElements(
2316
      Object** elements,
2317
      uint32_t count,
2318
      EnsureElementsMode mode);
2319
  MUST_USE_RESULT inline MaybeObject* EnsureCanContainElements(
2320
      FixedArrayBase* elements,
2321
      uint32_t length,
2322
      EnsureElementsMode mode);
2323
  MUST_USE_RESULT MaybeObject* EnsureCanContainElements(
2324
      Arguments* arguments,
2325
      uint32_t first_arg,
2326
      uint32_t arg_count,
2327
      EnsureElementsMode mode);
2328

    
2329
  // Do we want to keep the elements in fast case when increasing the
2330
  // capacity?
2331
  bool ShouldConvertToSlowElements(int new_capacity);
2332
  // Returns true if the backing storage for the slow-case elements of
2333
  // this object takes up nearly as much space as a fast-case backing
2334
  // storage would.  In that case the JSObject should have fast
2335
  // elements.
2336
  bool ShouldConvertToFastElements();
2337
  // Returns true if the elements of JSObject contains only values that can be
2338
  // represented in a FixedDoubleArray and has at least one value that can only
2339
  // be represented as a double and not a Smi.
2340
  bool ShouldConvertToFastDoubleElements(bool* has_smi_only_elements);
2341

    
2342
  // Computes the new capacity when expanding the elements of a JSObject.
2343
  static int NewElementsCapacity(int old_capacity) {
2344
    // (old_capacity + 50%) + 16
2345
    return old_capacity + (old_capacity >> 1) + 16;
2346
  }
2347

    
2348
  // These methods do not perform access checks!
2349
  AccessorPair* GetLocalPropertyAccessorPair(Name* name);
2350
  AccessorPair* GetLocalElementAccessorPair(uint32_t index);
2351

    
2352
  MUST_USE_RESULT MaybeObject* SetFastElement(uint32_t index,
2353
                                              Object* value,
2354
                                              StrictModeFlag strict_mode,
2355
                                              bool check_prototype);
2356

    
2357
  MUST_USE_RESULT MaybeObject* SetDictionaryElement(
2358
      uint32_t index,
2359
      Object* value,
2360
      PropertyAttributes attributes,
2361
      StrictModeFlag strict_mode,
2362
      bool check_prototype,
2363
      SetPropertyMode set_mode = SET_PROPERTY);
2364

    
2365
  MUST_USE_RESULT MaybeObject* SetFastDoubleElement(
2366
      uint32_t index,
2367
      Object* value,
2368
      StrictModeFlag strict_mode,
2369
      bool check_prototype = true);
2370

    
2371
  static Handle<Object> SetOwnElement(Handle<JSObject> object,
2372
                                      uint32_t index,
2373
                                      Handle<Object> value,
2374
                                      StrictModeFlag strict_mode);
2375

    
2376
  // Empty handle is returned if the element cannot be set to the given value.
2377
  static Handle<Object> SetElement(
2378
      Handle<JSObject> object,
2379
      uint32_t index,
2380
      Handle<Object> value,
2381
      PropertyAttributes attr,
2382
      StrictModeFlag strict_mode,
2383
      SetPropertyMode set_mode = SET_PROPERTY);
2384

    
2385
  // A Failure object is returned if GC is needed.
2386
  MUST_USE_RESULT MaybeObject* SetElement(
2387
      uint32_t index,
2388
      Object* value,
2389
      PropertyAttributes attributes,
2390
      StrictModeFlag strict_mode,
2391
      bool check_prototype = true,
2392
      SetPropertyMode set_mode = SET_PROPERTY);
2393

    
2394
  // Returns the index'th element.
2395
  // The undefined object if index is out of bounds.
2396
  MUST_USE_RESULT MaybeObject* GetElementWithInterceptor(Object* receiver,
2397
                                                         uint32_t index);
2398

    
2399
  enum SetFastElementsCapacitySmiMode {
2400
    kAllowSmiElements,
2401
    kForceSmiElements,
2402
    kDontAllowSmiElements
2403
  };
2404

    
2405
  // Replace the elements' backing store with fast elements of the given
2406
  // capacity.  Update the length for JSArrays.  Returns the new backing
2407
  // store.
2408
  MUST_USE_RESULT MaybeObject* SetFastElementsCapacityAndLength(
2409
      int capacity,
2410
      int length,
2411
      SetFastElementsCapacitySmiMode smi_mode);
2412
  MUST_USE_RESULT MaybeObject* SetFastDoubleElementsCapacityAndLength(
2413
      int capacity,
2414
      int length);
2415

    
2416
  // Lookup interceptors are used for handling properties controlled by host
2417
  // objects.
2418
  inline bool HasNamedInterceptor();
2419
  inline bool HasIndexedInterceptor();
2420

    
2421
  // Support functions for v8 api (needed for correct interceptor behavior).
2422
  static bool HasRealNamedProperty(Handle<JSObject> object,
2423
                                   Handle<Name> key);
2424
  static bool HasRealElementProperty(Handle<JSObject> object, uint32_t index);
2425
  static bool HasRealNamedCallbackProperty(Handle<JSObject> object,
2426
                                           Handle<Name> key);
2427

    
2428
  // Get the header size for a JSObject.  Used to compute the index of
2429
  // internal fields as well as the number of internal fields.
2430
  inline int GetHeaderSize();
2431

    
2432
  inline int GetInternalFieldCount();
2433
  inline int GetInternalFieldOffset(int index);
2434
  inline Object* GetInternalField(int index);
2435
  inline void SetInternalField(int index, Object* value);
2436
  inline void SetInternalField(int index, Smi* value);
2437

    
2438
  // The following lookup functions skip interceptors.
2439
  void LocalLookupRealNamedProperty(Name* name, LookupResult* result);
2440
  void LookupRealNamedProperty(Name* name, LookupResult* result);
2441
  void LookupRealNamedPropertyInPrototypes(Name* name, LookupResult* result);
2442
  void LookupCallbackProperty(Name* name, LookupResult* result);
2443

    
2444
  // Returns the number of properties on this object filtering out properties
2445
  // with the specified attributes (ignoring interceptors).
2446
  int NumberOfLocalProperties(PropertyAttributes filter = NONE);
2447
  // Fill in details for properties into storage starting at the specified
2448
  // index.
2449
  void GetLocalPropertyNames(
2450
      FixedArray* storage, int index, PropertyAttributes filter = NONE);
2451

    
2452
  // Returns the number of properties on this object filtering out properties
2453
  // with the specified attributes (ignoring interceptors).
2454
  int NumberOfLocalElements(PropertyAttributes filter);
2455
  // Returns the number of enumerable elements (ignoring interceptors).
2456
  int NumberOfEnumElements();
2457
  // Returns the number of elements on this object filtering out elements
2458
  // with the specified attributes (ignoring interceptors).
2459
  int GetLocalElementKeys(FixedArray* storage, PropertyAttributes filter);
2460
  // Count and fill in the enumerable elements into storage.
2461
  // (storage->length() == NumberOfEnumElements()).
2462
  // If storage is NULL, will count the elements without adding
2463
  // them to any storage.
2464
  // Returns the number of enumerable elements.
2465
  int GetEnumElementKeys(FixedArray* storage);
2466

    
2467
  // Returns a new map with all transitions dropped from the object's current
2468
  // map and the ElementsKind set.
2469
  static Handle<Map> GetElementsTransitionMap(Handle<JSObject> object,
2470
                                              ElementsKind to_kind);
2471
  inline MUST_USE_RESULT MaybeObject* GetElementsTransitionMap(
2472
      Isolate* isolate,
2473
      ElementsKind elements_kind);
2474
  MUST_USE_RESULT MaybeObject* GetElementsTransitionMapSlow(
2475
      ElementsKind elements_kind);
2476

    
2477
  static void TransitionElementsKind(Handle<JSObject> object,
2478
                                     ElementsKind to_kind);
2479

    
2480
  MUST_USE_RESULT MaybeObject* TransitionElementsKind(ElementsKind to_kind);
2481
  MUST_USE_RESULT MaybeObject* UpdateAllocationSite(ElementsKind to_kind);
2482

    
2483
  // TODO(mstarzinger): Both public because of ConvertAnsSetLocalProperty().
2484
  static void MigrateToMap(Handle<JSObject> object, Handle<Map> new_map);
2485
  static void GeneralizeFieldRepresentation(Handle<JSObject> object,
2486
                                            int modify_index,
2487
                                            Representation new_representation,
2488
                                            StoreMode store_mode);
2489

    
2490
  // Convert the object to use the canonical dictionary
2491
  // representation. If the object is expected to have additional properties
2492
  // added this number can be indicated to have the backing store allocated to
2493
  // an initial capacity for holding these properties.
2494
  static void NormalizeProperties(Handle<JSObject> object,
2495
                                  PropertyNormalizationMode mode,
2496
                                  int expected_additional_properties);
2497

    
2498
  // Convert and update the elements backing store to be a
2499
  // SeededNumberDictionary dictionary.  Returns the backing after conversion.
2500
  static Handle<SeededNumberDictionary> NormalizeElements(
2501
      Handle<JSObject> object);
2502

    
2503
  MUST_USE_RESULT MaybeObject* NormalizeElements();
2504

    
2505
  // Transform slow named properties to fast variants.
2506
  static void TransformToFastProperties(Handle<JSObject> object,
2507
                                        int unused_property_fields);
2508

    
2509
  // Access fast-case object properties at index.
2510
  MUST_USE_RESULT inline MaybeObject* FastPropertyAt(
2511
      Representation representation,
2512
      int index);
2513
  inline Object* RawFastPropertyAt(int index);
2514
  inline void FastPropertyAtPut(int index, Object* value);
2515

    
2516
  // Access to in object properties.
2517
  inline int GetInObjectPropertyOffset(int index);
2518
  inline Object* InObjectPropertyAt(int index);
2519
  inline Object* InObjectPropertyAtPut(int index,
2520
                                       Object* value,
2521
                                       WriteBarrierMode mode
2522
                                       = UPDATE_WRITE_BARRIER);
2523

    
2524
  // Set the object's prototype (only JSReceiver and null are allowed values).
2525
  static Handle<Object> SetPrototype(Handle<JSObject> object,
2526
                                     Handle<Object> value,
2527
                                     bool skip_hidden_prototypes = false);
2528

    
2529
  // Initializes the body after properties slot, properties slot is
2530
  // initialized by set_properties.  Fill the pre-allocated fields with
2531
  // pre_allocated_value and the rest with filler_value.
2532
  // Note: this call does not update write barrier, the caller is responsible
2533
  // to ensure that |filler_value| can be collected without WB here.
2534
  inline void InitializeBody(Map* map,
2535
                             Object* pre_allocated_value,
2536
                             Object* filler_value);
2537

    
2538
  // Check whether this object references another object
2539
  bool ReferencesObject(Object* obj);
2540

    
2541
  // Disalow further properties to be added to the object.
2542
  static Handle<Object> PreventExtensions(Handle<JSObject> object);
2543

    
2544
  // ES5 Object.freeze
2545
  static Handle<Object> Freeze(Handle<JSObject> object);
2546

    
2547
  // Called the first time an object is observed with ES7 Object.observe.
2548
  static void SetObserved(Handle<JSObject> object);
2549

    
2550
  // Copy object.
2551
  static Handle<JSObject> Copy(Handle<JSObject> object,
2552
                               Handle<AllocationSite> site);
2553
  static Handle<JSObject> Copy(Handle<JSObject> object);
2554
  static Handle<JSObject> DeepCopy(Handle<JSObject> object,
2555
                                   AllocationSiteContext* site_context);
2556
  static Handle<JSObject> DeepWalk(Handle<JSObject> object,
2557
                                   AllocationSiteContext* site_context);
2558

    
2559
  // Casting.
2560
  static inline JSObject* cast(Object* obj);
2561

    
2562
  // Dispatched behavior.
2563
  void JSObjectShortPrint(StringStream* accumulator);
2564
  DECLARE_PRINTER(JSObject)
2565
  DECLARE_VERIFIER(JSObject)
2566
#ifdef OBJECT_PRINT
2567
  void PrintProperties(FILE* out = stdout);
2568
  void PrintElements(FILE* out = stdout);
2569
  void PrintTransitions(FILE* out = stdout);
2570
#endif
2571

    
2572
  void PrintElementsTransition(
2573
      FILE* file, ElementsKind from_kind, FixedArrayBase* from_elements,
2574
      ElementsKind to_kind, FixedArrayBase* to_elements);
2575

    
2576
  void PrintInstanceMigration(FILE* file, Map* original_map, Map* new_map);
2577

    
2578
#ifdef DEBUG
2579
  // Structure for collecting spill information about JSObjects.
2580
  class SpillInformation {
2581
   public:
2582
    void Clear();
2583
    void Print();
2584
    int number_of_objects_;
2585
    int number_of_objects_with_fast_properties_;
2586
    int number_of_objects_with_fast_elements_;
2587
    int number_of_fast_used_fields_;
2588
    int number_of_fast_unused_fields_;
2589
    int number_of_slow_used_properties_;
2590
    int number_of_slow_unused_properties_;
2591
    int number_of_fast_used_elements_;
2592
    int number_of_fast_unused_elements_;
2593
    int number_of_slow_used_elements_;
2594
    int number_of_slow_unused_elements_;
2595
  };
2596

    
2597
  void IncrementSpillStatistics(SpillInformation* info);
2598
#endif
2599

    
2600
#ifdef VERIFY_HEAP
2601
  // If a GC was caused while constructing this object, the elements pointer
2602
  // may point to a one pointer filler map. The object won't be rooted, but
2603
  // our heap verification code could stumble across it.
2604
  bool ElementsAreSafeToExamine();
2605
#endif
2606

    
2607
  Object* SlowReverseLookup(Object* value);
2608

    
2609
  // Maximal number of fast properties for the JSObject. Used to
2610
  // restrict the number of map transitions to avoid an explosion in
2611
  // the number of maps for objects used as dictionaries.
2612
  inline bool TooManyFastProperties(
2613
      StoreFromKeyed store_mode = MAY_BE_STORE_FROM_KEYED);
2614

    
2615
  // Maximal number of elements (numbered 0 .. kMaxElementCount - 1).
2616
  // Also maximal value of JSArray's length property.
2617
  static const uint32_t kMaxElementCount = 0xffffffffu;
2618

    
2619
  // Constants for heuristics controlling conversion of fast elements
2620
  // to slow elements.
2621

    
2622
  // Maximal gap that can be introduced by adding an element beyond
2623
  // the current elements length.
2624
  static const uint32_t kMaxGap = 1024;
2625

    
2626
  // Maximal length of fast elements array that won't be checked for
2627
  // being dense enough on expansion.
2628
  static const int kMaxUncheckedFastElementsLength = 5000;
2629

    
2630
  // Same as above but for old arrays. This limit is more strict. We
2631
  // don't want to be wasteful with long lived objects.
2632
  static const int kMaxUncheckedOldFastElementsLength = 500;
2633

    
2634
  // Note that Heap::MaxRegularSpaceAllocationSize() puts a limit on
2635
  // permissible values (see the ASSERT in heap.cc).
2636
  static const int kInitialMaxFastElementArray = 100000;
2637

    
2638
  static const int kFastPropertiesSoftLimit = 12;
2639
  static const int kMaxFastProperties = 64;
2640
  static const int kMaxInstanceSize = 255 * kPointerSize;
2641
  // When extending the backing storage for property values, we increase
2642
  // its size by more than the 1 entry necessary, so sequentially adding fields
2643
  // to the same object requires fewer allocations and copies.
2644
  static const int kFieldsAdded = 3;
2645

    
2646
  // Layout description.
2647
  static const int kPropertiesOffset = HeapObject::kHeaderSize;
2648
  static const int kElementsOffset = kPropertiesOffset + kPointerSize;
2649
  static const int kHeaderSize = kElementsOffset + kPointerSize;
2650

    
2651
  STATIC_CHECK(kHeaderSize == Internals::kJSObjectHeaderSize);
2652

    
2653
  class BodyDescriptor : public FlexibleBodyDescriptor<kPropertiesOffset> {
2654
   public:
2655
    static inline int SizeOf(Map* map, HeapObject* object);
2656
  };
2657

    
2658
  // Enqueue change record for Object.observe. May cause GC.
2659
  static void EnqueueChangeRecord(Handle<JSObject> object,
2660
                                  const char* type,
2661
                                  Handle<Name> name,
2662
                                  Handle<Object> old_value);
2663

    
2664
  // Deliver change records to observers. May cause GC.
2665
  static void DeliverChangeRecords(Isolate* isolate);
2666

    
2667
 private:
2668
  friend class DictionaryElementsAccessor;
2669
  friend class JSReceiver;
2670
  friend class Object;
2671

    
2672
  // Used from Object::GetProperty().
2673
  static Handle<Object> GetPropertyWithFailedAccessCheck(
2674
      Handle<JSObject> object,
2675
      Handle<Object> receiver,
2676
      LookupResult* result,
2677
      Handle<Name> name,
2678
      PropertyAttributes* attributes);
2679

    
2680
  MUST_USE_RESULT MaybeObject* GetElementWithCallback(Object* receiver,
2681
                                                      Object* structure,
2682
                                                      uint32_t index,
2683
                                                      Object* holder);
2684
  MUST_USE_RESULT PropertyAttributes GetElementAttributeWithInterceptor(
2685
      JSReceiver* receiver,
2686
      uint32_t index,
2687
      bool continue_search);
2688
  MUST_USE_RESULT PropertyAttributes GetElementAttributeWithoutInterceptor(
2689
      JSReceiver* receiver,
2690
      uint32_t index,
2691
      bool continue_search);
2692
  static Handle<Object> SetElementWithCallback(
2693
      Handle<JSObject> object,
2694
      Handle<Object> structure,
2695
      uint32_t index,
2696
      Handle<Object> value,
2697
      Handle<JSObject> holder,
2698
      StrictModeFlag strict_mode);
2699
  MUST_USE_RESULT MaybeObject* SetElementWithInterceptor(
2700
      uint32_t index,
2701
      Object* value,
2702
      PropertyAttributes attributes,
2703
      StrictModeFlag strict_mode,
2704
      bool check_prototype,
2705
      SetPropertyMode set_mode);
2706
  MUST_USE_RESULT MaybeObject* SetElementWithoutInterceptor(
2707
      uint32_t index,
2708
      Object* value,
2709
      PropertyAttributes attributes,
2710
      StrictModeFlag strict_mode,
2711
      bool check_prototype,
2712
      SetPropertyMode set_mode);
2713
  MUST_USE_RESULT MaybeObject* SetElementWithCallbackSetterInPrototypes(
2714
      uint32_t index,
2715
      Object* value,
2716
      bool* found,
2717
      StrictModeFlag strict_mode);
2718

    
2719
  // Searches the prototype chain for property 'name'. If it is found and
2720
  // has a setter, invoke it and set '*done' to true. If it is found and is
2721
  // read-only, reject and set '*done' to true. Otherwise, set '*done' to
2722
  // false. Can throw and return an empty handle with '*done==true'.
2723
  static Handle<Object> SetPropertyViaPrototypes(
2724
      Handle<JSObject> object,
2725
      Handle<Name> name,
2726
      Handle<Object> value,
2727
      PropertyAttributes attributes,
2728
      StrictModeFlag strict_mode,
2729
      bool* done);
2730
  static Handle<Object> SetPropertyPostInterceptor(
2731
      Handle<JSObject> object,
2732
      Handle<Name> name,
2733
      Handle<Object> value,
2734
      PropertyAttributes attributes,
2735
      StrictModeFlag strict_mode);
2736
  static Handle<Object> SetPropertyUsingTransition(
2737
      Handle<JSObject> object,
2738
      LookupResult* lookup,
2739
      Handle<Name> name,
2740
      Handle<Object> value,
2741
      PropertyAttributes attributes);
2742
  static Handle<Object> SetPropertyWithFailedAccessCheck(
2743
      Handle<JSObject> object,
2744
      LookupResult* result,
2745
      Handle<Name> name,
2746
      Handle<Object> value,
2747
      bool check_prototype,
2748
      StrictModeFlag strict_mode);
2749

    
2750
  // Add a property to an object.
2751
  static Handle<Object> AddProperty(
2752
      Handle<JSObject> object,
2753
      Handle<Name> name,
2754
      Handle<Object> value,
2755
      PropertyAttributes attributes,
2756
      StrictModeFlag strict_mode,
2757
      StoreFromKeyed store_mode = MAY_BE_STORE_FROM_KEYED,
2758
      ExtensibilityCheck extensibility_check = PERFORM_EXTENSIBILITY_CHECK,
2759
      ValueType value_type = OPTIMAL_REPRESENTATION,
2760
      StoreMode mode = ALLOW_AS_CONSTANT,
2761
      TransitionFlag flag = INSERT_TRANSITION);
2762

    
2763
  // Add a constant function property to a fast-case object.
2764
  // This leaves a CONSTANT_TRANSITION in the old map, and
2765
  // if it is called on a second object with this map, a
2766
  // normal property is added instead, with a map transition.
2767
  // This avoids the creation of many maps with the same constant
2768
  // function, all orphaned.
2769
  static void AddConstantProperty(Handle<JSObject> object,
2770
                                  Handle<Name> name,
2771
                                  Handle<Object> constant,
2772
                                  PropertyAttributes attributes,
2773
                                  TransitionFlag flag);
2774

    
2775
  // Add a property to a fast-case object.
2776
  static void AddFastProperty(Handle<JSObject> object,
2777
                              Handle<Name> name,
2778
                              Handle<Object> value,
2779
                              PropertyAttributes attributes,
2780
                              StoreFromKeyed store_mode,
2781
                              ValueType value_type,
2782
                              TransitionFlag flag);
2783

    
2784
  // Add a property to a fast-case object using a map transition to
2785
  // new_map.
2786
  static void AddFastPropertyUsingMap(Handle<JSObject> object,
2787
                                      Handle<Map> new_map,
2788
                                      Handle<Name> name,
2789
                                      Handle<Object> value,
2790
                                      int field_index,
2791
                                      Representation representation);
2792

    
2793
  // Add a property to a slow-case object.
2794
  static void AddSlowProperty(Handle<JSObject> object,
2795
                              Handle<Name> name,
2796
                              Handle<Object> value,
2797
                              PropertyAttributes attributes);
2798

    
2799
  static Handle<Object> DeleteProperty(Handle<JSObject> object,
2800
                                       Handle<Name> name,
2801
                                       DeleteMode mode);
2802
  static Handle<Object> DeletePropertyPostInterceptor(Handle<JSObject> object,
2803
                                                      Handle<Name> name,
2804
                                                      DeleteMode mode);
2805
  static Handle<Object> DeletePropertyWithInterceptor(Handle<JSObject> object,
2806
                                                      Handle<Name> name);
2807

    
2808
  // Deletes the named property in a normalized object.
2809
  static Handle<Object> DeleteNormalizedProperty(Handle<JSObject> object,
2810
                                                 Handle<Name> name,
2811
                                                 DeleteMode mode);
2812

    
2813
  static Handle<Object> DeleteElement(Handle<JSObject> object,
2814
                                      uint32_t index,
2815
                                      DeleteMode mode);
2816
  static Handle<Object> DeleteElementWithInterceptor(Handle<JSObject> object,
2817
                                                     uint32_t index);
2818

    
2819
  bool ReferencesObjectFromElements(FixedArray* elements,
2820
                                    ElementsKind kind,
2821
                                    Object* object);
2822

    
2823
  // Returns true if most of the elements backing storage is used.
2824
  bool HasDenseElements();
2825

    
2826
  // Gets the current elements capacity and the number of used elements.
2827
  void GetElementsCapacityAndUsage(int* capacity, int* used);
2828

    
2829
  bool CanSetCallback(Name* name);
2830
  static void SetElementCallback(Handle<JSObject> object,
2831
                                 uint32_t index,
2832
                                 Handle<Object> structure,
2833
                                 PropertyAttributes attributes);
2834
  static void SetPropertyCallback(Handle<JSObject> object,
2835
                                  Handle<Name> name,
2836
                                  Handle<Object> structure,
2837
                                  PropertyAttributes attributes);
2838
  static void DefineElementAccessor(Handle<JSObject> object,
2839
                                    uint32_t index,
2840
                                    Handle<Object> getter,
2841
                                    Handle<Object> setter,
2842
                                    PropertyAttributes attributes,
2843
                                    v8::AccessControl access_control);
2844
  static Handle<AccessorPair> CreateAccessorPairFor(Handle<JSObject> object,
2845
                                                    Handle<Name> name);
2846
  static void DefinePropertyAccessor(Handle<JSObject> object,
2847
                                     Handle<Name> name,
2848
                                     Handle<Object> getter,
2849
                                     Handle<Object> setter,
2850
                                     PropertyAttributes attributes,
2851
                                     v8::AccessControl access_control);
2852

    
2853
  // Try to define a single accessor paying attention to map transitions.
2854
  // Returns false if this was not possible and we have to use the slow case.
2855
  static bool DefineFastAccessor(Handle<JSObject> object,
2856
                                 Handle<Name> name,
2857
                                 AccessorComponent component,
2858
                                 Handle<Object> accessor,
2859
                                 PropertyAttributes attributes);
2860

    
2861
  enum InitializeHiddenProperties {
2862
    CREATE_NEW_IF_ABSENT,
2863
    ONLY_RETURN_INLINE_VALUE
2864
  };
2865

    
2866
  // If create_if_absent is true, return the hash table backing store
2867
  // for hidden properties.  If there is no backing store, allocate one.
2868
  // If create_if_absent is false, return the hash table backing store
2869
  // or the inline stored identity hash, whatever is found.
2870
  MUST_USE_RESULT MaybeObject* GetHiddenPropertiesHashTable(
2871
      InitializeHiddenProperties init_option);
2872
  // Set the hidden property backing store to either a hash table or
2873
  // the inline-stored identity hash.
2874
  MUST_USE_RESULT MaybeObject* SetHiddenPropertiesHashTable(
2875
      Object* value);
2876

    
2877
  MUST_USE_RESULT MaybeObject* GetIdentityHash(CreationFlag flag);
2878

    
2879
  DISALLOW_IMPLICIT_CONSTRUCTORS(JSObject);
2880
};
2881

    
2882

    
2883
// Common superclass for FixedArrays that allow implementations to share
2884
// common accessors and some code paths.
2885
class FixedArrayBase: public HeapObject {
2886
 public:
2887
  // [length]: length of the array.
2888
  inline int length();
2889
  inline void set_length(int value);
2890

    
2891
  inline static FixedArrayBase* cast(Object* object);
2892

    
2893
  // Layout description.
2894
  // Length is smi tagged when it is stored.
2895
  static const int kLengthOffset = HeapObject::kHeaderSize;
2896
  static const int kHeaderSize = kLengthOffset + kPointerSize;
2897
};
2898

    
2899

    
2900
class FixedDoubleArray;
2901
class IncrementalMarking;
2902

    
2903

    
2904
// FixedArray describes fixed-sized arrays with element type Object*.
2905
class FixedArray: public FixedArrayBase {
2906
 public:
2907
  // Setter and getter for elements.
2908
  inline Object* get(int index);
2909
  // Setter that uses write barrier.
2910
  inline void set(int index, Object* value);
2911
  inline bool is_the_hole(int index);
2912

    
2913
  // Setter that doesn't need write barrier.
2914
  inline void set(int index, Smi* value);
2915
  // Setter with explicit barrier mode.
2916
  inline void set(int index, Object* value, WriteBarrierMode mode);
2917

    
2918
  // Setters for frequently used oddballs located in old space.
2919
  inline void set_undefined(int index);
2920
  inline void set_null(int index);
2921
  inline void set_the_hole(int index);
2922

    
2923
  inline Object** GetFirstElementAddress();
2924
  inline bool ContainsOnlySmisOrHoles();
2925

    
2926
  // Gives access to raw memory which stores the array's data.
2927
  inline Object** data_start();
2928

    
2929
  // Copy operations.
2930
  MUST_USE_RESULT inline MaybeObject* Copy();
2931
  MUST_USE_RESULT MaybeObject* CopySize(int new_length,
2932
                                        PretenureFlag pretenure = NOT_TENURED);
2933

    
2934
  // Add the elements of a JSArray to this FixedArray.
2935
  MUST_USE_RESULT MaybeObject* AddKeysFromJSArray(JSArray* array);
2936

    
2937
  // Compute the union of this and other.
2938
  MUST_USE_RESULT MaybeObject* UnionOfKeys(FixedArray* other);
2939

    
2940
  // Copy a sub array from the receiver to dest.
2941
  void CopyTo(int pos, FixedArray* dest, int dest_pos, int len);
2942

    
2943
  // Garbage collection support.
2944
  static int SizeFor(int length) { return kHeaderSize + length * kPointerSize; }
2945

    
2946
  // Code Generation support.
2947
  static int OffsetOfElementAt(int index) { return SizeFor(index); }
2948

    
2949
  // Casting.
2950
  static inline FixedArray* cast(Object* obj);
2951

    
2952
  // Maximal allowed size, in bytes, of a single FixedArray.
2953
  // Prevents overflowing size computations, as well as extreme memory
2954
  // consumption.
2955
  static const int kMaxSize = 128 * MB * kPointerSize;
2956
  // Maximally allowed length of a FixedArray.
2957
  static const int kMaxLength = (kMaxSize - kHeaderSize) / kPointerSize;
2958

    
2959
  // Dispatched behavior.
2960
  DECLARE_PRINTER(FixedArray)
2961
  DECLARE_VERIFIER(FixedArray)
2962
#ifdef DEBUG
2963
  // Checks if two FixedArrays have identical contents.
2964
  bool IsEqualTo(FixedArray* other);
2965
#endif
2966

    
2967
  // Swap two elements in a pair of arrays.  If this array and the
2968
  // numbers array are the same object, the elements are only swapped
2969
  // once.
2970
  void SwapPairs(FixedArray* numbers, int i, int j);
2971

    
2972
  // Sort prefix of this array and the numbers array as pairs wrt. the
2973
  // numbers.  If the numbers array and the this array are the same
2974
  // object, the prefix of this array is sorted.
2975
  void SortPairs(FixedArray* numbers, uint32_t len);
2976

    
2977
  class BodyDescriptor : public FlexibleBodyDescriptor<kHeaderSize> {
2978
   public:
2979
    static inline int SizeOf(Map* map, HeapObject* object) {
2980
      return SizeFor(reinterpret_cast<FixedArray*>(object)->length());
2981
    }
2982
  };
2983

    
2984
 protected:
2985
  // Set operation on FixedArray without using write barriers. Can
2986
  // only be used for storing old space objects or smis.
2987
  static inline void NoWriteBarrierSet(FixedArray* array,
2988
                                       int index,
2989
                                       Object* value);
2990

    
2991
  // Set operation on FixedArray without incremental write barrier. Can
2992
  // only be used if the object is guaranteed to be white (whiteness witness
2993
  // is present).
2994
  static inline void NoIncrementalWriteBarrierSet(FixedArray* array,
2995
                                                  int index,
2996
                                                  Object* value);
2997

    
2998
 private:
2999
  STATIC_CHECK(kHeaderSize == Internals::kFixedArrayHeaderSize);
3000

    
3001
  DISALLOW_IMPLICIT_CONSTRUCTORS(FixedArray);
3002
};
3003

    
3004

    
3005
// FixedDoubleArray describes fixed-sized arrays with element type double.
3006
class FixedDoubleArray: public FixedArrayBase {
3007
 public:
3008
  // Setter and getter for elements.
3009
  inline double get_scalar(int index);
3010
  inline int64_t get_representation(int index);
3011
  MUST_USE_RESULT inline MaybeObject* get(int index);
3012
  inline void set(int index, double value);
3013
  inline void set_the_hole(int index);
3014

    
3015
  // Checking for the hole.
3016
  inline bool is_the_hole(int index);
3017

    
3018
  // Copy operations
3019
  MUST_USE_RESULT inline MaybeObject* Copy();
3020

    
3021
  // Garbage collection support.
3022
  inline static int SizeFor(int length) {
3023
    return kHeaderSize + length * kDoubleSize;
3024
  }
3025

    
3026
  // Gives access to raw memory which stores the array's data.
3027
  inline double* data_start();
3028

    
3029
  // Code Generation support.
3030
  static int OffsetOfElementAt(int index) { return SizeFor(index); }
3031

    
3032
  inline static bool is_the_hole_nan(double value);
3033
  inline static double hole_nan_as_double();
3034
  inline static double canonical_not_the_hole_nan_as_double();
3035

    
3036
  // Casting.
3037
  static inline FixedDoubleArray* cast(Object* obj);
3038

    
3039
  // Maximal allowed size, in bytes, of a single FixedDoubleArray.
3040
  // Prevents overflowing size computations, as well as extreme memory
3041
  // consumption.
3042
  static const int kMaxSize = 512 * MB;
3043
  // Maximally allowed length of a FixedArray.
3044
  static const int kMaxLength = (kMaxSize - kHeaderSize) / kDoubleSize;
3045

    
3046
  // Dispatched behavior.
3047
  DECLARE_PRINTER(FixedDoubleArray)
3048
  DECLARE_VERIFIER(FixedDoubleArray)
3049

    
3050
 private:
3051
  DISALLOW_IMPLICIT_CONSTRUCTORS(FixedDoubleArray);
3052
};
3053

    
3054

    
3055
// ConstantPoolArray describes a fixed-sized array containing constant pool
3056
// entires.
3057
// The format of the pool is:
3058
//   [0]: Field holding the first index which is a pointer entry
3059
//   [1]: Field holding the first index which is a int32 entry
3060
//   [2] ... [first_ptr_index() - 1]: 64 bit entries
3061
//   [first_ptr_index()] ... [first_int32_index() - 1]: pointer entries
3062
//   [first_int32_index()] ... [length - 1]: 32 bit entries
3063
class ConstantPoolArray: public FixedArrayBase {
3064
 public:
3065
  // Getters for the field storing the first index for different type entries.
3066
  inline int first_ptr_index();
3067
  inline int first_int64_index();
3068
  inline int first_int32_index();
3069

    
3070
  // Getters for counts of different type entries.
3071
  inline int count_of_ptr_entries();
3072
  inline int count_of_int64_entries();
3073
  inline int count_of_int32_entries();
3074

    
3075
  // Setter and getter for pool elements.
3076
  inline Object* get_ptr_entry(int index);
3077
  inline int64_t get_int64_entry(int index);
3078
  inline int32_t get_int32_entry(int index);
3079
  inline double get_int64_entry_as_double(int index);
3080

    
3081
  inline void set(int index, Object* value);
3082
  inline void set(int index, int64_t value);
3083
  inline void set(int index, double value);
3084
  inline void set(int index, int32_t value);
3085

    
3086
  // Set up initial state.
3087
  inline void SetEntryCounts(int number_of_int64_entries,
3088
                             int number_of_ptr_entries,
3089
                             int number_of_int32_entries);
3090

    
3091
  // Copy operations
3092
  MUST_USE_RESULT inline MaybeObject* Copy();
3093

    
3094
  // Garbage collection support.
3095
  inline static int SizeFor(int number_of_int64_entries,
3096
                            int number_of_ptr_entries,
3097
                            int number_of_int32_entries) {
3098
    return RoundUp(OffsetAt(number_of_int64_entries,
3099
                            number_of_ptr_entries,
3100
                            number_of_int32_entries),
3101
                   kPointerSize);
3102
  }
3103

    
3104
  // Code Generation support.
3105
  inline int OffsetOfElementAt(int index) {
3106
    ASSERT(index < length());
3107
    if (index >= first_int32_index()) {
3108
      return OffsetAt(count_of_int64_entries(), count_of_ptr_entries(),
3109
                      index - first_int32_index());
3110
    } else if (index >= first_ptr_index()) {
3111
      return OffsetAt(count_of_int64_entries(), index - first_ptr_index(), 0);
3112
    } else {
3113
      return OffsetAt(index, 0, 0);
3114
    }
3115
  }
3116

    
3117
  // Casting.
3118
  static inline ConstantPoolArray* cast(Object* obj);
3119

    
3120
  // Layout description.
3121
  static const int kFirstPointerIndexOffset = FixedArray::kHeaderSize;
3122
  static const int kFirstInt32IndexOffset =
3123
      kFirstPointerIndexOffset + kPointerSize;
3124
  static const int kFirstOffset = kFirstInt32IndexOffset + kPointerSize;
3125

    
3126
  // Dispatched behavior.
3127
  void ConstantPoolIterateBody(ObjectVisitor* v);
3128

    
3129
  DECLARE_PRINTER(ConstantPoolArray)
3130
  DECLARE_VERIFIER(ConstantPoolArray)
3131

    
3132
 private:
3133
  inline void set_first_ptr_index(int value);
3134
  inline void set_first_int32_index(int value);
3135

    
3136
  inline static int OffsetAt(int number_of_int64_entries,
3137
                             int number_of_ptr_entries,
3138
                             int number_of_int32_entries) {
3139
    return kFirstOffset
3140
        + (number_of_int64_entries * kInt64Size)
3141
        + (number_of_ptr_entries * kPointerSize)
3142
        + (number_of_int32_entries * kInt32Size);
3143
  }
3144

    
3145
  DISALLOW_IMPLICIT_CONSTRUCTORS(ConstantPoolArray);
3146
};
3147

    
3148

    
3149
// DescriptorArrays are fixed arrays used to hold instance descriptors.
3150
// The format of the these objects is:
3151
//   [0]: Number of descriptors
3152
//   [1]: Either Smi(0) if uninitialized, or a pointer to small fixed array:
3153
//          [0]: pointer to fixed array with enum cache
3154
//          [1]: either Smi(0) or pointer to fixed array with indices
3155
//   [2]: first key
3156
//   [2 + number of descriptors * kDescriptorSize]: start of slack
3157
class DescriptorArray: public FixedArray {
3158
 public:
3159
  // WhitenessWitness is used to prove that a descriptor array is white
3160
  // (unmarked), so incremental write barriers can be skipped because the
3161
  // marking invariant cannot be broken and slots pointing into evacuation
3162
  // candidates will be discovered when the object is scanned. A witness is
3163
  // always stack-allocated right after creating an array. By allocating a
3164
  // witness, incremental marking is globally disabled. The witness is then
3165
  // passed along wherever needed to statically prove that the array is known to
3166
  // be white.
3167
  class WhitenessWitness {
3168
   public:
3169
    inline explicit WhitenessWitness(FixedArray* array);
3170
    inline ~WhitenessWitness();
3171

    
3172
   private:
3173
    IncrementalMarking* marking_;
3174
  };
3175

    
3176
  // Returns true for both shared empty_descriptor_array and for smis, which the
3177
  // map uses to encode additional bit fields when the descriptor array is not
3178
  // yet used.
3179
  inline bool IsEmpty();
3180

    
3181
  // Returns the number of descriptors in the array.
3182
  int number_of_descriptors() {
3183
    ASSERT(length() >= kFirstIndex || IsEmpty());
3184
    int len = length();
3185
    return len == 0 ? 0 : Smi::cast(get(kDescriptorLengthIndex))->value();
3186
  }
3187

    
3188
  int number_of_descriptors_storage() {
3189
    int len = length();
3190
    return len == 0 ? 0 : (len - kFirstIndex) / kDescriptorSize;
3191
  }
3192

    
3193
  int NumberOfSlackDescriptors() {
3194
    return number_of_descriptors_storage() - number_of_descriptors();
3195
  }
3196

    
3197
  inline void SetNumberOfDescriptors(int number_of_descriptors);
3198
  inline int number_of_entries() { return number_of_descriptors(); }
3199

    
3200
  bool HasEnumCache() {
3201
    return !IsEmpty() && !get(kEnumCacheIndex)->IsSmi();
3202
  }
3203

    
3204
  void CopyEnumCacheFrom(DescriptorArray* array) {
3205
    set(kEnumCacheIndex, array->get(kEnumCacheIndex));
3206
  }
3207

    
3208
  FixedArray* GetEnumCache() {
3209
    ASSERT(HasEnumCache());
3210
    FixedArray* bridge = FixedArray::cast(get(kEnumCacheIndex));
3211
    return FixedArray::cast(bridge->get(kEnumCacheBridgeCacheIndex));
3212
  }
3213

    
3214
  bool HasEnumIndicesCache() {
3215
    if (IsEmpty()) return false;
3216
    Object* object = get(kEnumCacheIndex);
3217
    if (object->IsSmi()) return false;
3218
    FixedArray* bridge = FixedArray::cast(object);
3219
    return !bridge->get(kEnumCacheBridgeIndicesCacheIndex)->IsSmi();
3220
  }
3221

    
3222
  FixedArray* GetEnumIndicesCache() {
3223
    ASSERT(HasEnumIndicesCache());
3224
    FixedArray* bridge = FixedArray::cast(get(kEnumCacheIndex));
3225
    return FixedArray::cast(bridge->get(kEnumCacheBridgeIndicesCacheIndex));
3226
  }
3227

    
3228
  Object** GetEnumCacheSlot() {
3229
    ASSERT(HasEnumCache());
3230
    return HeapObject::RawField(reinterpret_cast<HeapObject*>(this),
3231
                                kEnumCacheOffset);
3232
  }
3233

    
3234
  void ClearEnumCache();
3235

    
3236
  // Initialize or change the enum cache,
3237
  // using the supplied storage for the small "bridge".
3238
  void SetEnumCache(FixedArray* bridge_storage,
3239
                    FixedArray* new_cache,
3240
                    Object* new_index_cache);
3241

    
3242
  // Accessors for fetching instance descriptor at descriptor number.
3243
  inline Name* GetKey(int descriptor_number);
3244
  inline Object** GetKeySlot(int descriptor_number);
3245
  inline Object* GetValue(int descriptor_number);
3246
  inline Object** GetValueSlot(int descriptor_number);
3247
  inline Object** GetDescriptorStartSlot(int descriptor_number);
3248
  inline Object** GetDescriptorEndSlot(int descriptor_number);
3249
  inline PropertyDetails GetDetails(int descriptor_number);
3250
  inline PropertyType GetType(int descriptor_number);
3251
  inline int GetFieldIndex(int descriptor_number);
3252
  inline Object* GetConstant(int descriptor_number);
3253
  inline Object* GetCallbacksObject(int descriptor_number);
3254
  inline AccessorDescriptor* GetCallbacks(int descriptor_number);
3255

    
3256
  inline Name* GetSortedKey(int descriptor_number);
3257
  inline int GetSortedKeyIndex(int descriptor_number);
3258
  inline void SetSortedKey(int pointer, int descriptor_number);
3259
  inline void InitializeRepresentations(Representation representation);
3260
  inline void SetRepresentation(int descriptor_number,
3261
                                Representation representation);
3262

    
3263
  // Accessor for complete descriptor.
3264
  inline void Get(int descriptor_number, Descriptor* desc);
3265
  inline void Set(int descriptor_number,
3266
                  Descriptor* desc,
3267
                  const WhitenessWitness&);
3268
  inline void Set(int descriptor_number, Descriptor* desc);
3269

    
3270
  // Append automatically sets the enumeration index. This should only be used
3271
  // to add descriptors in bulk at the end, followed by sorting the descriptor
3272
  // array.
3273
  inline void Append(Descriptor* desc, const WhitenessWitness&);
3274
  inline void Append(Descriptor* desc);
3275

    
3276
  // Transfer a complete descriptor from the src descriptor array to this
3277
  // descriptor array.
3278
  void CopyFrom(int dst_index,
3279
                DescriptorArray* src,
3280
                int src_index,
3281
                const WhitenessWitness&);
3282
  static Handle<DescriptorArray> Merge(Handle<DescriptorArray> desc,
3283
                                       int verbatim,
3284
                                       int valid,
3285
                                       int new_size,
3286
                                       int modify_index,
3287
                                       StoreMode store_mode,
3288
                                       Handle<DescriptorArray> other);
3289
  MUST_USE_RESULT MaybeObject* Merge(int verbatim,
3290
                                     int valid,
3291
                                     int new_size,
3292
                                     int modify_index,
3293
                                     StoreMode store_mode,
3294
                                     DescriptorArray* other);
3295

    
3296
  bool IsMoreGeneralThan(int verbatim,
3297
                         int valid,
3298
                         int new_size,
3299
                         DescriptorArray* other);
3300

    
3301
  MUST_USE_RESULT MaybeObject* CopyUpTo(int enumeration_index) {
3302
    return CopyUpToAddAttributes(enumeration_index, NONE);
3303
  }
3304

    
3305
  static Handle<DescriptorArray> CopyUpToAddAttributes(
3306
      Handle<DescriptorArray> desc,
3307
      int enumeration_index,
3308
      PropertyAttributes attributes);
3309
  MUST_USE_RESULT MaybeObject* CopyUpToAddAttributes(
3310
      int enumeration_index,
3311
      PropertyAttributes attributes);
3312

    
3313
  // Sort the instance descriptors by the hash codes of their keys.
3314
  void Sort();
3315

    
3316
  // Search the instance descriptors for given name.
3317
  INLINE(int Search(Name* name, int number_of_own_descriptors));
3318

    
3319
  // As the above, but uses DescriptorLookupCache and updates it when
3320
  // necessary.
3321
  INLINE(int SearchWithCache(Name* name, Map* map));
3322

    
3323
  // Allocates a DescriptorArray, but returns the singleton
3324
  // empty descriptor array object if number_of_descriptors is 0.
3325
  MUST_USE_RESULT static MaybeObject* Allocate(Isolate* isolate,
3326
                                               int number_of_descriptors,
3327
                                               int slack = 0);
3328

    
3329
  // Casting.
3330
  static inline DescriptorArray* cast(Object* obj);
3331

    
3332
  // Constant for denoting key was not found.
3333
  static const int kNotFound = -1;
3334

    
3335
  static const int kDescriptorLengthIndex = 0;
3336
  static const int kEnumCacheIndex = 1;
3337
  static const int kFirstIndex = 2;
3338

    
3339
  // The length of the "bridge" to the enum cache.
3340
  static const int kEnumCacheBridgeLength = 2;
3341
  static const int kEnumCacheBridgeCacheIndex = 0;
3342
  static const int kEnumCacheBridgeIndicesCacheIndex = 1;
3343

    
3344
  // Layout description.
3345
  static const int kDescriptorLengthOffset = FixedArray::kHeaderSize;
3346
  static const int kEnumCacheOffset = kDescriptorLengthOffset + kPointerSize;
3347
  static const int kFirstOffset = kEnumCacheOffset + kPointerSize;
3348

    
3349
  // Layout description for the bridge array.
3350
  static const int kEnumCacheBridgeCacheOffset = FixedArray::kHeaderSize;
3351

    
3352
  // Layout of descriptor.
3353
  static const int kDescriptorKey = 0;
3354
  static const int kDescriptorDetails = 1;
3355
  static const int kDescriptorValue = 2;
3356
  static const int kDescriptorSize = 3;
3357

    
3358
#ifdef OBJECT_PRINT
3359
  // Print all the descriptors.
3360
  void PrintDescriptors(FILE* out = stdout);
3361
#endif
3362

    
3363
#ifdef DEBUG
3364
  // Is the descriptor array sorted and without duplicates?
3365
  bool IsSortedNoDuplicates(int valid_descriptors = -1);
3366

    
3367
  // Is the descriptor array consistent with the back pointers in targets?
3368
  bool IsConsistentWithBackPointers(Map* current_map);
3369

    
3370
  // Are two DescriptorArrays equal?
3371
  bool IsEqualTo(DescriptorArray* other);
3372
#endif
3373

    
3374
  // The maximum number of descriptors we want in a descriptor array (should
3375
  // fit in a page).
3376
  static const int kMaxNumberOfDescriptors = 1024 + 512;
3377

    
3378
  // Returns the fixed array length required to hold number_of_descriptors
3379
  // descriptors.
3380
  static int LengthFor(int number_of_descriptors) {
3381
    return ToKeyIndex(number_of_descriptors);
3382
  }
3383

    
3384
 private:
3385
  // An entry in a DescriptorArray, represented as an (array, index) pair.
3386
  class Entry {
3387
   public:
3388
    inline explicit Entry(DescriptorArray* descs, int index) :
3389
        descs_(descs), index_(index) { }
3390

    
3391
    inline PropertyType type() { return descs_->GetType(index_); }
3392
    inline Object* GetCallbackObject() { return descs_->GetValue(index_); }
3393

    
3394
   private:
3395
    DescriptorArray* descs_;
3396
    int index_;
3397
  };
3398

    
3399
  // Conversion from descriptor number to array indices.
3400
  static int ToKeyIndex(int descriptor_number) {
3401
    return kFirstIndex +
3402
           (descriptor_number * kDescriptorSize) +
3403
           kDescriptorKey;
3404
  }
3405

    
3406
  static int ToDetailsIndex(int descriptor_number) {
3407
    return kFirstIndex +
3408
           (descriptor_number * kDescriptorSize) +
3409
           kDescriptorDetails;
3410
  }
3411

    
3412
  static int ToValueIndex(int descriptor_number) {
3413
    return kFirstIndex +
3414
           (descriptor_number * kDescriptorSize) +
3415
           kDescriptorValue;
3416
  }
3417

    
3418
  // Swap first and second descriptor.
3419
  inline void SwapSortedKeys(int first, int second);
3420

    
3421
  DISALLOW_IMPLICIT_CONSTRUCTORS(DescriptorArray);
3422
};
3423

    
3424

    
3425
enum SearchMode { ALL_ENTRIES, VALID_ENTRIES };
3426

    
3427
template<SearchMode search_mode, typename T>
3428
inline int LinearSearch(T* array, Name* name, int len, int valid_entries);
3429

    
3430

    
3431
template<SearchMode search_mode, typename T>
3432
inline int Search(T* array, Name* name, int valid_entries = 0);
3433

    
3434

    
3435
// HashTable is a subclass of FixedArray that implements a hash table
3436
// that uses open addressing and quadratic probing.
3437
//
3438
// In order for the quadratic probing to work, elements that have not
3439
// yet been used and elements that have been deleted are
3440
// distinguished.  Probing continues when deleted elements are
3441
// encountered and stops when unused elements are encountered.
3442
//
3443
// - Elements with key == undefined have not been used yet.
3444
// - Elements with key == the_hole have been deleted.
3445
//
3446
// The hash table class is parameterized with a Shape and a Key.
3447
// Shape must be a class with the following interface:
3448
//   class ExampleShape {
3449
//    public:
3450
//      // Tells whether key matches other.
3451
//     static bool IsMatch(Key key, Object* other);
3452
//     // Returns the hash value for key.
3453
//     static uint32_t Hash(Key key);
3454
//     // Returns the hash value for object.
3455
//     static uint32_t HashForObject(Key key, Object* object);
3456
//     // Convert key to an object.
3457
//     static inline Object* AsObject(Heap* heap, Key key);
3458
//     // The prefix size indicates number of elements in the beginning
3459
//     // of the backing storage.
3460
//     static const int kPrefixSize = ..;
3461
//     // The Element size indicates number of elements per entry.
3462
//     static const int kEntrySize = ..;
3463
//   };
3464
// The prefix size indicates an amount of memory in the
3465
// beginning of the backing storage that can be used for non-element
3466
// information by subclasses.
3467

    
3468
template<typename Key>
3469
class BaseShape {
3470
 public:
3471
  static const bool UsesSeed = false;
3472
  static uint32_t Hash(Key key) { return 0; }
3473
  static uint32_t SeededHash(Key key, uint32_t seed) {
3474
    ASSERT(UsesSeed);
3475
    return Hash(key);
3476
  }
3477
  static uint32_t HashForObject(Key key, Object* object) { return 0; }
3478
  static uint32_t SeededHashForObject(Key key, uint32_t seed, Object* object) {
3479
    ASSERT(UsesSeed);
3480
    return HashForObject(key, object);
3481
  }
3482
};
3483

    
3484
template<typename Shape, typename Key>
3485
class HashTable: public FixedArray {
3486
 public:
3487
  enum MinimumCapacity {
3488
    USE_DEFAULT_MINIMUM_CAPACITY,
3489
    USE_CUSTOM_MINIMUM_CAPACITY
3490
  };
3491

    
3492
  // Wrapper methods
3493
  inline uint32_t Hash(Key key) {
3494
    if (Shape::UsesSeed) {
3495
      return Shape::SeededHash(key,
3496
          GetHeap()->HashSeed());
3497
    } else {
3498
      return Shape::Hash(key);
3499
    }
3500
  }
3501

    
3502
  inline uint32_t HashForObject(Key key, Object* object) {
3503
    if (Shape::UsesSeed) {
3504
      return Shape::SeededHashForObject(key,
3505
          GetHeap()->HashSeed(), object);
3506
    } else {
3507
      return Shape::HashForObject(key, object);
3508
    }
3509
  }
3510

    
3511
  // Returns the number of elements in the hash table.
3512
  int NumberOfElements() {
3513
    return Smi::cast(get(kNumberOfElementsIndex))->value();
3514
  }
3515

    
3516
  // Returns the number of deleted elements in the hash table.
3517
  int NumberOfDeletedElements() {
3518
    return Smi::cast(get(kNumberOfDeletedElementsIndex))->value();
3519
  }
3520

    
3521
  // Returns the capacity of the hash table.
3522
  int Capacity() {
3523
    return Smi::cast(get(kCapacityIndex))->value();
3524
  }
3525

    
3526
  // ElementAdded should be called whenever an element is added to a
3527
  // hash table.
3528
  void ElementAdded() { SetNumberOfElements(NumberOfElements() + 1); }
3529

    
3530
  // ElementRemoved should be called whenever an element is removed from
3531
  // a hash table.
3532
  void ElementRemoved() {
3533
    SetNumberOfElements(NumberOfElements() - 1);
3534
    SetNumberOfDeletedElements(NumberOfDeletedElements() + 1);
3535
  }
3536
  void ElementsRemoved(int n) {
3537
    SetNumberOfElements(NumberOfElements() - n);
3538
    SetNumberOfDeletedElements(NumberOfDeletedElements() + n);
3539
  }
3540

    
3541
  // Returns a new HashTable object. Might return Failure.
3542
  MUST_USE_RESULT static MaybeObject* Allocate(
3543
      Heap* heap,
3544
      int at_least_space_for,
3545
      MinimumCapacity capacity_option = USE_DEFAULT_MINIMUM_CAPACITY,
3546
      PretenureFlag pretenure = NOT_TENURED);
3547

    
3548
  // Computes the required capacity for a table holding the given
3549
  // number of elements. May be more than HashTable::kMaxCapacity.
3550
  static int ComputeCapacity(int at_least_space_for);
3551

    
3552
  // Returns the key at entry.
3553
  Object* KeyAt(int entry) { return get(EntryToIndex(entry)); }
3554

    
3555
  // Tells whether k is a real key.  The hole and undefined are not allowed
3556
  // as keys and can be used to indicate missing or deleted elements.
3557
  bool IsKey(Object* k) {
3558
    return !k->IsTheHole() && !k->IsUndefined();
3559
  }
3560

    
3561
  // Garbage collection support.
3562
  void IteratePrefix(ObjectVisitor* visitor);
3563
  void IterateElements(ObjectVisitor* visitor);
3564

    
3565
  // Casting.
3566
  static inline HashTable* cast(Object* obj);
3567

    
3568
  // Compute the probe offset (quadratic probing).
3569
  INLINE(static uint32_t GetProbeOffset(uint32_t n)) {
3570
    return (n + n * n) >> 1;
3571
  }
3572

    
3573
  static const int kNumberOfElementsIndex = 0;
3574
  static const int kNumberOfDeletedElementsIndex = 1;
3575
  static const int kCapacityIndex = 2;
3576
  static const int kPrefixStartIndex = 3;
3577
  static const int kElementsStartIndex =
3578
      kPrefixStartIndex + Shape::kPrefixSize;
3579
  static const int kEntrySize = Shape::kEntrySize;
3580
  static const int kElementsStartOffset =
3581
      kHeaderSize + kElementsStartIndex * kPointerSize;
3582
  static const int kCapacityOffset =
3583
      kHeaderSize + kCapacityIndex * kPointerSize;
3584

    
3585
  // Constant used for denoting a absent entry.
3586
  static const int kNotFound = -1;
3587

    
3588
  // Maximal capacity of HashTable. Based on maximal length of underlying
3589
  // FixedArray. Staying below kMaxCapacity also ensures that EntryToIndex
3590
  // cannot overflow.
3591
  static const int kMaxCapacity =
3592
      (FixedArray::kMaxLength - kElementsStartOffset) / kEntrySize;
3593

    
3594
  // Find entry for key otherwise return kNotFound.
3595
  inline int FindEntry(Key key);
3596
  int FindEntry(Isolate* isolate, Key key);
3597

    
3598
  // Rehashes the table in-place.
3599
  void Rehash(Key key);
3600

    
3601
 protected:
3602
  // Find the entry at which to insert element with the given key that
3603
  // has the given hash value.
3604
  uint32_t FindInsertionEntry(uint32_t hash);
3605

    
3606
  // Returns the index for an entry (of the key)
3607
  static inline int EntryToIndex(int entry) {
3608
    return (entry * kEntrySize) + kElementsStartIndex;
3609
  }
3610

    
3611
  // Update the number of elements in the hash table.
3612
  void SetNumberOfElements(int nof) {
3613
    set(kNumberOfElementsIndex, Smi::FromInt(nof));
3614
  }
3615

    
3616
  // Update the number of deleted elements in the hash table.
3617
  void SetNumberOfDeletedElements(int nod) {
3618
    set(kNumberOfDeletedElementsIndex, Smi::FromInt(nod));
3619
  }
3620

    
3621
  // Sets the capacity of the hash table.
3622
  void SetCapacity(int capacity) {
3623
    // To scale a computed hash code to fit within the hash table, we
3624
    // use bit-wise AND with a mask, so the capacity must be positive
3625
    // and non-zero.
3626
    ASSERT(capacity > 0);
3627
    ASSERT(capacity <= kMaxCapacity);
3628
    set(kCapacityIndex, Smi::FromInt(capacity));
3629
  }
3630

    
3631

    
3632
  // Returns probe entry.
3633
  static uint32_t GetProbe(uint32_t hash, uint32_t number, uint32_t size) {
3634
    ASSERT(IsPowerOf2(size));
3635
    return (hash + GetProbeOffset(number)) & (size - 1);
3636
  }
3637

    
3638
  inline static uint32_t FirstProbe(uint32_t hash, uint32_t size) {
3639
    return hash & (size - 1);
3640
  }
3641

    
3642
  inline static uint32_t NextProbe(
3643
      uint32_t last, uint32_t number, uint32_t size) {
3644
    return (last + number) & (size - 1);
3645
  }
3646

    
3647
  // Returns _expected_ if one of entries given by the first _probe_ probes is
3648
  // equal to  _expected_. Otherwise, returns the entry given by the probe
3649
  // number _probe_.
3650
  uint32_t EntryForProbe(Key key, Object* k, int probe, uint32_t expected);
3651

    
3652
  void Swap(uint32_t entry1, uint32_t entry2, WriteBarrierMode mode);
3653

    
3654
  // Rehashes this hash-table into the new table.
3655
  MUST_USE_RESULT MaybeObject* Rehash(HashTable* new_table, Key key);
3656

    
3657
  // Attempt to shrink hash table after removal of key.
3658
  MUST_USE_RESULT MaybeObject* Shrink(Key key);
3659

    
3660
  // Ensure enough space for n additional elements.
3661
  MUST_USE_RESULT MaybeObject* EnsureCapacity(
3662
      int n,
3663
      Key key,
3664
      PretenureFlag pretenure = NOT_TENURED);
3665
};
3666

    
3667

    
3668
// HashTableKey is an abstract superclass for virtual key behavior.
3669
class HashTableKey {
3670
 public:
3671
  // Returns whether the other object matches this key.
3672
  virtual bool IsMatch(Object* other) = 0;
3673
  // Returns the hash value for this key.
3674
  virtual uint32_t Hash() = 0;
3675
  // Returns the hash value for object.
3676
  virtual uint32_t HashForObject(Object* key) = 0;
3677
  // Returns the key object for storing into the hash table.
3678
  // If allocations fails a failure object is returned.
3679
  MUST_USE_RESULT virtual MaybeObject* AsObject(Heap* heap) = 0;
3680
  // Required.
3681
  virtual ~HashTableKey() {}
3682
};
3683

    
3684

    
3685
class StringTableShape : public BaseShape<HashTableKey*> {
3686
 public:
3687
  static inline bool IsMatch(HashTableKey* key, Object* value) {
3688
    return key->IsMatch(value);
3689
  }
3690
  static inline uint32_t Hash(HashTableKey* key) {
3691
    return key->Hash();
3692
  }
3693
  static inline uint32_t HashForObject(HashTableKey* key, Object* object) {
3694
    return key->HashForObject(object);
3695
  }
3696
  MUST_USE_RESULT static inline MaybeObject* AsObject(Heap* heap,
3697
                                                      HashTableKey* key) {
3698
    return key->AsObject(heap);
3699
  }
3700

    
3701
  static const int kPrefixSize = 0;
3702
  static const int kEntrySize = 1;
3703
};
3704

    
3705
class SeqOneByteString;
3706

    
3707
// StringTable.
3708
//
3709
// No special elements in the prefix and the element size is 1
3710
// because only the string itself (the key) needs to be stored.
3711
class StringTable: public HashTable<StringTableShape, HashTableKey*> {
3712
 public:
3713
  // Find string in the string table.  If it is not there yet, it is
3714
  // added.  The return value is the string table which might have
3715
  // been enlarged.  If the return value is not a failure, the string
3716
  // pointer *s is set to the string found.
3717
  MUST_USE_RESULT MaybeObject* LookupUtf8String(
3718
      Vector<const char> str,
3719
      Object** s);
3720
  MUST_USE_RESULT MaybeObject* LookupOneByteString(
3721
      Vector<const uint8_t> str,
3722
      Object** s);
3723
  MUST_USE_RESULT MaybeObject* LookupSubStringOneByteString(
3724
      Handle<SeqOneByteString> str,
3725
      int from,
3726
      int length,
3727
      Object** s);
3728
  MUST_USE_RESULT MaybeObject* LookupTwoByteString(
3729
      Vector<const uc16> str,
3730
      Object** s);
3731
  MUST_USE_RESULT MaybeObject* LookupString(String* key, Object** s);
3732

    
3733
  // Looks up a string that is equal to the given string and returns
3734
  // true if it is found, assigning the string to the given output
3735
  // parameter.
3736
  bool LookupStringIfExists(String* str, String** result);
3737
  bool LookupTwoCharsStringIfExists(uint16_t c1, uint16_t c2, String** result);
3738

    
3739
  // Casting.
3740
  static inline StringTable* cast(Object* obj);
3741

    
3742
 private:
3743
  MUST_USE_RESULT MaybeObject* LookupKey(HashTableKey* key, Object** s);
3744

    
3745
  template <bool seq_ascii> friend class JsonParser;
3746

    
3747
  DISALLOW_IMPLICIT_CONSTRUCTORS(StringTable);
3748
};
3749

    
3750

    
3751
class MapCacheShape : public BaseShape<HashTableKey*> {
3752
 public:
3753
  static inline bool IsMatch(HashTableKey* key, Object* value) {
3754
    return key->IsMatch(value);
3755
  }
3756
  static inline uint32_t Hash(HashTableKey* key) {
3757
    return key->Hash();
3758
  }
3759

    
3760
  static inline uint32_t HashForObject(HashTableKey* key, Object* object) {
3761
    return key->HashForObject(object);
3762
  }
3763

    
3764
  MUST_USE_RESULT static inline MaybeObject* AsObject(Heap* heap,
3765
                                                      HashTableKey* key) {
3766
    return key->AsObject(heap);
3767
  }
3768

    
3769
  static const int kPrefixSize = 0;
3770
  static const int kEntrySize = 2;
3771
};
3772

    
3773

    
3774
// MapCache.
3775
//
3776
// Maps keys that are a fixed array of unique names to a map.
3777
// Used for canonicalize maps for object literals.
3778
class MapCache: public HashTable<MapCacheShape, HashTableKey*> {
3779
 public:
3780
  // Find cached value for a name key, otherwise return null.
3781
  Object* Lookup(FixedArray* key);
3782
  MUST_USE_RESULT MaybeObject* Put(FixedArray* key, Map* value);
3783
  static inline MapCache* cast(Object* obj);
3784

    
3785
 private:
3786
  DISALLOW_IMPLICIT_CONSTRUCTORS(MapCache);
3787
};
3788

    
3789

    
3790
template <typename Shape, typename Key>
3791
class Dictionary: public HashTable<Shape, Key> {
3792
 public:
3793
  static inline Dictionary<Shape, Key>* cast(Object* obj) {
3794
    return reinterpret_cast<Dictionary<Shape, Key>*>(obj);
3795
  }
3796

    
3797
  // Returns the value at entry.
3798
  Object* ValueAt(int entry) {
3799
    return this->get(HashTable<Shape, Key>::EntryToIndex(entry) + 1);
3800
  }
3801

    
3802
  // Set the value for entry.
3803
  void ValueAtPut(int entry, Object* value) {
3804
    this->set(HashTable<Shape, Key>::EntryToIndex(entry) + 1, value);
3805
  }
3806

    
3807
  // Returns the property details for the property at entry.
3808
  PropertyDetails DetailsAt(int entry) {
3809
    ASSERT(entry >= 0);  // Not found is -1, which is not caught by get().
3810
    return PropertyDetails(
3811
        Smi::cast(this->get(HashTable<Shape, Key>::EntryToIndex(entry) + 2)));
3812
  }
3813

    
3814
  // Set the details for entry.
3815
  void DetailsAtPut(int entry, PropertyDetails value) {
3816
    this->set(HashTable<Shape, Key>::EntryToIndex(entry) + 2, value.AsSmi());
3817
  }
3818

    
3819
  // Sorting support
3820
  void CopyValuesTo(FixedArray* elements);
3821

    
3822
  // Delete a property from the dictionary.
3823
  Object* DeleteProperty(int entry, JSObject::DeleteMode mode);
3824

    
3825
  // Attempt to shrink the dictionary after deletion of key.
3826
  MUST_USE_RESULT MaybeObject* Shrink(Key key);
3827

    
3828
  // Returns the number of elements in the dictionary filtering out properties
3829
  // with the specified attributes.
3830
  int NumberOfElementsFilterAttributes(PropertyAttributes filter);
3831

    
3832
  // Returns the number of enumerable elements in the dictionary.
3833
  int NumberOfEnumElements();
3834

    
3835
  enum SortMode { UNSORTED, SORTED };
3836
  // Copies keys to preallocated fixed array.
3837
  void CopyKeysTo(FixedArray* storage,
3838
                  PropertyAttributes filter,
3839
                  SortMode sort_mode);
3840
  // Fill in details for properties into storage.
3841
  void CopyKeysTo(FixedArray* storage,
3842
                  int index,
3843
                  PropertyAttributes filter,
3844
                  SortMode sort_mode);
3845

    
3846
  // Accessors for next enumeration index.
3847
  void SetNextEnumerationIndex(int index) {
3848
    ASSERT(index != 0);
3849
    this->set(kNextEnumerationIndexIndex, Smi::FromInt(index));
3850
  }
3851

    
3852
  int NextEnumerationIndex() {
3853
    return Smi::cast(FixedArray::get(kNextEnumerationIndexIndex))->value();
3854
  }
3855

    
3856
  // Returns a new array for dictionary usage. Might return Failure.
3857
  MUST_USE_RESULT static MaybeObject* Allocate(
3858
      Heap* heap,
3859
      int at_least_space_for,
3860
      PretenureFlag pretenure = NOT_TENURED);
3861

    
3862
  // Ensure enough space for n additional elements.
3863
  MUST_USE_RESULT MaybeObject* EnsureCapacity(int n, Key key);
3864

    
3865
#ifdef OBJECT_PRINT
3866
  void Print(FILE* out = stdout);
3867
#endif
3868
  // Returns the key (slow).
3869
  Object* SlowReverseLookup(Object* value);
3870

    
3871
  // Sets the entry to (key, value) pair.
3872
  inline void SetEntry(int entry,
3873
                       Object* key,
3874
                       Object* value);
3875
  inline void SetEntry(int entry,
3876
                       Object* key,
3877
                       Object* value,
3878
                       PropertyDetails details);
3879

    
3880
  MUST_USE_RESULT MaybeObject* Add(Key key,
3881
                                   Object* value,
3882
                                   PropertyDetails details);
3883

    
3884
 protected:
3885
  // Generic at put operation.
3886
  MUST_USE_RESULT MaybeObject* AtPut(Key key, Object* value);
3887

    
3888
  // Add entry to dictionary.
3889
  MUST_USE_RESULT MaybeObject* AddEntry(Key key,
3890
                                        Object* value,
3891
                                        PropertyDetails details,
3892
                                        uint32_t hash);
3893

    
3894
  // Generate new enumeration indices to avoid enumeration index overflow.
3895
  MUST_USE_RESULT MaybeObject* GenerateNewEnumerationIndices();
3896
  static const int kMaxNumberKeyIndex =
3897
      HashTable<Shape, Key>::kPrefixStartIndex;
3898
  static const int kNextEnumerationIndexIndex = kMaxNumberKeyIndex + 1;
3899
};
3900

    
3901

    
3902
class NameDictionaryShape : public BaseShape<Name*> {
3903
 public:
3904
  static inline bool IsMatch(Name* key, Object* other);
3905
  static inline uint32_t Hash(Name* key);
3906
  static inline uint32_t HashForObject(Name* key, Object* object);
3907
  MUST_USE_RESULT static inline MaybeObject* AsObject(Heap* heap,
3908
                                                      Name* key);
3909
  static const int kPrefixSize = 2;
3910
  static const int kEntrySize = 3;
3911
  static const bool kIsEnumerable = true;
3912
};
3913

    
3914

    
3915
class NameDictionary: public Dictionary<NameDictionaryShape, Name*> {
3916
 public:
3917
  static inline NameDictionary* cast(Object* obj) {
3918
    ASSERT(obj->IsDictionary());
3919
    return reinterpret_cast<NameDictionary*>(obj);
3920
  }
3921

    
3922
  // Copies enumerable keys to preallocated fixed array.
3923
  FixedArray* CopyEnumKeysTo(FixedArray* storage);
3924
  static void DoGenerateNewEnumerationIndices(
3925
      Handle<NameDictionary> dictionary);
3926

    
3927
  // For transforming properties of a JSObject.
3928
  MUST_USE_RESULT MaybeObject* TransformPropertiesToFastFor(
3929
      JSObject* obj,
3930
      int unused_property_fields);
3931

    
3932
  // Find entry for key, otherwise return kNotFound. Optimized version of
3933
  // HashTable::FindEntry.
3934
  int FindEntry(Name* key);
3935
};
3936

    
3937

    
3938
class NumberDictionaryShape : public BaseShape<uint32_t> {
3939
 public:
3940
  static inline bool IsMatch(uint32_t key, Object* other);
3941
  MUST_USE_RESULT static inline MaybeObject* AsObject(Heap* heap,
3942
                                                      uint32_t key);
3943
  static const int kEntrySize = 3;
3944
  static const bool kIsEnumerable = false;
3945
};
3946

    
3947

    
3948
class SeededNumberDictionaryShape : public NumberDictionaryShape {
3949
 public:
3950
  static const bool UsesSeed = true;
3951
  static const int kPrefixSize = 2;
3952

    
3953
  static inline uint32_t SeededHash(uint32_t key, uint32_t seed);
3954
  static inline uint32_t SeededHashForObject(uint32_t key,
3955
                                             uint32_t seed,
3956
                                             Object* object);
3957
};
3958

    
3959

    
3960
class UnseededNumberDictionaryShape : public NumberDictionaryShape {
3961
 public:
3962
  static const int kPrefixSize = 0;
3963

    
3964
  static inline uint32_t Hash(uint32_t key);
3965
  static inline uint32_t HashForObject(uint32_t key, Object* object);
3966
};
3967

    
3968

    
3969
class SeededNumberDictionary
3970
    : public Dictionary<SeededNumberDictionaryShape, uint32_t> {
3971
 public:
3972
  static SeededNumberDictionary* cast(Object* obj) {
3973
    ASSERT(obj->IsDictionary());
3974
    return reinterpret_cast<SeededNumberDictionary*>(obj);
3975
  }
3976

    
3977
  // Type specific at put (default NONE attributes is used when adding).
3978
  MUST_USE_RESULT MaybeObject* AtNumberPut(uint32_t key, Object* value);
3979
  MUST_USE_RESULT MaybeObject* AddNumberEntry(uint32_t key,
3980
                                              Object* value,
3981
                                              PropertyDetails details);
3982

    
3983
  // Set an existing entry or add a new one if needed.
3984
  // Return the updated dictionary.
3985
  MUST_USE_RESULT static Handle<SeededNumberDictionary> Set(
3986
      Handle<SeededNumberDictionary> dictionary,
3987
      uint32_t index,
3988
      Handle<Object> value,
3989
      PropertyDetails details);
3990

    
3991
  MUST_USE_RESULT MaybeObject* Set(uint32_t key,
3992
                                   Object* value,
3993
                                   PropertyDetails details);
3994

    
3995
  void UpdateMaxNumberKey(uint32_t key);
3996

    
3997
  // If slow elements are required we will never go back to fast-case
3998
  // for the elements kept in this dictionary.  We require slow
3999
  // elements if an element has been added at an index larger than
4000
  // kRequiresSlowElementsLimit or set_requires_slow_elements() has been called
4001
  // when defining a getter or setter with a number key.
4002
  inline bool requires_slow_elements();
4003
  inline void set_requires_slow_elements();
4004

    
4005
  // Get the value of the max number key that has been added to this
4006
  // dictionary.  max_number_key can only be called if
4007
  // requires_slow_elements returns false.
4008
  inline uint32_t max_number_key();
4009

    
4010
  // Bit masks.
4011
  static const int kRequiresSlowElementsMask = 1;
4012
  static const int kRequiresSlowElementsTagSize = 1;
4013
  static const uint32_t kRequiresSlowElementsLimit = (1 << 29) - 1;
4014
};
4015

    
4016

    
4017
class UnseededNumberDictionary
4018
    : public Dictionary<UnseededNumberDictionaryShape, uint32_t> {
4019
 public:
4020
  static UnseededNumberDictionary* cast(Object* obj) {
4021
    ASSERT(obj->IsDictionary());
4022
    return reinterpret_cast<UnseededNumberDictionary*>(obj);
4023
  }
4024

    
4025
  // Type specific at put (default NONE attributes is used when adding).
4026
  MUST_USE_RESULT MaybeObject* AtNumberPut(uint32_t key, Object* value);
4027
  MUST_USE_RESULT MaybeObject* AddNumberEntry(uint32_t key, Object* value);
4028

    
4029
  // Set an existing entry or add a new one if needed.
4030
  // Return the updated dictionary.
4031
  MUST_USE_RESULT static Handle<UnseededNumberDictionary> Set(
4032
      Handle<UnseededNumberDictionary> dictionary,
4033
      uint32_t index,
4034
      Handle<Object> value);
4035

    
4036
  MUST_USE_RESULT MaybeObject* Set(uint32_t key, Object* value);
4037
};
4038

    
4039

    
4040
template <int entrysize>
4041
class ObjectHashTableShape : public BaseShape<Object*> {
4042
 public:
4043
  static inline bool IsMatch(Object* key, Object* other);
4044
  static inline uint32_t Hash(Object* key);
4045
  static inline uint32_t HashForObject(Object* key, Object* object);
4046
  MUST_USE_RESULT static inline MaybeObject* AsObject(Heap* heap,
4047
                                                      Object* key);
4048
  static const int kPrefixSize = 0;
4049
  static const int kEntrySize = entrysize;
4050
};
4051

    
4052

    
4053
// ObjectHashSet holds keys that are arbitrary objects by using the identity
4054
// hash of the key for hashing purposes.
4055
class ObjectHashSet: public HashTable<ObjectHashTableShape<1>, Object*> {
4056
 public:
4057
  static inline ObjectHashSet* cast(Object* obj) {
4058
    ASSERT(obj->IsHashTable());
4059
    return reinterpret_cast<ObjectHashSet*>(obj);
4060
  }
4061

    
4062
  // Looks up whether the given key is part of this hash set.
4063
  bool Contains(Object* key);
4064

    
4065
  // Adds the given key to this hash set.
4066
  MUST_USE_RESULT MaybeObject* Add(Object* key);
4067

    
4068
  // Removes the given key from this hash set.
4069
  MUST_USE_RESULT MaybeObject* Remove(Object* key);
4070
};
4071

    
4072

    
4073
// ObjectHashTable maps keys that are arbitrary objects to object values by
4074
// using the identity hash of the key for hashing purposes.
4075
class ObjectHashTable: public HashTable<ObjectHashTableShape<2>, Object*> {
4076
 public:
4077
  static inline ObjectHashTable* cast(Object* obj) {
4078
    ASSERT(obj->IsHashTable());
4079
    return reinterpret_cast<ObjectHashTable*>(obj);
4080
  }
4081

    
4082
  // Looks up the value associated with the given key. The hole value is
4083
  // returned in case the key is not present.
4084
  Object* Lookup(Object* key);
4085

    
4086
  // Adds (or overwrites) the value associated with the given key. Mapping a
4087
  // key to the hole value causes removal of the whole entry.
4088
  MUST_USE_RESULT MaybeObject* Put(Object* key, Object* value);
4089

    
4090
 private:
4091
  friend class MarkCompactCollector;
4092

    
4093
  void AddEntry(int entry, Object* key, Object* value);
4094
  void RemoveEntry(int entry);
4095

    
4096
  // Returns the index to the value of an entry.
4097
  static inline int EntryToValueIndex(int entry) {
4098
    return EntryToIndex(entry) + 1;
4099
  }
4100
};
4101

    
4102

    
4103
template <int entrysize>
4104
class WeakHashTableShape : public BaseShape<Object*> {
4105
 public:
4106
  static inline bool IsMatch(Object* key, Object* other);
4107
  static inline uint32_t Hash(Object* key);
4108
  static inline uint32_t HashForObject(Object* key, Object* object);
4109
  MUST_USE_RESULT static inline MaybeObject* AsObject(Heap* heap,
4110
                                                      Object* key);
4111
  static const int kPrefixSize = 0;
4112
  static const int kEntrySize = entrysize;
4113
};
4114

    
4115

    
4116
// WeakHashTable maps keys that are arbitrary objects to object values.
4117
// It is used for the global weak hash table that maps objects
4118
// embedded in optimized code to dependent code lists.
4119
class WeakHashTable: public HashTable<WeakHashTableShape<2>, Object*> {
4120
 public:
4121
  static inline WeakHashTable* cast(Object* obj) {
4122
    ASSERT(obj->IsHashTable());
4123
    return reinterpret_cast<WeakHashTable*>(obj);
4124
  }
4125

    
4126
  // Looks up the value associated with the given key. The hole value is
4127
  // returned in case the key is not present.
4128
  Object* Lookup(Object* key);
4129

    
4130
  // Adds (or overwrites) the value associated with the given key. Mapping a
4131
  // key to the hole value causes removal of the whole entry.
4132
  MUST_USE_RESULT MaybeObject* Put(Object* key, Object* value);
4133

    
4134
  // This function is called when heap verification is turned on.
4135
  void Zap(Object* value) {
4136
    int capacity = Capacity();
4137
    for (int i = 0; i < capacity; i++) {
4138
      set(EntryToIndex(i), value);
4139
      set(EntryToValueIndex(i), value);
4140
    }
4141
  }
4142

    
4143
 private:
4144
  friend class MarkCompactCollector;
4145

    
4146
  void AddEntry(int entry, Object* key, Object* value);
4147

    
4148
  // Returns the index to the value of an entry.
4149
  static inline int EntryToValueIndex(int entry) {
4150
    return EntryToIndex(entry) + 1;
4151
  }
4152
};
4153

    
4154

    
4155
// JSFunctionResultCache caches results of some JSFunction invocation.
4156
// It is a fixed array with fixed structure:
4157
//   [0]: factory function
4158
//   [1]: finger index
4159
//   [2]: current cache size
4160
//   [3]: dummy field.
4161
// The rest of array are key/value pairs.
4162
class JSFunctionResultCache: public FixedArray {
4163
 public:
4164
  static const int kFactoryIndex = 0;
4165
  static const int kFingerIndex = kFactoryIndex + 1;
4166
  static const int kCacheSizeIndex = kFingerIndex + 1;
4167
  static const int kDummyIndex = kCacheSizeIndex + 1;
4168
  static const int kEntriesIndex = kDummyIndex + 1;
4169

    
4170
  static const int kEntrySize = 2;  // key + value
4171

    
4172
  static const int kFactoryOffset = kHeaderSize;
4173
  static const int kFingerOffset = kFactoryOffset + kPointerSize;
4174
  static const int kCacheSizeOffset = kFingerOffset + kPointerSize;
4175

    
4176
  inline void MakeZeroSize();
4177
  inline void Clear();
4178

    
4179
  inline int size();
4180
  inline void set_size(int size);
4181
  inline int finger_index();
4182
  inline void set_finger_index(int finger_index);
4183

    
4184
  // Casting
4185
  static inline JSFunctionResultCache* cast(Object* obj);
4186

    
4187
  DECLARE_VERIFIER(JSFunctionResultCache)
4188
};
4189

    
4190

    
4191
// ScopeInfo represents information about different scopes of a source
4192
// program  and the allocation of the scope's variables. Scope information
4193
// is stored in a compressed form in ScopeInfo objects and is used
4194
// at runtime (stack dumps, deoptimization, etc.).
4195

    
4196
// This object provides quick access to scope info details for runtime
4197
// routines.
4198
class ScopeInfo : public FixedArray {
4199
 public:
4200
  static inline ScopeInfo* cast(Object* object);
4201

    
4202
  // Return the type of this scope.
4203
  ScopeType scope_type();
4204

    
4205
  // Does this scope call eval?
4206
  bool CallsEval();
4207

    
4208
  // Return the language mode of this scope.
4209
  LanguageMode language_mode();
4210

    
4211
  // Does this scope make a non-strict eval call?
4212
  bool CallsNonStrictEval() {
4213
    return CallsEval() && (language_mode() == CLASSIC_MODE);
4214
  }
4215

    
4216
  // Return the total number of locals allocated on the stack and in the
4217
  // context. This includes the parameters that are allocated in the context.
4218
  int LocalCount();
4219

    
4220
  // Return the number of stack slots for code. This number consists of two
4221
  // parts:
4222
  //  1. One stack slot per stack allocated local.
4223
  //  2. One stack slot for the function name if it is stack allocated.
4224
  int StackSlotCount();
4225

    
4226
  // Return the number of context slots for code if a context is allocated. This
4227
  // number consists of three parts:
4228
  //  1. Size of fixed header for every context: Context::MIN_CONTEXT_SLOTS
4229
  //  2. One context slot per context allocated local.
4230
  //  3. One context slot for the function name if it is context allocated.
4231
  // Parameters allocated in the context count as context allocated locals. If
4232
  // no contexts are allocated for this scope ContextLength returns 0.
4233
  int ContextLength();
4234

    
4235
  // Is this scope the scope of a named function expression?
4236
  bool HasFunctionName();
4237

    
4238
  // Return if this has context allocated locals.
4239
  bool HasHeapAllocatedLocals();
4240

    
4241
  // Return if contexts are allocated for this scope.
4242
  bool HasContext();
4243

    
4244
  // Return the function_name if present.
4245
  String* FunctionName();
4246

    
4247
  // Return the name of the given parameter.
4248
  String* ParameterName(int var);
4249

    
4250
  // Return the name of the given local.
4251
  String* LocalName(int var);
4252

    
4253
  // Return the name of the given stack local.
4254
  String* StackLocalName(int var);
4255

    
4256
  // Return the name of the given context local.
4257
  String* ContextLocalName(int var);
4258

    
4259
  // Return the mode of the given context local.
4260
  VariableMode ContextLocalMode(int var);
4261

    
4262
  // Return the initialization flag of the given context local.
4263
  InitializationFlag ContextLocalInitFlag(int var);
4264

    
4265
  // Lookup support for serialized scope info. Returns the
4266
  // the stack slot index for a given slot name if the slot is
4267
  // present; otherwise returns a value < 0. The name must be an internalized
4268
  // string.
4269
  int StackSlotIndex(String* name);
4270

    
4271
  // Lookup support for serialized scope info. Returns the
4272
  // context slot index for a given slot name if the slot is present; otherwise
4273
  // returns a value < 0. The name must be an internalized string.
4274
  // If the slot is present and mode != NULL, sets *mode to the corresponding
4275
  // mode for that variable.
4276
  int ContextSlotIndex(String* name,
4277
                       VariableMode* mode,
4278
                       InitializationFlag* init_flag);
4279

    
4280
  // Lookup support for serialized scope info. Returns the
4281
  // parameter index for a given parameter name if the parameter is present;
4282
  // otherwise returns a value < 0. The name must be an internalized string.
4283
  int ParameterIndex(String* name);
4284

    
4285
  // Lookup support for serialized scope info. Returns the function context
4286
  // slot index if the function name is present and context-allocated (named
4287
  // function expressions, only), otherwise returns a value < 0. The name
4288
  // must be an internalized string.
4289
  int FunctionContextSlotIndex(String* name, VariableMode* mode);
4290

    
4291

    
4292
  // Copies all the context locals into an object used to materialize a scope.
4293
  static bool CopyContextLocalsToScopeObject(Handle<ScopeInfo> scope_info,
4294
                                             Handle<Context> context,
4295
                                             Handle<JSObject> scope_object);
4296

    
4297

    
4298
  static Handle<ScopeInfo> Create(Scope* scope, Zone* zone);
4299

    
4300
  // Serializes empty scope info.
4301
  static ScopeInfo* Empty(Isolate* isolate);
4302

    
4303
#ifdef DEBUG
4304
  void Print();
4305
#endif
4306

    
4307
  // The layout of the static part of a ScopeInfo is as follows. Each entry is
4308
  // numeric and occupies one array slot.
4309
  // 1. A set of properties of the scope
4310
  // 2. The number of parameters. This only applies to function scopes. For
4311
  //    non-function scopes this is 0.
4312
  // 3. The number of non-parameter variables allocated on the stack.
4313
  // 4. The number of non-parameter and parameter variables allocated in the
4314
  //    context.
4315
#define FOR_EACH_NUMERIC_FIELD(V)          \
4316
  V(Flags)                                 \
4317
  V(ParameterCount)                        \
4318
  V(StackLocalCount)                       \
4319
  V(ContextLocalCount)
4320

    
4321
#define FIELD_ACCESSORS(name)                            \
4322
  void Set##name(int value) {                            \
4323
    set(k##name, Smi::FromInt(value));                   \
4324
  }                                                      \
4325
  int name() {                                           \
4326
    if (length() > 0) {                                  \
4327
      return Smi::cast(get(k##name))->value();           \
4328
    } else {                                             \
4329
      return 0;                                          \
4330
    }                                                    \
4331
  }
4332
  FOR_EACH_NUMERIC_FIELD(FIELD_ACCESSORS)
4333
#undef FIELD_ACCESSORS
4334

    
4335
 private:
4336
  enum {
4337
#define DECL_INDEX(name) k##name,
4338
  FOR_EACH_NUMERIC_FIELD(DECL_INDEX)
4339
#undef DECL_INDEX
4340
#undef FOR_EACH_NUMERIC_FIELD
4341
    kVariablePartIndex
4342
  };
4343

    
4344
  // The layout of the variable part of a ScopeInfo is as follows:
4345
  // 1. ParameterEntries:
4346
  //    This part stores the names of the parameters for function scopes. One
4347
  //    slot is used per parameter, so in total this part occupies
4348
  //    ParameterCount() slots in the array. For other scopes than function
4349
  //    scopes ParameterCount() is 0.
4350
  // 2. StackLocalEntries:
4351
  //    Contains the names of local variables that are allocated on the stack,
4352
  //    in increasing order of the stack slot index. One slot is used per stack
4353
  //    local, so in total this part occupies StackLocalCount() slots in the
4354
  //    array.
4355
  // 3. ContextLocalNameEntries:
4356
  //    Contains the names of local variables and parameters that are allocated
4357
  //    in the context. They are stored in increasing order of the context slot
4358
  //    index starting with Context::MIN_CONTEXT_SLOTS. One slot is used per
4359
  //    context local, so in total this part occupies ContextLocalCount() slots
4360
  //    in the array.
4361
  // 4. ContextLocalInfoEntries:
4362
  //    Contains the variable modes and initialization flags corresponding to
4363
  //    the context locals in ContextLocalNameEntries. One slot is used per
4364
  //    context local, so in total this part occupies ContextLocalCount()
4365
  //    slots in the array.
4366
  // 5. FunctionNameEntryIndex:
4367
  //    If the scope belongs to a named function expression this part contains
4368
  //    information about the function variable. It always occupies two array
4369
  //    slots:  a. The name of the function variable.
4370
  //            b. The context or stack slot index for the variable.
4371
  int ParameterEntriesIndex();
4372
  int StackLocalEntriesIndex();
4373
  int ContextLocalNameEntriesIndex();
4374
  int ContextLocalInfoEntriesIndex();
4375
  int FunctionNameEntryIndex();
4376

    
4377
  // Location of the function variable for named function expressions.
4378
  enum FunctionVariableInfo {
4379
    NONE,     // No function name present.
4380
    STACK,    // Function
4381
    CONTEXT,
4382
    UNUSED
4383
  };
4384

    
4385
  // Properties of scopes.
4386
  class ScopeTypeField:        public BitField<ScopeType,            0, 3> {};
4387
  class CallsEvalField:        public BitField<bool,                 3, 1> {};
4388
  class LanguageModeField:     public BitField<LanguageMode,         4, 2> {};
4389
  class FunctionVariableField: public BitField<FunctionVariableInfo, 6, 2> {};
4390
  class FunctionVariableMode:  public BitField<VariableMode,         8, 3> {};
4391

    
4392
  // BitFields representing the encoded information for context locals in the
4393
  // ContextLocalInfoEntries part.
4394
  class ContextLocalMode:      public BitField<VariableMode,         0, 3> {};
4395
  class ContextLocalInitFlag:  public BitField<InitializationFlag,   3, 1> {};
4396
};
4397

    
4398

    
4399
// The cache for maps used by normalized (dictionary mode) objects.
4400
// Such maps do not have property descriptors, so a typical program
4401
// needs very limited number of distinct normalized maps.
4402
class NormalizedMapCache: public FixedArray {
4403
 public:
4404
  static const int kEntries = 64;
4405

    
4406
  static Handle<Map> Get(Handle<NormalizedMapCache> cache,
4407
                         Handle<JSObject> object,
4408
                         PropertyNormalizationMode mode);
4409

    
4410
  void Clear();
4411

    
4412
  // Casting
4413
  static inline NormalizedMapCache* cast(Object* obj);
4414

    
4415
  DECLARE_VERIFIER(NormalizedMapCache)
4416
};
4417

    
4418

    
4419
// ByteArray represents fixed sized byte arrays.  Used for the relocation info
4420
// that is attached to code objects.
4421
class ByteArray: public FixedArrayBase {
4422
 public:
4423
  inline int Size() { return RoundUp(length() + kHeaderSize, kPointerSize); }
4424

    
4425
  // Setter and getter.
4426
  inline byte get(int index);
4427
  inline void set(int index, byte value);
4428

    
4429
  // Treat contents as an int array.
4430
  inline int get_int(int index);
4431

    
4432
  static int SizeFor(int length) {
4433
    return OBJECT_POINTER_ALIGN(kHeaderSize + length);
4434
  }
4435
  // We use byte arrays for free blocks in the heap.  Given a desired size in
4436
  // bytes that is a multiple of the word size and big enough to hold a byte
4437
  // array, this function returns the number of elements a byte array should
4438
  // have.
4439
  static int LengthFor(int size_in_bytes) {
4440
    ASSERT(IsAligned(size_in_bytes, kPointerSize));
4441
    ASSERT(size_in_bytes >= kHeaderSize);
4442
    return size_in_bytes - kHeaderSize;
4443
  }
4444

    
4445
  // Returns data start address.
4446
  inline Address GetDataStartAddress();
4447

    
4448
  // Returns a pointer to the ByteArray object for a given data start address.
4449
  static inline ByteArray* FromDataStartAddress(Address address);
4450

    
4451
  // Casting.
4452
  static inline ByteArray* cast(Object* obj);
4453

    
4454
  // Dispatched behavior.
4455
  inline int ByteArraySize() {
4456
    return SizeFor(this->length());
4457
  }
4458
  DECLARE_PRINTER(ByteArray)
4459
  DECLARE_VERIFIER(ByteArray)
4460

    
4461
  // Layout description.
4462
  static const int kAlignedSize = OBJECT_POINTER_ALIGN(kHeaderSize);
4463

    
4464
  // Maximal memory consumption for a single ByteArray.
4465
  static const int kMaxSize = 512 * MB;
4466
  // Maximal length of a single ByteArray.
4467
  static const int kMaxLength = kMaxSize - kHeaderSize;
4468

    
4469
 private:
4470
  DISALLOW_IMPLICIT_CONSTRUCTORS(ByteArray);
4471
};
4472

    
4473

    
4474
// FreeSpace represents fixed sized areas of the heap that are not currently in
4475
// use.  Used by the heap and GC.
4476
class FreeSpace: public HeapObject {
4477
 public:
4478
  // [size]: size of the free space including the header.
4479
  inline int size();
4480
  inline void set_size(int value);
4481

    
4482
  inline int Size() { return size(); }
4483

    
4484
  // Casting.
4485
  static inline FreeSpace* cast(Object* obj);
4486

    
4487
  // Dispatched behavior.
4488
  DECLARE_PRINTER(FreeSpace)
4489
  DECLARE_VERIFIER(FreeSpace)
4490

    
4491
  // Layout description.
4492
  // Size is smi tagged when it is stored.
4493
  static const int kSizeOffset = HeapObject::kHeaderSize;
4494
  static const int kHeaderSize = kSizeOffset + kPointerSize;
4495

    
4496
  static const int kAlignedSize = OBJECT_POINTER_ALIGN(kHeaderSize);
4497

    
4498
 private:
4499
  DISALLOW_IMPLICIT_CONSTRUCTORS(FreeSpace);
4500
};
4501

    
4502

    
4503
// An ExternalArray represents a fixed-size array of primitive values
4504
// which live outside the JavaScript heap. Its subclasses are used to
4505
// implement the CanvasArray types being defined in the WebGL
4506
// specification. As of this writing the first public draft is not yet
4507
// available, but Khronos members can access the draft at:
4508
//   https://cvs.khronos.org/svn/repos/3dweb/trunk/doc/spec/WebGL-spec.html
4509
//
4510
// The semantics of these arrays differ from CanvasPixelArray.
4511
// Out-of-range values passed to the setter are converted via a C
4512
// cast, not clamping. Out-of-range indices cause exceptions to be
4513
// raised rather than being silently ignored.
4514
class ExternalArray: public FixedArrayBase {
4515
 public:
4516
  inline bool is_the_hole(int index) { return false; }
4517

    
4518
  // [external_pointer]: The pointer to the external memory area backing this
4519
  // external array.
4520
  DECL_ACCESSORS(external_pointer, void)  // Pointer to the data store.
4521

    
4522
  // Casting.
4523
  static inline ExternalArray* cast(Object* obj);
4524

    
4525
  // Maximal acceptable length for an external array.
4526
  static const int kMaxLength = 0x3fffffff;
4527

    
4528
  // ExternalArray headers are not quadword aligned.
4529
  static const int kExternalPointerOffset =
4530
      POINTER_SIZE_ALIGN(FixedArrayBase::kLengthOffset + kPointerSize);
4531
  static const int kHeaderSize = kExternalPointerOffset + kPointerSize;
4532
  static const int kAlignedSize = OBJECT_POINTER_ALIGN(kHeaderSize);
4533

    
4534
 private:
4535
  DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalArray);
4536
};
4537

    
4538

    
4539
// A ExternalPixelArray represents a fixed-size byte array with special
4540
// semantics used for implementing the CanvasPixelArray object. Please see the
4541
// specification at:
4542

    
4543
// http://www.whatwg.org/specs/web-apps/current-work/
4544
//                      multipage/the-canvas-element.html#canvaspixelarray
4545
// In particular, write access clamps the value written to 0 or 255 if the
4546
// value written is outside this range.
4547
class ExternalPixelArray: public ExternalArray {
4548
 public:
4549
  inline uint8_t* external_pixel_pointer();
4550

    
4551
  // Setter and getter.
4552
  inline uint8_t get_scalar(int index);
4553
  MUST_USE_RESULT inline MaybeObject* get(int index);
4554
  inline void set(int index, uint8_t value);
4555

    
4556
  // This accessor applies the correct conversion from Smi, HeapNumber and
4557
  // undefined and clamps the converted value between 0 and 255.
4558
  Object* SetValue(uint32_t index, Object* value);
4559

    
4560
  // Casting.
4561
  static inline ExternalPixelArray* cast(Object* obj);
4562

    
4563
  // Dispatched behavior.
4564
  DECLARE_PRINTER(ExternalPixelArray)
4565
  DECLARE_VERIFIER(ExternalPixelArray)
4566

    
4567
 private:
4568
  DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalPixelArray);
4569
};
4570

    
4571

    
4572
class ExternalByteArray: public ExternalArray {
4573
 public:
4574
  // Setter and getter.
4575
  inline int8_t get_scalar(int index);
4576
  MUST_USE_RESULT inline MaybeObject* get(int index);
4577
  inline void set(int index, int8_t value);
4578

    
4579
  // This accessor applies the correct conversion from Smi, HeapNumber
4580
  // and undefined.
4581
  MUST_USE_RESULT MaybeObject* SetValue(uint32_t index, Object* value);
4582

    
4583
  // Casting.
4584
  static inline ExternalByteArray* cast(Object* obj);
4585

    
4586
  // Dispatched behavior.
4587
  DECLARE_PRINTER(ExternalByteArray)
4588
  DECLARE_VERIFIER(ExternalByteArray)
4589

    
4590
 private:
4591
  DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalByteArray);
4592
};
4593

    
4594

    
4595
class ExternalUnsignedByteArray: public ExternalArray {
4596
 public:
4597
  // Setter and getter.
4598
  inline uint8_t get_scalar(int index);
4599
  MUST_USE_RESULT inline MaybeObject* get(int index);
4600
  inline void set(int index, uint8_t value);
4601

    
4602
  // This accessor applies the correct conversion from Smi, HeapNumber
4603
  // and undefined.
4604
  MUST_USE_RESULT MaybeObject* SetValue(uint32_t index, Object* value);
4605

    
4606
  // Casting.
4607
  static inline ExternalUnsignedByteArray* cast(Object* obj);
4608

    
4609
  // Dispatched behavior.
4610
  DECLARE_PRINTER(ExternalUnsignedByteArray)
4611
  DECLARE_VERIFIER(ExternalUnsignedByteArray)
4612

    
4613
 private:
4614
  DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalUnsignedByteArray);
4615
};
4616

    
4617

    
4618
class ExternalShortArray: public ExternalArray {
4619
 public:
4620
  // Setter and getter.
4621
  inline int16_t get_scalar(int index);
4622
  MUST_USE_RESULT inline MaybeObject* get(int index);
4623
  inline void set(int index, int16_t value);
4624

    
4625
  // This accessor applies the correct conversion from Smi, HeapNumber
4626
  // and undefined.
4627
  MUST_USE_RESULT MaybeObject* SetValue(uint32_t index, Object* value);
4628

    
4629
  // Casting.
4630
  static inline ExternalShortArray* cast(Object* obj);
4631

    
4632
  // Dispatched behavior.
4633
  DECLARE_PRINTER(ExternalShortArray)
4634
  DECLARE_VERIFIER(ExternalShortArray)
4635

    
4636
 private:
4637
  DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalShortArray);
4638
};
4639

    
4640

    
4641
class ExternalUnsignedShortArray: public ExternalArray {
4642
 public:
4643
  // Setter and getter.
4644
  inline uint16_t get_scalar(int index);
4645
  MUST_USE_RESULT inline MaybeObject* get(int index);
4646
  inline void set(int index, uint16_t value);
4647

    
4648
  // This accessor applies the correct conversion from Smi, HeapNumber
4649
  // and undefined.
4650
  MUST_USE_RESULT MaybeObject* SetValue(uint32_t index, Object* value);
4651

    
4652
  // Casting.
4653
  static inline ExternalUnsignedShortArray* cast(Object* obj);
4654

    
4655
  // Dispatched behavior.
4656
  DECLARE_PRINTER(ExternalUnsignedShortArray)
4657
  DECLARE_VERIFIER(ExternalUnsignedShortArray)
4658

    
4659
 private:
4660
  DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalUnsignedShortArray);
4661
};
4662

    
4663

    
4664
class ExternalIntArray: public ExternalArray {
4665
 public:
4666
  // Setter and getter.
4667
  inline int32_t get_scalar(int index);
4668
  MUST_USE_RESULT inline MaybeObject* get(int index);
4669
  inline void set(int index, int32_t value);
4670

    
4671
  // This accessor applies the correct conversion from Smi, HeapNumber
4672
  // and undefined.
4673
  MUST_USE_RESULT MaybeObject* SetValue(uint32_t index, Object* value);
4674

    
4675
  // Casting.
4676
  static inline ExternalIntArray* cast(Object* obj);
4677

    
4678
  // Dispatched behavior.
4679
  DECLARE_PRINTER(ExternalIntArray)
4680
  DECLARE_VERIFIER(ExternalIntArray)
4681

    
4682
 private:
4683
  DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalIntArray);
4684
};
4685

    
4686

    
4687
class ExternalUnsignedIntArray: public ExternalArray {
4688
 public:
4689
  // Setter and getter.
4690
  inline uint32_t get_scalar(int index);
4691
  MUST_USE_RESULT inline MaybeObject* get(int index);
4692
  inline void set(int index, uint32_t value);
4693

    
4694
  // This accessor applies the correct conversion from Smi, HeapNumber
4695
  // and undefined.
4696
  MUST_USE_RESULT MaybeObject* SetValue(uint32_t index, Object* value);
4697

    
4698
  // Casting.
4699
  static inline ExternalUnsignedIntArray* cast(Object* obj);
4700

    
4701
  // Dispatched behavior.
4702
  DECLARE_PRINTER(ExternalUnsignedIntArray)
4703
  DECLARE_VERIFIER(ExternalUnsignedIntArray)
4704

    
4705
 private:
4706
  DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalUnsignedIntArray);
4707
};
4708

    
4709

    
4710
class ExternalFloatArray: public ExternalArray {
4711
 public:
4712
  // Setter and getter.
4713
  inline float get_scalar(int index);
4714
  MUST_USE_RESULT inline MaybeObject* get(int index);
4715
  inline void set(int index, float value);
4716

    
4717
  // This accessor applies the correct conversion from Smi, HeapNumber
4718
  // and undefined.
4719
  MUST_USE_RESULT MaybeObject* SetValue(uint32_t index, Object* value);
4720

    
4721
  // Casting.
4722
  static inline ExternalFloatArray* cast(Object* obj);
4723

    
4724
  // Dispatched behavior.
4725
  DECLARE_PRINTER(ExternalFloatArray)
4726
  DECLARE_VERIFIER(ExternalFloatArray)
4727

    
4728
 private:
4729
  DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalFloatArray);
4730
};
4731

    
4732

    
4733
class ExternalDoubleArray: public ExternalArray {
4734
 public:
4735
  // Setter and getter.
4736
  inline double get_scalar(int index);
4737
  MUST_USE_RESULT inline MaybeObject* get(int index);
4738
  inline void set(int index, double value);
4739

    
4740
  // This accessor applies the correct conversion from Smi, HeapNumber
4741
  // and undefined.
4742
  MUST_USE_RESULT MaybeObject* SetValue(uint32_t index, Object* value);
4743

    
4744
  // Casting.
4745
  static inline ExternalDoubleArray* cast(Object* obj);
4746

    
4747
  // Dispatched behavior.
4748
  DECLARE_PRINTER(ExternalDoubleArray)
4749
  DECLARE_VERIFIER(ExternalDoubleArray)
4750

    
4751
 private:
4752
  DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalDoubleArray);
4753
};
4754

    
4755

    
4756
// DeoptimizationInputData is a fixed array used to hold the deoptimization
4757
// data for code generated by the Hydrogen/Lithium compiler.  It also
4758
// contains information about functions that were inlined.  If N different
4759
// functions were inlined then first N elements of the literal array will
4760
// contain these functions.
4761
//
4762
// It can be empty.
4763
class DeoptimizationInputData: public FixedArray {
4764
 public:
4765
  // Layout description.  Indices in the array.
4766
  static const int kTranslationByteArrayIndex = 0;
4767
  static const int kInlinedFunctionCountIndex = 1;
4768
  static const int kLiteralArrayIndex = 2;
4769
  static const int kOsrAstIdIndex = 3;
4770
  static const int kOsrPcOffsetIndex = 4;
4771
  static const int kFirstDeoptEntryIndex = 5;
4772

    
4773
  // Offsets of deopt entry elements relative to the start of the entry.
4774
  static const int kAstIdRawOffset = 0;
4775
  static const int kTranslationIndexOffset = 1;
4776
  static const int kArgumentsStackHeightOffset = 2;
4777
  static const int kPcOffset = 3;
4778
  static const int kDeoptEntrySize = 4;
4779

    
4780
  // Simple element accessors.
4781
#define DEFINE_ELEMENT_ACCESSORS(name, type)      \
4782
  type* name() {                                  \
4783
    return type::cast(get(k##name##Index));       \
4784
  }                                               \
4785
  void Set##name(type* value) {                   \
4786
    set(k##name##Index, value);                   \
4787
  }
4788

    
4789
  DEFINE_ELEMENT_ACCESSORS(TranslationByteArray, ByteArray)
4790
  DEFINE_ELEMENT_ACCESSORS(InlinedFunctionCount, Smi)
4791
  DEFINE_ELEMENT_ACCESSORS(LiteralArray, FixedArray)
4792
  DEFINE_ELEMENT_ACCESSORS(OsrAstId, Smi)
4793
  DEFINE_ELEMENT_ACCESSORS(OsrPcOffset, Smi)
4794

    
4795
#undef DEFINE_ELEMENT_ACCESSORS
4796

    
4797
  // Accessors for elements of the ith deoptimization entry.
4798
#define DEFINE_ENTRY_ACCESSORS(name, type)                       \
4799
  type* name(int i) {                                            \
4800
    return type::cast(get(IndexForEntry(i) + k##name##Offset));  \
4801
  }                                                              \
4802
  void Set##name(int i, type* value) {                           \
4803
    set(IndexForEntry(i) + k##name##Offset, value);              \
4804
  }
4805

    
4806
  DEFINE_ENTRY_ACCESSORS(AstIdRaw, Smi)
4807
  DEFINE_ENTRY_ACCESSORS(TranslationIndex, Smi)
4808
  DEFINE_ENTRY_ACCESSORS(ArgumentsStackHeight, Smi)
4809
  DEFINE_ENTRY_ACCESSORS(Pc, Smi)
4810

    
4811
#undef DEFINE_ENTRY_ACCESSORS
4812

    
4813
  BailoutId AstId(int i) {
4814
    return BailoutId(AstIdRaw(i)->value());
4815
  }
4816

    
4817
  void SetAstId(int i, BailoutId value) {
4818
    SetAstIdRaw(i, Smi::FromInt(value.ToInt()));
4819
  }
4820

    
4821
  int DeoptCount() {
4822
    return (length() - kFirstDeoptEntryIndex) / kDeoptEntrySize;
4823
  }
4824

    
4825
  // Allocates a DeoptimizationInputData.
4826
  MUST_USE_RESULT static MaybeObject* Allocate(Isolate* isolate,
4827
                                               int deopt_entry_count,
4828
                                               PretenureFlag pretenure);
4829

    
4830
  // Casting.
4831
  static inline DeoptimizationInputData* cast(Object* obj);
4832

    
4833
#ifdef ENABLE_DISASSEMBLER
4834
  void DeoptimizationInputDataPrint(FILE* out);
4835
#endif
4836

    
4837
 private:
4838
  static int IndexForEntry(int i) {
4839
    return kFirstDeoptEntryIndex + (i * kDeoptEntrySize);
4840
  }
4841

    
4842
  static int LengthFor(int entry_count) {
4843
    return IndexForEntry(entry_count);
4844
  }
4845
};
4846

    
4847

    
4848
// DeoptimizationOutputData is a fixed array used to hold the deoptimization
4849
// data for code generated by the full compiler.
4850
// The format of the these objects is
4851
//   [i * 2]: Ast ID for ith deoptimization.
4852
//   [i * 2 + 1]: PC and state of ith deoptimization
4853
class DeoptimizationOutputData: public FixedArray {
4854
 public:
4855
  int DeoptPoints() { return length() / 2; }
4856

    
4857
  BailoutId AstId(int index) {
4858
    return BailoutId(Smi::cast(get(index * 2))->value());
4859
  }
4860

    
4861
  void SetAstId(int index, BailoutId id) {
4862
    set(index * 2, Smi::FromInt(id.ToInt()));
4863
  }
4864

    
4865
  Smi* PcAndState(int index) { return Smi::cast(get(1 + index * 2)); }
4866
  void SetPcAndState(int index, Smi* offset) { set(1 + index * 2, offset); }
4867

    
4868
  static int LengthOfFixedArray(int deopt_points) {
4869
    return deopt_points * 2;
4870
  }
4871

    
4872
  // Allocates a DeoptimizationOutputData.
4873
  MUST_USE_RESULT static MaybeObject* Allocate(Isolate* isolate,
4874
                                               int number_of_deopt_points,
4875
                                               PretenureFlag pretenure);
4876

    
4877
  // Casting.
4878
  static inline DeoptimizationOutputData* cast(Object* obj);
4879

    
4880
#if defined(OBJECT_PRINT) || defined(ENABLE_DISASSEMBLER)
4881
  void DeoptimizationOutputDataPrint(FILE* out);
4882
#endif
4883
};
4884

    
4885

    
4886
// Forward declaration.
4887
class Cell;
4888
class PropertyCell;
4889

    
4890
// TypeFeedbackCells is a fixed array used to hold the association between
4891
// cache cells and AST ids for code generated by the full compiler.
4892
// The format of the these objects is
4893
//   [i * 2]: Global property cell of ith cache cell.
4894
//   [i * 2 + 1]: Ast ID for ith cache cell.
4895
class TypeFeedbackCells: public FixedArray {
4896
 public:
4897
  int CellCount() { return length() / 2; }
4898
  static int LengthOfFixedArray(int cell_count) { return cell_count * 2; }
4899

    
4900
  // Accessors for AST ids associated with cache values.
4901
  inline TypeFeedbackId AstId(int index);
4902
  inline void SetAstId(int index, TypeFeedbackId id);
4903

    
4904
  // Accessors for global property cells holding the cache values.
4905
  inline Cell* GetCell(int index);
4906
  inline void SetCell(int index, Cell* cell);
4907

    
4908
  // The object that indicates an uninitialized cache.
4909
  static inline Handle<Object> UninitializedSentinel(Isolate* isolate);
4910

    
4911
  // The object that indicates a megamorphic state.
4912
  static inline Handle<Object> MegamorphicSentinel(Isolate* isolate);
4913

    
4914
  // The object that indicates a monomorphic state of Array with
4915
  // ElementsKind
4916
  static inline Handle<Object> MonomorphicArraySentinel(Isolate* isolate,
4917
      ElementsKind elements_kind);
4918

    
4919
  // A raw version of the uninitialized sentinel that's safe to read during
4920
  // garbage collection (e.g., for patching the cache).
4921
  static inline Object* RawUninitializedSentinel(Heap* heap);
4922

    
4923
  // Casting.
4924
  static inline TypeFeedbackCells* cast(Object* obj);
4925

    
4926
  static const int kForInFastCaseMarker = 0;
4927
  static const int kForInSlowCaseMarker = 1;
4928
};
4929

    
4930

    
4931
// Forward declaration.
4932
class SafepointEntry;
4933
class TypeFeedbackInfo;
4934

    
4935
// Code describes objects with on-the-fly generated machine code.
4936
class Code: public HeapObject {
4937
 public:
4938
  // Opaque data type for encapsulating code flags like kind, inline
4939
  // cache state, and arguments count.
4940
  typedef uint32_t Flags;
4941

    
4942
#define NON_IC_KIND_LIST(V) \
4943
  V(FUNCTION)               \
4944
  V(OPTIMIZED_FUNCTION)     \
4945
  V(STUB)                   \
4946
  V(HANDLER)                \
4947
  V(BUILTIN)                \
4948
  V(REGEXP)
4949

    
4950
#define IC_KIND_LIST(V) \
4951
  V(LOAD_IC)            \
4952
  V(KEYED_LOAD_IC)      \
4953
  V(CALL_IC)            \
4954
  V(KEYED_CALL_IC)      \
4955
  V(STORE_IC)           \
4956
  V(KEYED_STORE_IC)     \
4957
  V(BINARY_OP_IC)       \
4958
  V(COMPARE_IC)         \
4959
  V(COMPARE_NIL_IC)     \
4960
  V(TO_BOOLEAN_IC)
4961

    
4962
#define CODE_KIND_LIST(V) \
4963
  NON_IC_KIND_LIST(V)     \
4964
  IC_KIND_LIST(V)
4965

    
4966
  enum Kind {
4967
#define DEFINE_CODE_KIND_ENUM(name) name,
4968
    CODE_KIND_LIST(DEFINE_CODE_KIND_ENUM)
4969
#undef DEFINE_CODE_KIND_ENUM
4970
    NUMBER_OF_KINDS
4971
  };
4972

    
4973
  // No more than 16 kinds. The value is currently encoded in four bits in
4974
  // Flags.
4975
  STATIC_ASSERT(NUMBER_OF_KINDS <= 16);
4976

    
4977
  static const char* Kind2String(Kind kind);
4978

    
4979
  // Types of stubs.
4980
  enum StubType {
4981
    NORMAL,
4982
    FIELD,
4983
    CONSTANT,
4984
    CALLBACKS,
4985
    INTERCEPTOR,
4986
    TRANSITION,
4987
    NONEXISTENT
4988
  };
4989

    
4990
  typedef int ExtraICState;
4991

    
4992
  static const ExtraICState kNoExtraICState = 0;
4993

    
4994
  static const int kPrologueOffsetNotSet = -1;
4995

    
4996
#ifdef ENABLE_DISASSEMBLER
4997
  // Printing
4998
  static const char* ICState2String(InlineCacheState state);
4999
  static const char* StubType2String(StubType type);
5000
  static void PrintExtraICState(FILE* out, Kind kind, ExtraICState extra);
5001
  void Disassemble(const char* name, FILE* out = stdout);
5002
#endif  // ENABLE_DISASSEMBLER
5003

    
5004
  // [instruction_size]: Size of the native instructions
5005
  inline int instruction_size();
5006
  inline void set_instruction_size(int value);
5007

    
5008
  // [relocation_info]: Code relocation information
5009
  DECL_ACCESSORS(relocation_info, ByteArray)
5010
  void InvalidateRelocation();
5011

    
5012
  // [handler_table]: Fixed array containing offsets of exception handlers.
5013
  DECL_ACCESSORS(handler_table, FixedArray)
5014

    
5015
  // [deoptimization_data]: Array containing data for deopt.
5016
  DECL_ACCESSORS(deoptimization_data, FixedArray)
5017

    
5018
  // [type_feedback_info]: This field stores various things, depending on the
5019
  // kind of the code object.
5020
  //   FUNCTION           => type feedback information.
5021
  //   STUB               => various things, e.g. a SMI
5022
  //   OPTIMIZED_FUNCTION => the next_code_link for optimized code list.
5023
  DECL_ACCESSORS(type_feedback_info, Object)
5024
  inline void InitializeTypeFeedbackInfoNoWriteBarrier(Object* value);
5025
  inline int stub_info();
5026
  inline void set_stub_info(int info);
5027

    
5028
  // [next_code_link]: Link for lists of optimized or deoptimized code.
5029
  // Note that storage for this field is overlapped with typefeedback_info.
5030
  DECL_ACCESSORS(next_code_link, Object)
5031

    
5032
  // [gc_metadata]: Field used to hold GC related metadata. The contents of this
5033
  // field does not have to be traced during garbage collection since
5034
  // it is only used by the garbage collector itself.
5035
  DECL_ACCESSORS(gc_metadata, Object)
5036

    
5037
  // [ic_age]: Inline caching age: the value of the Heap::global_ic_age
5038
  // at the moment when this object was created.
5039
  inline void set_ic_age(int count);
5040
  inline int ic_age();
5041

    
5042
  // [prologue_offset]: Offset of the function prologue, used for aging
5043
  // FUNCTIONs and OPTIMIZED_FUNCTIONs.
5044
  inline int prologue_offset();
5045
  inline void set_prologue_offset(int offset);
5046

    
5047
  // Unchecked accessors to be used during GC.
5048
  inline ByteArray* unchecked_relocation_info();
5049

    
5050
  inline int relocation_size();
5051

    
5052
  // [flags]: Various code flags.
5053
  inline Flags flags();
5054
  inline void set_flags(Flags flags);
5055

    
5056
  // [flags]: Access to specific code flags.
5057
  inline Kind kind();
5058
  inline Kind handler_kind() {
5059
    return static_cast<Kind>(arguments_count());
5060
  }
5061
  inline InlineCacheState ic_state();  // Only valid for IC stubs.
5062
  inline ExtraICState extra_ic_state();  // Only valid for IC stubs.
5063

    
5064
  inline ExtraICState extended_extra_ic_state();  // Only valid for
5065
                                                  // non-call IC stubs.
5066
  static bool needs_extended_extra_ic_state(Kind kind) {
5067
    // TODO(danno): This is a bit of a hack right now since there are still
5068
    // clients of this API that pass "extra" values in for argc. These clients
5069
    // should be retrofitted to used ExtendedExtraICState.
5070
    return kind == COMPARE_NIL_IC || kind == TO_BOOLEAN_IC ||
5071
           kind == BINARY_OP_IC;
5072
  }
5073

    
5074
  inline StubType type();  // Only valid for monomorphic IC stubs.
5075
  inline int arguments_count();  // Only valid for call IC stubs.
5076

    
5077
  // Testers for IC stub kinds.
5078
  inline bool is_inline_cache_stub();
5079
  inline bool is_debug_stub();
5080
  inline bool is_handler() { return kind() == HANDLER; }
5081
  inline bool is_load_stub() { return kind() == LOAD_IC; }
5082
  inline bool is_keyed_load_stub() { return kind() == KEYED_LOAD_IC; }
5083
  inline bool is_store_stub() { return kind() == STORE_IC; }
5084
  inline bool is_keyed_store_stub() { return kind() == KEYED_STORE_IC; }
5085
  inline bool is_call_stub() { return kind() == CALL_IC; }
5086
  inline bool is_keyed_call_stub() { return kind() == KEYED_CALL_IC; }
5087
  inline bool is_binary_op_stub() { return kind() == BINARY_OP_IC; }
5088
  inline bool is_compare_ic_stub() { return kind() == COMPARE_IC; }
5089
  inline bool is_compare_nil_ic_stub() { return kind() == COMPARE_NIL_IC; }
5090
  inline bool is_to_boolean_ic_stub() { return kind() == TO_BOOLEAN_IC; }
5091
  inline bool is_keyed_stub();
5092

    
5093
  // [major_key]: For kind STUB or BINARY_OP_IC, the major key.
5094
  inline int major_key();
5095
  inline void set_major_key(int value);
5096

    
5097
  // For kind STUB or ICs, tells whether or not a code object was generated by
5098
  // the optimizing compiler (but it may not be an optimized function).
5099
  bool is_crankshafted();
5100
  inline void set_is_crankshafted(bool value);
5101

    
5102
  // For stubs, tells whether they should always exist, so that they can be
5103
  // called from other stubs.
5104
  inline bool is_pregenerated();
5105
  inline void set_is_pregenerated(bool value);
5106

    
5107
  // [optimizable]: For FUNCTION kind, tells if it is optimizable.
5108
  inline bool optimizable();
5109
  inline void set_optimizable(bool value);
5110

    
5111
  // [has_deoptimization_support]: For FUNCTION kind, tells if it has
5112
  // deoptimization support.
5113
  inline bool has_deoptimization_support();
5114
  inline void set_has_deoptimization_support(bool value);
5115

    
5116
  // [has_debug_break_slots]: For FUNCTION kind, tells if it has
5117
  // been compiled with debug break slots.
5118
  inline bool has_debug_break_slots();
5119
  inline void set_has_debug_break_slots(bool value);
5120

    
5121
  // [compiled_with_optimizing]: For FUNCTION kind, tells if it has
5122
  // been compiled with IsOptimizing set to true.
5123
  inline bool is_compiled_optimizable();
5124
  inline void set_compiled_optimizable(bool value);
5125

    
5126
  // [allow_osr_at_loop_nesting_level]: For FUNCTION kind, tells for
5127
  // how long the function has been marked for OSR and therefore which
5128
  // level of loop nesting we are willing to do on-stack replacement
5129
  // for.
5130
  inline void set_allow_osr_at_loop_nesting_level(int level);
5131
  inline int allow_osr_at_loop_nesting_level();
5132

    
5133
  // [profiler_ticks]: For FUNCTION kind, tells for how many profiler ticks
5134
  // the code object was seen on the stack with no IC patching going on.
5135
  inline int profiler_ticks();
5136
  inline void set_profiler_ticks(int ticks);
5137

    
5138
  // [stack_slots]: For kind OPTIMIZED_FUNCTION, the number of stack slots
5139
  // reserved in the code prologue.
5140
  inline unsigned stack_slots();
5141
  inline void set_stack_slots(unsigned slots);
5142

    
5143
  // [safepoint_table_start]: For kind OPTIMIZED_CODE, the offset in
5144
  // the instruction stream where the safepoint table starts.
5145
  inline unsigned safepoint_table_offset();
5146
  inline void set_safepoint_table_offset(unsigned offset);
5147

    
5148
  // [back_edge_table_start]: For kind FUNCTION, the offset in the
5149
  // instruction stream where the back edge table starts.
5150
  inline unsigned back_edge_table_offset();
5151
  inline void set_back_edge_table_offset(unsigned offset);
5152

    
5153
  inline bool back_edges_patched_for_osr();
5154
  inline void set_back_edges_patched_for_osr(bool value);
5155

    
5156
  // [check type]: For kind CALL_IC, tells how to check if the
5157
  // receiver is valid for the given call.
5158
  inline CheckType check_type();
5159
  inline void set_check_type(CheckType value);
5160

    
5161
  // [to_boolean_foo]: For kind TO_BOOLEAN_IC tells what state the stub is in.
5162
  inline byte to_boolean_state();
5163

    
5164
  // [has_function_cache]: For kind STUB tells whether there is a function
5165
  // cache is passed to the stub.
5166
  inline bool has_function_cache();
5167
  inline void set_has_function_cache(bool flag);
5168

    
5169

    
5170
  // [marked_for_deoptimization]: For kind OPTIMIZED_FUNCTION tells whether
5171
  // the code is going to be deoptimized because of dead embedded maps.
5172
  inline bool marked_for_deoptimization();
5173
  inline void set_marked_for_deoptimization(bool flag);
5174

    
5175
  // Get the safepoint entry for the given pc.
5176
  SafepointEntry GetSafepointEntry(Address pc);
5177

    
5178
  // Find an object in a stub with a specified map
5179
  Object* FindNthObject(int n, Map* match_map);
5180
  void ReplaceNthObject(int n, Map* match_map, Object* replace_with);
5181

    
5182
  // Find the first map in an IC stub.
5183
  Map* FindFirstMap();
5184
  void FindAllMaps(MapHandleList* maps);
5185
  void ReplaceFirstMap(Map* replace);
5186

    
5187
  // Find the first handler in an IC stub.
5188
  Code* FindFirstHandler();
5189

    
5190
  // Find |length| handlers and put them into |code_list|. Returns false if not
5191
  // enough handlers can be found.
5192
  bool FindHandlers(CodeHandleList* code_list, int length = -1);
5193

    
5194
  // Find the first name in an IC stub.
5195
  Name* FindFirstName();
5196

    
5197
  void ReplaceNthCell(int n, Cell* replace_with);
5198

    
5199
  class ExtraICStateStrictMode: public BitField<StrictModeFlag, 0, 1> {};
5200
  class ExtraICStateKeyedAccessStoreMode:
5201
      public BitField<KeyedAccessStoreMode, 1, 4> {};  // NOLINT
5202

    
5203
  static inline StrictModeFlag GetStrictMode(ExtraICState extra_ic_state) {
5204
    return ExtraICStateStrictMode::decode(extra_ic_state);
5205
  }
5206

    
5207
  static inline KeyedAccessStoreMode GetKeyedAccessStoreMode(
5208
      ExtraICState extra_ic_state) {
5209
    return ExtraICStateKeyedAccessStoreMode::decode(extra_ic_state);
5210
  }
5211

    
5212
  static inline ExtraICState ComputeExtraICState(
5213
      KeyedAccessStoreMode store_mode,
5214
      StrictModeFlag strict_mode) {
5215
    return ExtraICStateKeyedAccessStoreMode::encode(store_mode) |
5216
        ExtraICStateStrictMode::encode(strict_mode);
5217
  }
5218

    
5219
  // Flags operations.
5220
  static inline Flags ComputeFlags(
5221
      Kind kind,
5222
      InlineCacheState ic_state = UNINITIALIZED,
5223
      ExtraICState extra_ic_state = kNoExtraICState,
5224
      StubType type = NORMAL,
5225
      int argc = -1,
5226
      InlineCacheHolderFlag holder = OWN_MAP);
5227

    
5228
  static inline Flags ComputeMonomorphicFlags(
5229
      Kind kind,
5230
      ExtraICState extra_ic_state = kNoExtraICState,
5231
      StubType type = NORMAL,
5232
      int argc = -1,
5233
      InlineCacheHolderFlag holder = OWN_MAP);
5234

    
5235
  static inline InlineCacheState ExtractICStateFromFlags(Flags flags);
5236
  static inline StubType ExtractTypeFromFlags(Flags flags);
5237
  static inline Kind ExtractKindFromFlags(Flags flags);
5238
  static inline InlineCacheHolderFlag ExtractCacheHolderFromFlags(Flags flags);
5239
  static inline ExtraICState ExtractExtraICStateFromFlags(Flags flags);
5240
  static inline ExtraICState ExtractExtendedExtraICStateFromFlags(Flags flags);
5241
  static inline int ExtractArgumentsCountFromFlags(Flags flags);
5242

    
5243
  static inline Flags RemoveTypeFromFlags(Flags flags);
5244

    
5245
  // Convert a target address into a code object.
5246
  static inline Code* GetCodeFromTargetAddress(Address address);
5247

    
5248
  // Convert an entry address into an object.
5249
  static inline Object* GetObjectFromEntryAddress(Address location_of_address);
5250

    
5251
  // Returns the address of the first instruction.
5252
  inline byte* instruction_start();
5253

    
5254
  // Returns the address right after the last instruction.
5255
  inline byte* instruction_end();
5256

    
5257
  // Returns the size of the instructions, padding, and relocation information.
5258
  inline int body_size();
5259

    
5260
  // Returns the address of the first relocation info (read backwards!).
5261
  inline byte* relocation_start();
5262

    
5263
  // Code entry point.
5264
  inline byte* entry();
5265

    
5266
  // Returns true if pc is inside this object's instructions.
5267
  inline bool contains(byte* pc);
5268

    
5269
  // Relocate the code by delta bytes. Called to signal that this code
5270
  // object has been moved by delta bytes.
5271
  void Relocate(intptr_t delta);
5272

    
5273
  // Migrate code described by desc.
5274
  void CopyFrom(const CodeDesc& desc);
5275

    
5276
  // Returns the object size for a given body (used for allocation).
5277
  static int SizeFor(int body_size) {
5278
    ASSERT_SIZE_TAG_ALIGNED(body_size);
5279
    return RoundUp(kHeaderSize + body_size, kCodeAlignment);
5280
  }
5281

    
5282
  // Calculate the size of the code object to report for log events. This takes
5283
  // the layout of the code object into account.
5284
  int ExecutableSize() {
5285
    // Check that the assumptions about the layout of the code object holds.
5286
    ASSERT_EQ(static_cast<int>(instruction_start() - address()),
5287
              Code::kHeaderSize);
5288
    return instruction_size() + Code::kHeaderSize;
5289
  }
5290

    
5291
  // Locating source position.
5292
  int SourcePosition(Address pc);
5293
  int SourceStatementPosition(Address pc);
5294

    
5295
  // Casting.
5296
  static inline Code* cast(Object* obj);
5297

    
5298
  // Dispatched behavior.
5299
  int CodeSize() { return SizeFor(body_size()); }
5300
  inline void CodeIterateBody(ObjectVisitor* v);
5301

    
5302
  template<typename StaticVisitor>
5303
  inline void CodeIterateBody(Heap* heap);
5304

    
5305
  DECLARE_PRINTER(Code)
5306
  DECLARE_VERIFIER(Code)
5307

    
5308
  void ClearInlineCaches();
5309
  void ClearTypeFeedbackCells(Heap* heap);
5310

    
5311
  BailoutId TranslatePcOffsetToAstId(uint32_t pc_offset);
5312

    
5313
#define DECLARE_CODE_AGE_ENUM(X) k##X##CodeAge,
5314
  enum Age {
5315
    kNotExecutedCodeAge = -2,
5316
    kExecutedOnceCodeAge = -1,
5317
    kNoAgeCodeAge = 0,
5318
    CODE_AGE_LIST(DECLARE_CODE_AGE_ENUM)
5319
    kAfterLastCodeAge,
5320
    kLastCodeAge = kAfterLastCodeAge - 1,
5321
    kCodeAgeCount = kAfterLastCodeAge - 1,
5322
    kIsOldCodeAge = kSexagenarianCodeAge,
5323
    kPreAgedCodeAge = kIsOldCodeAge - 1
5324
  };
5325
#undef DECLARE_CODE_AGE_ENUM
5326

    
5327
  // Code aging.  Indicates how many full GCs this code has survived without
5328
  // being entered through the prologue.  Used to determine when it is
5329
  // relatively safe to flush this code object and replace it with the lazy
5330
  // compilation stub.
5331
  static void MakeCodeAgeSequenceYoung(byte* sequence, Isolate* isolate);
5332
  static void MarkCodeAsExecuted(byte* sequence, Isolate* isolate);
5333
  void MakeOlder(MarkingParity);
5334
  static bool IsYoungSequence(byte* sequence);
5335
  bool IsOld();
5336
  Age GetAge();
5337
  static inline Code* GetPreAgedCodeAgeStub(Isolate* isolate) {
5338
    return GetCodeAgeStub(isolate, kNotExecutedCodeAge, NO_MARKING_PARITY);
5339
  }
5340

    
5341
  void PrintDeoptLocation(int bailout_id);
5342
  bool CanDeoptAt(Address pc);
5343

    
5344
#ifdef VERIFY_HEAP
5345
  void VerifyEmbeddedObjectsDependency();
5346
#endif
5347

    
5348
  static bool IsWeakEmbeddedObject(Kind kind, Object* object);
5349

    
5350
  // Max loop nesting marker used to postpose OSR. We don't take loop
5351
  // nesting that is deeper than 5 levels into account.
5352
  static const int kMaxLoopNestingMarker = 6;
5353

    
5354
  // Layout description.
5355
  static const int kInstructionSizeOffset = HeapObject::kHeaderSize;
5356
  static const int kRelocationInfoOffset = kInstructionSizeOffset + kIntSize;
5357
  static const int kHandlerTableOffset = kRelocationInfoOffset + kPointerSize;
5358
  static const int kDeoptimizationDataOffset =
5359
      kHandlerTableOffset + kPointerSize;
5360
  static const int kTypeFeedbackInfoOffset =
5361
      kDeoptimizationDataOffset + kPointerSize;
5362
  static const int kNextCodeLinkOffset = kTypeFeedbackInfoOffset;  // Shared.
5363
  static const int kGCMetadataOffset = kTypeFeedbackInfoOffset + kPointerSize;
5364
  static const int kICAgeOffset =
5365
      kGCMetadataOffset + kPointerSize;
5366
  static const int kFlagsOffset = kICAgeOffset + kIntSize;
5367
  static const int kKindSpecificFlags1Offset = kFlagsOffset + kIntSize;
5368
  static const int kKindSpecificFlags2Offset =
5369
      kKindSpecificFlags1Offset + kIntSize;
5370
  // Note: We might be able to squeeze this into the flags above.
5371
  static const int kPrologueOffset = kKindSpecificFlags2Offset + kIntSize;
5372

    
5373
  static const int kHeaderPaddingStart = kPrologueOffset + kIntSize;
5374

    
5375
  // Add padding to align the instruction start following right after
5376
  // the Code object header.
5377
  static const int kHeaderSize =
5378
      (kHeaderPaddingStart + kCodeAlignmentMask) & ~kCodeAlignmentMask;
5379

    
5380
  // Byte offsets within kKindSpecificFlags1Offset.
5381
  static const int kOptimizableOffset = kKindSpecificFlags1Offset;
5382
  static const int kCheckTypeOffset = kKindSpecificFlags1Offset;
5383

    
5384
  static const int kFullCodeFlags = kOptimizableOffset + 1;
5385
  class FullCodeFlagsHasDeoptimizationSupportField:
5386
      public BitField<bool, 0, 1> {};  // NOLINT
5387
  class FullCodeFlagsHasDebugBreakSlotsField: public BitField<bool, 1, 1> {};
5388
  class FullCodeFlagsIsCompiledOptimizable: public BitField<bool, 2, 1> {};
5389

    
5390
  static const int kAllowOSRAtLoopNestingLevelOffset = kFullCodeFlags + 1;
5391
  static const int kProfilerTicksOffset = kAllowOSRAtLoopNestingLevelOffset + 1;
5392

    
5393
  // Flags layout.  BitField<type, shift, size>.
5394
  class ICStateField: public BitField<InlineCacheState, 0, 3> {};
5395
  class TypeField: public BitField<StubType, 3, 3> {};
5396
  class CacheHolderField: public BitField<InlineCacheHolderFlag, 6, 1> {};
5397
  class KindField: public BitField<Kind, 7, 4> {};
5398
  class IsPregeneratedField: public BitField<bool, 11, 1> {};
5399
  class ExtraICStateField: public BitField<ExtraICState, 12, 5> {};
5400
  class ExtendedExtraICStateField: public BitField<ExtraICState, 12,
5401
      PlatformSmiTagging::kSmiValueSize - 12 + 1> {};  // NOLINT
5402
  STATIC_ASSERT(ExtraICStateField::kShift == ExtendedExtraICStateField::kShift);
5403

    
5404
  // KindSpecificFlags1 layout (STUB and OPTIMIZED_FUNCTION)
5405
  static const int kStackSlotsFirstBit = 0;
5406
  static const int kStackSlotsBitCount = 24;
5407
  static const int kHasFunctionCacheFirstBit =
5408
      kStackSlotsFirstBit + kStackSlotsBitCount;
5409
  static const int kHasFunctionCacheBitCount = 1;
5410
  static const int kMarkedForDeoptimizationFirstBit =
5411
      kStackSlotsFirstBit + kStackSlotsBitCount + 1;
5412
  static const int kMarkedForDeoptimizationBitCount = 1;
5413

    
5414
  STATIC_ASSERT(kStackSlotsFirstBit + kStackSlotsBitCount <= 32);
5415
  STATIC_ASSERT(kHasFunctionCacheFirstBit + kHasFunctionCacheBitCount <= 32);
5416
  STATIC_ASSERT(kMarkedForDeoptimizationFirstBit +
5417
                kMarkedForDeoptimizationBitCount <= 32);
5418

    
5419
  class StackSlotsField: public BitField<int,
5420
      kStackSlotsFirstBit, kStackSlotsBitCount> {};  // NOLINT
5421
  class HasFunctionCacheField: public BitField<bool,
5422
      kHasFunctionCacheFirstBit, kHasFunctionCacheBitCount> {};  // NOLINT
5423
  class MarkedForDeoptimizationField: public BitField<bool,
5424
      kMarkedForDeoptimizationFirstBit,
5425
      kMarkedForDeoptimizationBitCount> {};  // NOLINT
5426

    
5427
  // KindSpecificFlags2 layout (ALL)
5428
  static const int kIsCrankshaftedBit = 0;
5429
  class IsCrankshaftedField: public BitField<bool,
5430
      kIsCrankshaftedBit, 1> {};  // NOLINT
5431

    
5432
  // KindSpecificFlags2 layout (STUB and OPTIMIZED_FUNCTION)
5433
  static const int kStubMajorKeyFirstBit = kIsCrankshaftedBit + 1;
5434
  static const int kSafepointTableOffsetFirstBit =
5435
      kStubMajorKeyFirstBit + kStubMajorKeyBits;
5436
  static const int kSafepointTableOffsetBitCount = 25;
5437

    
5438
  STATIC_ASSERT(kStubMajorKeyFirstBit + kStubMajorKeyBits <= 32);
5439
  STATIC_ASSERT(kSafepointTableOffsetFirstBit +
5440
                kSafepointTableOffsetBitCount <= 32);
5441
  STATIC_ASSERT(1 + kStubMajorKeyBits +
5442
                kSafepointTableOffsetBitCount <= 32);
5443

    
5444
  class SafepointTableOffsetField: public BitField<int,
5445
      kSafepointTableOffsetFirstBit,
5446
      kSafepointTableOffsetBitCount> {};  // NOLINT
5447
  class StubMajorKeyField: public BitField<int,
5448
      kStubMajorKeyFirstBit, kStubMajorKeyBits> {};  // NOLINT
5449

    
5450
  // KindSpecificFlags2 layout (FUNCTION)
5451
  class BackEdgeTableOffsetField: public BitField<int,
5452
      kIsCrankshaftedBit + 1, 29> {};  // NOLINT
5453
  class BackEdgesPatchedForOSRField: public BitField<bool,
5454
      kIsCrankshaftedBit + 1 + 29, 1> {};  // NOLINT
5455

    
5456
  // Signed field cannot be encoded using the BitField class.
5457
  static const int kArgumentsCountShift = 17;
5458
  static const int kArgumentsCountMask = ~((1 << kArgumentsCountShift) - 1);
5459
  static const int kArgumentsBits =
5460
      PlatformSmiTagging::kSmiValueSize - Code::kArgumentsCountShift + 1;
5461
  static const int kMaxArguments = (1 << kArgumentsBits) - 1;
5462

    
5463
  // ICs can use either argument count or ExtendedExtraIC, since their storage
5464
  // overlaps.
5465
  STATIC_ASSERT(ExtraICStateField::kShift +
5466
                ExtraICStateField::kSize + kArgumentsBits ==
5467
                ExtendedExtraICStateField::kShift +
5468
                ExtendedExtraICStateField::kSize);
5469

    
5470
  // This constant should be encodable in an ARM instruction.
5471
  static const int kFlagsNotUsedInLookup =
5472
      TypeField::kMask | CacheHolderField::kMask;
5473

    
5474
 private:
5475
  friend class RelocIterator;
5476

    
5477
  // Code aging
5478
  byte* FindCodeAgeSequence();
5479
  static void GetCodeAgeAndParity(Code* code, Age* age,
5480
                                  MarkingParity* parity);
5481
  static void GetCodeAgeAndParity(byte* sequence, Age* age,
5482
                                  MarkingParity* parity);
5483
  static Code* GetCodeAgeStub(Isolate* isolate, Age age, MarkingParity parity);
5484

    
5485
  // Code aging -- platform-specific
5486
  static void PatchPlatformCodeAge(Isolate* isolate,
5487
                                   byte* sequence, Age age,
5488
                                   MarkingParity parity);
5489

    
5490
  DISALLOW_IMPLICIT_CONSTRUCTORS(Code);
5491
};
5492

    
5493

    
5494
class CompilationInfo;
5495

    
5496
// This class describes the layout of dependent codes array of a map. The
5497
// array is partitioned into several groups of dependent codes. Each group
5498
// contains codes with the same dependency on the map. The array has the
5499
// following layout for n dependency groups:
5500
//
5501
// +----+----+-----+----+---------+----------+-----+---------+-----------+
5502
// | C1 | C2 | ... | Cn | group 1 |  group 2 | ... | group n | undefined |
5503
// +----+----+-----+----+---------+----------+-----+---------+-----------+
5504
//
5505
// The first n elements are Smis, each of them specifies the number of codes
5506
// in the corresponding group. The subsequent elements contain grouped code
5507
// objects. The suffix of the array can be filled with the undefined value if
5508
// the number of codes is less than the length of the array. The order of the
5509
// code objects within a group is not preserved.
5510
//
5511
// All code indexes used in the class are counted starting from the first
5512
// code object of the first group. In other words, code index 0 corresponds
5513
// to array index n = kCodesStartIndex.
5514

    
5515
class DependentCode: public FixedArray {
5516
 public:
5517
  enum DependencyGroup {
5518
    // Group of code that weakly embed this map and depend on being
5519
    // deoptimized when the map is garbage collected.
5520
    kWeaklyEmbeddedGroup,
5521
    // Group of code that embed a transition to this map, and depend on being
5522
    // deoptimized when the transition is replaced by a new version.
5523
    kTransitionGroup,
5524
    // Group of code that omit run-time prototype checks for prototypes
5525
    // described by this map. The group is deoptimized whenever an object
5526
    // described by this map changes shape (and transitions to a new map),
5527
    // possibly invalidating the assumptions embedded in the code.
5528
    kPrototypeCheckGroup,
5529
    // Group of code that depends on elements not being added to objects with
5530
    // this map.
5531
    kElementsCantBeAddedGroup,
5532
    // Group of code that depends on global property values in property cells
5533
    // not being changed.
5534
    kPropertyCellChangedGroup,
5535
    kGroupCount = kPropertyCellChangedGroup + 1
5536
  };
5537

    
5538
  // Array for holding the index of the first code object of each group.
5539
  // The last element stores the total number of code objects.
5540
  class GroupStartIndexes {
5541
   public:
5542
    explicit GroupStartIndexes(DependentCode* entries);
5543
    void Recompute(DependentCode* entries);
5544
    int at(int i) { return start_indexes_[i]; }
5545
    int number_of_entries() { return start_indexes_[kGroupCount]; }
5546
   private:
5547
    int start_indexes_[kGroupCount + 1];
5548
  };
5549

    
5550
  bool Contains(DependencyGroup group, Code* code);
5551
  static Handle<DependentCode> Insert(Handle<DependentCode> entries,
5552
                                      DependencyGroup group,
5553
                                      Handle<Object> object);
5554
  void UpdateToFinishedCode(DependencyGroup group,
5555
                            CompilationInfo* info,
5556
                            Code* code);
5557
  void RemoveCompilationInfo(DependentCode::DependencyGroup group,
5558
                             CompilationInfo* info);
5559

    
5560
  void DeoptimizeDependentCodeGroup(Isolate* isolate,
5561
                                    DependentCode::DependencyGroup group);
5562

    
5563
  // The following low-level accessors should only be used by this class
5564
  // and the mark compact collector.
5565
  inline int number_of_entries(DependencyGroup group);
5566
  inline void set_number_of_entries(DependencyGroup group, int value);
5567
  inline bool is_code_at(int i);
5568
  inline Code* code_at(int i);
5569
  inline CompilationInfo* compilation_info_at(int i);
5570
  inline void set_object_at(int i, Object* object);
5571
  inline Object** slot_at(int i);
5572
  inline Object* object_at(int i);
5573
  inline void clear_at(int i);
5574
  inline void copy(int from, int to);
5575
  static inline DependentCode* cast(Object* object);
5576

    
5577
  static DependentCode* ForObject(Handle<HeapObject> object,
5578
                                  DependencyGroup group);
5579

    
5580
 private:
5581
  // Make a room at the end of the given group by moving out the first
5582
  // code objects of the subsequent groups.
5583
  inline void ExtendGroup(DependencyGroup group);
5584
  static const int kCodesStartIndex = kGroupCount;
5585
};
5586

    
5587

    
5588
// All heap objects have a Map that describes their structure.
5589
//  A Map contains information about:
5590
//  - Size information about the object
5591
//  - How to iterate over an object (for garbage collection)
5592
class Map: public HeapObject {
5593
 public:
5594
  // Instance size.
5595
  // Size in bytes or kVariableSizeSentinel if instances do not have
5596
  // a fixed size.
5597
  inline int instance_size();
5598
  inline void set_instance_size(int value);
5599

    
5600
  // Count of properties allocated in the object.
5601
  inline int inobject_properties();
5602
  inline void set_inobject_properties(int value);
5603

    
5604
  // Count of property fields pre-allocated in the object when first allocated.
5605
  inline int pre_allocated_property_fields();
5606
  inline void set_pre_allocated_property_fields(int value);
5607

    
5608
  // Instance type.
5609
  inline InstanceType instance_type();
5610
  inline void set_instance_type(InstanceType value);
5611

    
5612
  // Tells how many unused property fields are available in the
5613
  // instance (only used for JSObject in fast mode).
5614
  inline int unused_property_fields();
5615
  inline void set_unused_property_fields(int value);
5616

    
5617
  // Bit field.
5618
  inline byte bit_field();
5619
  inline void set_bit_field(byte value);
5620

    
5621
  // Bit field 2.
5622
  inline byte bit_field2();
5623
  inline void set_bit_field2(byte value);
5624

    
5625
  // Bit field 3.
5626
  inline uint32_t bit_field3();
5627
  inline void set_bit_field3(uint32_t bits);
5628

    
5629
  class EnumLengthBits:             public BitField<int,   0, 11> {};
5630
  class NumberOfOwnDescriptorsBits: public BitField<int,  11, 11> {};
5631
  class IsShared:                   public BitField<bool, 22,  1> {};
5632
  class FunctionWithPrototype:      public BitField<bool, 23,  1> {};
5633
  class DictionaryMap:              public BitField<bool, 24,  1> {};
5634
  class OwnsDescriptors:            public BitField<bool, 25,  1> {};
5635
  class IsObserved:                 public BitField<bool, 26,  1> {};
5636
  class Deprecated:                 public BitField<bool, 27,  1> {};
5637
  class IsFrozen:                   public BitField<bool, 28,  1> {};
5638
  class IsUnstable:                 public BitField<bool, 29,  1> {};
5639
  class IsMigrationTarget:          public BitField<bool, 30,  1> {};
5640

    
5641
  // Tells whether the object in the prototype property will be used
5642
  // for instances created from this function.  If the prototype
5643
  // property is set to a value that is not a JSObject, the prototype
5644
  // property will not be used to create instances of the function.
5645
  // See ECMA-262, 13.2.2.
5646
  inline void set_non_instance_prototype(bool value);
5647
  inline bool has_non_instance_prototype();
5648

    
5649
  // Tells whether function has special prototype property. If not, prototype
5650
  // property will not be created when accessed (will return undefined),
5651
  // and construction from this function will not be allowed.
5652
  inline void set_function_with_prototype(bool value);
5653
  inline bool function_with_prototype();
5654

    
5655
  // Tells whether the instance with this map should be ignored by the
5656
  // Object.getPrototypeOf() function and the __proto__ accessor.
5657
  inline void set_is_hidden_prototype() {
5658
    set_bit_field(bit_field() | (1 << kIsHiddenPrototype));
5659
  }
5660

    
5661
  inline bool is_hidden_prototype() {
5662
    return ((1 << kIsHiddenPrototype) & bit_field()) != 0;
5663
  }
5664

    
5665
  // Records and queries whether the instance has a named interceptor.
5666
  inline void set_has_named_interceptor() {
5667
    set_bit_field(bit_field() | (1 << kHasNamedInterceptor));
5668
  }
5669

    
5670
  inline bool has_named_interceptor() {
5671
    return ((1 << kHasNamedInterceptor) & bit_field()) != 0;
5672
  }
5673

    
5674
  // Records and queries whether the instance has an indexed interceptor.
5675
  inline void set_has_indexed_interceptor() {
5676
    set_bit_field(bit_field() | (1 << kHasIndexedInterceptor));
5677
  }
5678

    
5679
  inline bool has_indexed_interceptor() {
5680
    return ((1 << kHasIndexedInterceptor) & bit_field()) != 0;
5681
  }
5682

    
5683
  // Tells whether the instance is undetectable.
5684
  // An undetectable object is a special class of JSObject: 'typeof' operator
5685
  // returns undefined, ToBoolean returns false. Otherwise it behaves like
5686
  // a normal JS object.  It is useful for implementing undetectable
5687
  // document.all in Firefox & Safari.
5688
  // See https://bugzilla.mozilla.org/show_bug.cgi?id=248549.
5689
  inline void set_is_undetectable() {
5690
    set_bit_field(bit_field() | (1 << kIsUndetectable));
5691
  }
5692

    
5693
  inline bool is_undetectable() {
5694
    return ((1 << kIsUndetectable) & bit_field()) != 0;
5695
  }
5696

    
5697
  // Tells whether the instance has a call-as-function handler.
5698
  inline void set_has_instance_call_handler() {
5699
    set_bit_field(bit_field() | (1 << kHasInstanceCallHandler));
5700
  }
5701

    
5702
  inline bool has_instance_call_handler() {
5703
    return ((1 << kHasInstanceCallHandler) & bit_field()) != 0;
5704
  }
5705

    
5706
  inline void set_is_extensible(bool value);
5707
  inline bool is_extensible();
5708

    
5709
  inline void set_elements_kind(ElementsKind elements_kind) {
5710
    ASSERT(elements_kind < kElementsKindCount);
5711
    ASSERT(kElementsKindCount <= (1 << kElementsKindBitCount));
5712
    ASSERT(!is_observed() ||
5713
           elements_kind == DICTIONARY_ELEMENTS ||
5714
           elements_kind == NON_STRICT_ARGUMENTS_ELEMENTS ||
5715
           IsExternalArrayElementsKind(elements_kind));
5716
    set_bit_field2((bit_field2() & ~kElementsKindMask) |
5717
        (elements_kind << kElementsKindShift));
5718
    ASSERT(this->elements_kind() == elements_kind);
5719
  }
5720

    
5721
  inline ElementsKind elements_kind() {
5722
    return static_cast<ElementsKind>(
5723
        (bit_field2() & kElementsKindMask) >> kElementsKindShift);
5724
  }
5725

    
5726
  // Tells whether the instance has fast elements that are only Smis.
5727
  inline bool has_fast_smi_elements() {
5728
    return IsFastSmiElementsKind(elements_kind());
5729
  }
5730

    
5731
  // Tells whether the instance has fast elements.
5732
  inline bool has_fast_object_elements() {
5733
    return IsFastObjectElementsKind(elements_kind());
5734
  }
5735

    
5736
  inline bool has_fast_smi_or_object_elements() {
5737
    return IsFastSmiOrObjectElementsKind(elements_kind());
5738
  }
5739

    
5740
  inline bool has_fast_double_elements() {
5741
    return IsFastDoubleElementsKind(elements_kind());
5742
  }
5743

    
5744
  inline bool has_fast_elements() {
5745
    return IsFastElementsKind(elements_kind());
5746
  }
5747

    
5748
  inline bool has_non_strict_arguments_elements() {
5749
    return elements_kind() == NON_STRICT_ARGUMENTS_ELEMENTS;
5750
  }
5751

    
5752
  inline bool has_external_array_elements() {
5753
    return IsExternalArrayElementsKind(elements_kind());
5754
  }
5755

    
5756
  inline bool has_dictionary_elements() {
5757
    return IsDictionaryElementsKind(elements_kind());
5758
  }
5759

    
5760
  inline bool has_slow_elements_kind() {
5761
    return elements_kind() == DICTIONARY_ELEMENTS
5762
        || elements_kind() == NON_STRICT_ARGUMENTS_ELEMENTS;
5763
  }
5764

    
5765
  static bool IsValidElementsTransition(ElementsKind from_kind,
5766
                                        ElementsKind to_kind);
5767

    
5768
  inline bool HasTransitionArray();
5769
  inline bool HasElementsTransition();
5770
  inline Map* elements_transition_map();
5771
  MUST_USE_RESULT inline MaybeObject* set_elements_transition_map(
5772
      Map* transitioned_map);
5773
  inline void SetTransition(int transition_index, Map* target);
5774
  inline Map* GetTransition(int transition_index);
5775

    
5776
  static Handle<TransitionArray> AddTransition(Handle<Map> map,
5777
                                               Handle<Name> key,
5778
                                               Handle<Map> target,
5779
                                               SimpleTransitionFlag flag);
5780

    
5781
  MUST_USE_RESULT inline MaybeObject* AddTransition(Name* key,
5782
                                                    Map* target,
5783
                                                    SimpleTransitionFlag flag);
5784
  DECL_ACCESSORS(transitions, TransitionArray)
5785
  inline void ClearTransitions(Heap* heap,
5786
                               WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
5787

    
5788
  void DeprecateTransitionTree();
5789
  void DeprecateTarget(Name* key, DescriptorArray* new_descriptors);
5790

    
5791
  Map* FindRootMap();
5792
  Map* FindUpdatedMap(int verbatim, int length, DescriptorArray* descriptors);
5793
  Map* FindLastMatchMap(int verbatim, int length, DescriptorArray* descriptors);
5794

    
5795
  int NumberOfFields();
5796

    
5797
  bool InstancesNeedRewriting(Map* target,
5798
                              int target_number_of_fields,
5799
                              int target_inobject,
5800
                              int target_unused);
5801
  static Handle<Map> GeneralizeAllFieldRepresentations(
5802
      Handle<Map> map,
5803
      Representation new_representation);
5804
  static Handle<Map> GeneralizeRepresentation(
5805
      Handle<Map> map,
5806
      int modify_index,
5807
      Representation new_representation,
5808
      StoreMode store_mode);
5809
  static Handle<Map> CopyGeneralizeAllRepresentations(
5810
      Handle<Map> map,
5811
      int modify_index,
5812
      StoreMode store_mode,
5813
      PropertyAttributes attributes,
5814
      const char* reason);
5815

    
5816
  void PrintGeneralization(FILE* file,
5817
                           const char* reason,
5818
                           int modify_index,
5819
                           int split,
5820
                           int descriptors,
5821
                           bool constant_to_field,
5822
                           Representation old_representation,
5823
                           Representation new_representation);
5824

    
5825
  // Returns the constructor name (the name (possibly, inferred name) of the
5826
  // function that was used to instantiate the object).
5827
  String* constructor_name();
5828

    
5829
  // Tells whether the map is attached to SharedFunctionInfo
5830
  // (for inobject slack tracking).
5831
  inline void set_attached_to_shared_function_info(bool value);
5832

    
5833
  inline bool attached_to_shared_function_info();
5834

    
5835
  // Tells whether the map is shared between objects that may have different
5836
  // behavior. If true, the map should never be modified, instead a clone
5837
  // should be created and modified.
5838
  inline void set_is_shared(bool value);
5839
  inline bool is_shared();
5840

    
5841
  // Tells whether the map is used for JSObjects in dictionary mode (ie
5842
  // normalized objects, ie objects for which HasFastProperties returns false).
5843
  // A map can never be used for both dictionary mode and fast mode JSObjects.
5844
  // False by default and for HeapObjects that are not JSObjects.
5845
  inline void set_dictionary_map(bool value);
5846
  inline bool is_dictionary_map();
5847

    
5848
  // Tells whether the instance needs security checks when accessing its
5849
  // properties.
5850
  inline void set_is_access_check_needed(bool access_check_needed);
5851
  inline bool is_access_check_needed();
5852

    
5853
  // Returns true if map has a non-empty stub code cache.
5854
  inline bool has_code_cache();
5855

    
5856
  // [prototype]: implicit prototype object.
5857
  DECL_ACCESSORS(prototype, Object)
5858

    
5859
  // [constructor]: points back to the function responsible for this map.
5860
  DECL_ACCESSORS(constructor, Object)
5861

    
5862
  // [instance descriptors]: describes the object.
5863
  DECL_ACCESSORS(instance_descriptors, DescriptorArray)
5864
  inline void InitializeDescriptors(DescriptorArray* descriptors);
5865

    
5866
  // [stub cache]: contains stubs compiled for this map.
5867
  DECL_ACCESSORS(code_cache, Object)
5868

    
5869
  // [dependent code]: list of optimized codes that have this map embedded.
5870
  DECL_ACCESSORS(dependent_code, DependentCode)
5871

    
5872
  // [back pointer]: points back to the parent map from which a transition
5873
  // leads to this map. The field overlaps with prototype transitions and the
5874
  // back pointer will be moved into the prototype transitions array if
5875
  // required.
5876
  inline Object* GetBackPointer();
5877
  inline void SetBackPointer(Object* value,
5878
                             WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
5879
  inline void init_back_pointer(Object* undefined);
5880

    
5881
  // [prototype transitions]: cache of prototype transitions.
5882
  // Prototype transition is a transition that happens
5883
  // when we change object's prototype to a new one.
5884
  // Cache format:
5885
  //    0: finger - index of the first free cell in the cache
5886
  //    1: back pointer that overlaps with prototype transitions field.
5887
  //    2 + 2 * i: prototype
5888
  //    3 + 2 * i: target map
5889
  inline FixedArray* GetPrototypeTransitions();
5890
  MUST_USE_RESULT inline MaybeObject* SetPrototypeTransitions(
5891
      FixedArray* prototype_transitions);
5892
  inline bool HasPrototypeTransitions();
5893

    
5894
  inline HeapObject* UncheckedPrototypeTransitions();
5895
  inline TransitionArray* unchecked_transition_array();
5896

    
5897
  static const int kProtoTransitionHeaderSize = 1;
5898
  static const int kProtoTransitionNumberOfEntriesOffset = 0;
5899
  static const int kProtoTransitionElementsPerEntry = 2;
5900
  static const int kProtoTransitionPrototypeOffset = 0;
5901
  static const int kProtoTransitionMapOffset = 1;
5902

    
5903
  inline int NumberOfProtoTransitions() {
5904
    FixedArray* cache = GetPrototypeTransitions();
5905
    if (cache->length() == 0) return 0;
5906
    return
5907
        Smi::cast(cache->get(kProtoTransitionNumberOfEntriesOffset))->value();
5908
  }
5909

    
5910
  inline void SetNumberOfProtoTransitions(int value) {
5911
    FixedArray* cache = GetPrototypeTransitions();
5912
    ASSERT(cache->length() != 0);
5913
    cache->set(kProtoTransitionNumberOfEntriesOffset, Smi::FromInt(value));
5914
  }
5915

    
5916
  // Lookup in the map's instance descriptors and fill out the result
5917
  // with the given holder if the name is found. The holder may be
5918
  // NULL when this function is used from the compiler.
5919
  inline void LookupDescriptor(JSObject* holder,
5920
                               Name* name,
5921
                               LookupResult* result);
5922

    
5923
  inline void LookupTransition(JSObject* holder,
5924
                               Name* name,
5925
                               LookupResult* result);
5926

    
5927
  // The size of transition arrays are limited so they do not end up in large
5928
  // object space. Otherwise ClearNonLiveTransitions would leak memory while
5929
  // applying in-place right trimming.
5930
  inline bool CanHaveMoreTransitions();
5931

    
5932
  int LastAdded() {
5933
    int number_of_own_descriptors = NumberOfOwnDescriptors();
5934
    ASSERT(number_of_own_descriptors > 0);
5935
    return number_of_own_descriptors - 1;
5936
  }
5937

    
5938
  int NumberOfOwnDescriptors() {
5939
    return NumberOfOwnDescriptorsBits::decode(bit_field3());
5940
  }
5941

    
5942
  void SetNumberOfOwnDescriptors(int number) {
5943
    ASSERT(number <= instance_descriptors()->number_of_descriptors());
5944
    set_bit_field3(NumberOfOwnDescriptorsBits::update(bit_field3(), number));
5945
  }
5946

    
5947
  inline Cell* RetrieveDescriptorsPointer();
5948

    
5949
  int EnumLength() {
5950
    return EnumLengthBits::decode(bit_field3());
5951
  }
5952

    
5953
  void SetEnumLength(int length) {
5954
    if (length != kInvalidEnumCache) {
5955
      ASSERT(length >= 0);
5956
      ASSERT(length == 0 || instance_descriptors()->HasEnumCache());
5957
      ASSERT(length <= NumberOfOwnDescriptors());
5958
    }
5959
    set_bit_field3(EnumLengthBits::update(bit_field3(), length));
5960
  }
5961

    
5962
  inline bool owns_descriptors();
5963
  inline void set_owns_descriptors(bool is_shared);
5964
  inline bool is_observed();
5965
  inline void set_is_observed(bool is_observed);
5966
  inline void freeze();
5967
  inline bool is_frozen();
5968
  inline void mark_unstable();
5969
  inline bool is_stable();
5970
  inline void set_migration_target(bool value);
5971
  inline bool is_migration_target();
5972
  inline void deprecate();
5973
  inline bool is_deprecated();
5974
  inline bool CanBeDeprecated();
5975
  // Returns a non-deprecated version of the input. If the input was not
5976
  // deprecated, it is directly returned. Otherwise, the non-deprecated version
5977
  // is found by re-transitioning from the root of the transition tree using the
5978
  // descriptor array of the map. Returns NULL if no updated map is found.
5979
  Map* CurrentMapForDeprecated();
5980

    
5981
  static Handle<Map> RawCopy(Handle<Map> map, int instance_size);
5982
  MUST_USE_RESULT MaybeObject* RawCopy(int instance_size);
5983
  MUST_USE_RESULT MaybeObject* CopyWithPreallocatedFieldDescriptors();
5984
  static Handle<Map> CopyDropDescriptors(Handle<Map> map);
5985
  MUST_USE_RESULT MaybeObject* CopyDropDescriptors();
5986
  static Handle<Map> CopyReplaceDescriptors(Handle<Map> map,
5987
                                            Handle<DescriptorArray> descriptors,
5988
                                            TransitionFlag flag,
5989
                                            Handle<Name> name);
5990
  MUST_USE_RESULT MaybeObject* CopyReplaceDescriptors(
5991
      DescriptorArray* descriptors,
5992
      TransitionFlag flag,
5993
      Name* name = NULL,
5994
      SimpleTransitionFlag simple_flag = FULL_TRANSITION);
5995
  static Handle<Map> CopyInstallDescriptors(
5996
      Handle<Map> map,
5997
      int new_descriptor,
5998
      Handle<DescriptorArray> descriptors);
5999
  MUST_USE_RESULT MaybeObject* ShareDescriptor(DescriptorArray* descriptors,
6000
                                               Descriptor* descriptor);
6001
  MUST_USE_RESULT MaybeObject* CopyAddDescriptor(Descriptor* descriptor,
6002
                                                 TransitionFlag flag);
6003
  MUST_USE_RESULT MaybeObject* CopyInsertDescriptor(Descriptor* descriptor,
6004
                                                    TransitionFlag flag);
6005
  MUST_USE_RESULT MaybeObject* CopyReplaceDescriptor(
6006
      DescriptorArray* descriptors,
6007
      Descriptor* descriptor,
6008
      int index,
6009
      TransitionFlag flag);
6010
  MUST_USE_RESULT MaybeObject* AsElementsKind(ElementsKind kind);
6011

    
6012
  MUST_USE_RESULT MaybeObject* CopyAsElementsKind(ElementsKind kind,
6013
                                                  TransitionFlag flag);
6014

    
6015
  static Handle<Map> CopyForObserved(Handle<Map> map);
6016

    
6017
  static Handle<Map> CopyNormalized(Handle<Map> map,
6018
                                    PropertyNormalizationMode mode,
6019
                                    NormalizedMapSharingMode sharing);
6020

    
6021
  inline void AppendDescriptor(Descriptor* desc,
6022
                               const DescriptorArray::WhitenessWitness&);
6023

    
6024
  // Returns a copy of the map, with all transitions dropped from the
6025
  // instance descriptors.
6026
  static Handle<Map> Copy(Handle<Map> map);
6027
  MUST_USE_RESULT MaybeObject* Copy();
6028

    
6029
  // Returns the next free property index (only valid for FAST MODE).
6030
  int NextFreePropertyIndex();
6031

    
6032
  // Returns the number of properties described in instance_descriptors
6033
  // filtering out properties with the specified attributes.
6034
  int NumberOfDescribedProperties(DescriptorFlag which = OWN_DESCRIPTORS,
6035
                                  PropertyAttributes filter = NONE);
6036

    
6037
  // Returns the number of slots allocated for the initial properties
6038
  // backing storage for instances of this map.
6039
  int InitialPropertiesLength() {
6040
    return pre_allocated_property_fields() + unused_property_fields() -
6041
        inobject_properties();
6042
  }
6043

    
6044
  // Casting.
6045
  static inline Map* cast(Object* obj);
6046

    
6047
  // Locate an accessor in the instance descriptor.
6048
  AccessorDescriptor* FindAccessor(Name* name);
6049

    
6050
  // Code cache operations.
6051

    
6052
  // Clears the code cache.
6053
  inline void ClearCodeCache(Heap* heap);
6054

    
6055
  // Update code cache.
6056
  static void UpdateCodeCache(Handle<Map> map,
6057
                              Handle<Name> name,
6058
                              Handle<Code> code);
6059
  MUST_USE_RESULT MaybeObject* UpdateCodeCache(Name* name, Code* code);
6060

    
6061
  // Extend the descriptor array of the map with the list of descriptors.
6062
  // In case of duplicates, the latest descriptor is used.
6063
  static void AppendCallbackDescriptors(Handle<Map> map,
6064
                                        Handle<Object> descriptors);
6065

    
6066
  static void EnsureDescriptorSlack(Handle<Map> map, int slack);
6067

    
6068
  // Returns the found code or undefined if absent.
6069
  Object* FindInCodeCache(Name* name, Code::Flags flags);
6070

    
6071
  // Returns the non-negative index of the code object if it is in the
6072
  // cache and -1 otherwise.
6073
  int IndexInCodeCache(Object* name, Code* code);
6074

    
6075
  // Removes a code object from the code cache at the given index.
6076
  void RemoveFromCodeCache(Name* name, Code* code, int index);
6077

    
6078
  // Set all map transitions from this map to dead maps to null.  Also clear
6079
  // back pointers in transition targets so that we do not process this map
6080
  // again while following back pointers.
6081
  void ClearNonLiveTransitions(Heap* heap);
6082

    
6083
  // Computes a hash value for this map, to be used in HashTables and such.
6084
  int Hash();
6085

    
6086
  bool EquivalentToForTransition(Map* other);
6087

    
6088
  // Compares this map to another to see if they describe equivalent objects.
6089
  // If |mode| is set to CLEAR_INOBJECT_PROPERTIES, |other| is treated as if
6090
  // it had exactly zero inobject properties.
6091
  // The "shared" flags of both this map and |other| are ignored.
6092
  bool EquivalentToForNormalization(Map* other, PropertyNormalizationMode mode);
6093

    
6094
  // Returns the map that this map transitions to if its elements_kind
6095
  // is changed to |elements_kind|, or NULL if no such map is cached yet.
6096
  // |safe_to_add_transitions| is set to false if adding transitions is not
6097
  // allowed.
6098
  Map* LookupElementsTransitionMap(ElementsKind elements_kind);
6099

    
6100
  // Returns the transitioned map for this map with the most generic
6101
  // elements_kind that's found in |candidates|, or null handle if no match is
6102
  // found at all.
6103
  Handle<Map> FindTransitionedMap(MapHandleList* candidates);
6104
  Map* FindTransitionedMap(MapList* candidates);
6105

    
6106
  // Zaps the contents of backing data structures. Note that the
6107
  // heap verifier (i.e. VerifyMarkingVisitor) relies on zapping of objects
6108
  // holding weak references when incremental marking is used, because it also
6109
  // iterates over objects that are otherwise unreachable.
6110
  // In general we only want to call these functions in release mode when
6111
  // heap verification is turned on.
6112
  void ZapPrototypeTransitions();
6113
  void ZapTransitions();
6114

    
6115
  bool CanTransition() {
6116
    // Only JSObject and subtypes have map transitions and back pointers.
6117
    STATIC_ASSERT(LAST_TYPE == LAST_JS_OBJECT_TYPE);
6118
    return instance_type() >= FIRST_JS_OBJECT_TYPE;
6119
  }
6120

    
6121
  bool IsJSObjectMap() {
6122
    return instance_type() >= FIRST_JS_OBJECT_TYPE;
6123
  }
6124

    
6125
  // Fires when the layout of an object with a leaf map changes.
6126
  // This includes adding transitions to the leaf map or changing
6127
  // the descriptor array.
6128
  inline void NotifyLeafMapLayoutChange();
6129

    
6130
  inline bool CanOmitMapChecks();
6131

    
6132
  void AddDependentCompilationInfo(DependentCode::DependencyGroup group,
6133
                                   CompilationInfo* info);
6134

    
6135
  void AddDependentCode(DependentCode::DependencyGroup group,
6136
                        Handle<Code> code);
6137

    
6138
  bool IsMapInArrayPrototypeChain();
6139

    
6140
  // Dispatched behavior.
6141
  DECLARE_PRINTER(Map)
6142
  DECLARE_VERIFIER(Map)
6143

    
6144
#ifdef VERIFY_HEAP
6145
  void SharedMapVerify();
6146
  void VerifyOmittedMapChecks();
6147
#endif
6148

    
6149
  inline int visitor_id();
6150
  inline void set_visitor_id(int visitor_id);
6151

    
6152
  typedef void (*TraverseCallback)(Map* map, void* data);
6153

    
6154
  void TraverseTransitionTree(TraverseCallback callback, void* data);
6155

    
6156
  // When you set the prototype of an object using the __proto__ accessor you
6157
  // need a new map for the object (the prototype is stored in the map).  In
6158
  // order not to multiply maps unnecessarily we store these as transitions in
6159
  // the original map.  That way we can transition to the same map if the same
6160
  // prototype is set, rather than creating a new map every time.  The
6161
  // transitions are in the form of a map where the keys are prototype objects
6162
  // and the values are the maps the are transitioned to.
6163
  static const int kMaxCachedPrototypeTransitions = 256;
6164
  static Handle<Map> GetPrototypeTransition(Handle<Map> map,
6165
                                            Handle<Object> prototype);
6166
  static Handle<Map> PutPrototypeTransition(Handle<Map> map,
6167
                                            Handle<Object> prototype,
6168
                                            Handle<Map> target_map);
6169

    
6170
  static const int kMaxPreAllocatedPropertyFields = 255;
6171

    
6172
  // Constant for denoting that the enum cache is not yet initialized.
6173
  static const int kInvalidEnumCache = EnumLengthBits::kMax;
6174

    
6175
  // Layout description.
6176
  static const int kInstanceSizesOffset = HeapObject::kHeaderSize;
6177
  static const int kInstanceAttributesOffset = kInstanceSizesOffset + kIntSize;
6178
  static const int kPrototypeOffset = kInstanceAttributesOffset + kIntSize;
6179
  static const int kConstructorOffset = kPrototypeOffset + kPointerSize;
6180
  // Storage for the transition array is overloaded to directly contain a back
6181
  // pointer if unused. When the map has transitions, the back pointer is
6182
  // transferred to the transition array and accessed through an extra
6183
  // indirection.
6184
  static const int kTransitionsOrBackPointerOffset =
6185
      kConstructorOffset + kPointerSize;
6186
  static const int kDescriptorsOffset =
6187
      kTransitionsOrBackPointerOffset + kPointerSize;
6188
  static const int kCodeCacheOffset = kDescriptorsOffset + kPointerSize;
6189
  static const int kDependentCodeOffset = kCodeCacheOffset + kPointerSize;
6190
  static const int kBitField3Offset = kDependentCodeOffset + kPointerSize;
6191
  static const int kSize = kBitField3Offset + kPointerSize;
6192

    
6193
  // Layout of pointer fields. Heap iteration code relies on them
6194
  // being continuously allocated.
6195
  static const int kPointerFieldsBeginOffset = Map::kPrototypeOffset;
6196
  static const int kPointerFieldsEndOffset = kBitField3Offset + kPointerSize;
6197

    
6198
  // Byte offsets within kInstanceSizesOffset.
6199
  static const int kInstanceSizeOffset = kInstanceSizesOffset + 0;
6200
  static const int kInObjectPropertiesByte = 1;
6201
  static const int kInObjectPropertiesOffset =
6202
      kInstanceSizesOffset + kInObjectPropertiesByte;
6203
  static const int kPreAllocatedPropertyFieldsByte = 2;
6204
  static const int kPreAllocatedPropertyFieldsOffset =
6205
      kInstanceSizesOffset + kPreAllocatedPropertyFieldsByte;
6206
  static const int kVisitorIdByte = 3;
6207
  static const int kVisitorIdOffset = kInstanceSizesOffset + kVisitorIdByte;
6208

    
6209
  // Byte offsets within kInstanceAttributesOffset attributes.
6210
  static const int kInstanceTypeOffset = kInstanceAttributesOffset + 0;
6211
  static const int kUnusedPropertyFieldsOffset = kInstanceAttributesOffset + 1;
6212
  static const int kBitFieldOffset = kInstanceAttributesOffset + 2;
6213
  static const int kBitField2Offset = kInstanceAttributesOffset + 3;
6214

    
6215
  STATIC_CHECK(kInstanceTypeOffset == Internals::kMapInstanceTypeOffset);
6216

    
6217
  // Bit positions for bit field.
6218
  static const int kUnused = 0;  // To be used for marking recently used maps.
6219
  static const int kHasNonInstancePrototype = 1;
6220
  static const int kIsHiddenPrototype = 2;
6221
  static const int kHasNamedInterceptor = 3;
6222
  static const int kHasIndexedInterceptor = 4;
6223
  static const int kIsUndetectable = 5;
6224
  static const int kHasInstanceCallHandler = 6;
6225
  static const int kIsAccessCheckNeeded = 7;
6226

    
6227
  // Bit positions for bit field 2
6228
  static const int kIsExtensible = 0;
6229
  static const int kStringWrapperSafeForDefaultValueOf = 1;
6230
  static const int kAttachedToSharedFunctionInfo = 2;
6231
  // No bits can be used after kElementsKindFirstBit, they are all reserved for
6232
  // storing ElementKind.
6233
  static const int kElementsKindShift = 3;
6234
  static const int kElementsKindBitCount = 5;
6235

    
6236
  // Derived values from bit field 2
6237
  static const int kElementsKindMask = (-1 << kElementsKindShift) &
6238
      ((1 << (kElementsKindShift + kElementsKindBitCount)) - 1);
6239
  static const int8_t kMaximumBitField2FastElementValue = static_cast<int8_t>(
6240
      (FAST_ELEMENTS + 1) << Map::kElementsKindShift) - 1;
6241
  static const int8_t kMaximumBitField2FastSmiElementValue =
6242
      static_cast<int8_t>((FAST_SMI_ELEMENTS + 1) <<
6243
                          Map::kElementsKindShift) - 1;
6244
  static const int8_t kMaximumBitField2FastHoleyElementValue =
6245
      static_cast<int8_t>((FAST_HOLEY_ELEMENTS + 1) <<
6246
                          Map::kElementsKindShift) - 1;
6247
  static const int8_t kMaximumBitField2FastHoleySmiElementValue =
6248
      static_cast<int8_t>((FAST_HOLEY_SMI_ELEMENTS + 1) <<
6249
                          Map::kElementsKindShift) - 1;
6250

    
6251
  typedef FixedBodyDescriptor<kPointerFieldsBeginOffset,
6252
                              kPointerFieldsEndOffset,
6253
                              kSize> BodyDescriptor;
6254

    
6255
 private:
6256
  DISALLOW_IMPLICIT_CONSTRUCTORS(Map);
6257
};
6258

    
6259

    
6260
// An abstract superclass, a marker class really, for simple structure classes.
6261
// It doesn't carry much functionality but allows struct classes to be
6262
// identified in the type system.
6263
class Struct: public HeapObject {
6264
 public:
6265
  inline void InitializeBody(int object_size);
6266
  static inline Struct* cast(Object* that);
6267
};
6268

    
6269

    
6270
// A simple one-element struct, useful where smis need to be boxed.
6271
class Box : public Struct {
6272
 public:
6273
  // [value]: the boxed contents.
6274
  DECL_ACCESSORS(value, Object)
6275

    
6276
  static inline Box* cast(Object* obj);
6277

    
6278
  // Dispatched behavior.
6279
  DECLARE_PRINTER(Box)
6280
  DECLARE_VERIFIER(Box)
6281

    
6282
  static const int kValueOffset = HeapObject::kHeaderSize;
6283
  static const int kSize = kValueOffset + kPointerSize;
6284

    
6285
 private:
6286
  DISALLOW_IMPLICIT_CONSTRUCTORS(Box);
6287
};
6288

    
6289

    
6290
// Script describes a script which has been added to the VM.
6291
class Script: public Struct {
6292
 public:
6293
  // Script types.
6294
  enum Type {
6295
    TYPE_NATIVE = 0,
6296
    TYPE_EXTENSION = 1,
6297
    TYPE_NORMAL = 2
6298
  };
6299

    
6300
  // Script compilation types.
6301
  enum CompilationType {
6302
    COMPILATION_TYPE_HOST = 0,
6303
    COMPILATION_TYPE_EVAL = 1
6304
  };
6305

    
6306
  // Script compilation state.
6307
  enum CompilationState {
6308
    COMPILATION_STATE_INITIAL = 0,
6309
    COMPILATION_STATE_COMPILED = 1
6310
  };
6311

    
6312
  // [source]: the script source.
6313
  DECL_ACCESSORS(source, Object)
6314

    
6315
  // [name]: the script name.
6316
  DECL_ACCESSORS(name, Object)
6317

    
6318
  // [id]: the script id.
6319
  DECL_ACCESSORS(id, Smi)
6320

    
6321
  // [line_offset]: script line offset in resource from where it was extracted.
6322
  DECL_ACCESSORS(line_offset, Smi)
6323

    
6324
  // [column_offset]: script column offset in resource from where it was
6325
  // extracted.
6326
  DECL_ACCESSORS(column_offset, Smi)
6327

    
6328
  // [data]: additional data associated with this script.
6329
  DECL_ACCESSORS(data, Object)
6330

    
6331
  // [context_data]: context data for the context this script was compiled in.
6332
  DECL_ACCESSORS(context_data, Object)
6333

    
6334
  // [wrapper]: the wrapper cache.
6335
  DECL_ACCESSORS(wrapper, Foreign)
6336

    
6337
  // [type]: the script type.
6338
  DECL_ACCESSORS(type, Smi)
6339

    
6340
  // [line_ends]: FixedArray of line ends positions.
6341
  DECL_ACCESSORS(line_ends, Object)
6342

    
6343
  // [eval_from_shared]: for eval scripts the shared funcion info for the
6344
  // function from which eval was called.
6345
  DECL_ACCESSORS(eval_from_shared, Object)
6346

    
6347
  // [eval_from_instructions_offset]: the instruction offset in the code for the
6348
  // function from which eval was called where eval was called.
6349
  DECL_ACCESSORS(eval_from_instructions_offset, Smi)
6350

    
6351
  // [flags]: Holds an exciting bitfield.
6352
  DECL_ACCESSORS(flags, Smi)
6353

    
6354
  // [compilation_type]: how the the script was compiled. Encoded in the
6355
  // 'flags' field.
6356
  inline CompilationType compilation_type();
6357
  inline void set_compilation_type(CompilationType type);
6358

    
6359
  // [compilation_state]: determines whether the script has already been
6360
  // compiled. Encoded in the 'flags' field.
6361
  inline CompilationState compilation_state();
6362
  inline void set_compilation_state(CompilationState state);
6363

    
6364
  // [is_shared_cross_origin]: An opaque boolean set by the embedder via
6365
  // ScriptOrigin, and used by the embedder to make decisions about the
6366
  // script's level of privilege. V8 just passes this through. Encoded in
6367
  // the 'flags' field.
6368
  DECL_BOOLEAN_ACCESSORS(is_shared_cross_origin)
6369

    
6370
  static inline Script* cast(Object* obj);
6371

    
6372
  // If script source is an external string, check that the underlying
6373
  // resource is accessible. Otherwise, always return true.
6374
  inline bool HasValidSource();
6375

    
6376
  // Dispatched behavior.
6377
  DECLARE_PRINTER(Script)
6378
  DECLARE_VERIFIER(Script)
6379

    
6380
  static const int kSourceOffset = HeapObject::kHeaderSize;
6381
  static const int kNameOffset = kSourceOffset + kPointerSize;
6382
  static const int kLineOffsetOffset = kNameOffset + kPointerSize;
6383
  static const int kColumnOffsetOffset = kLineOffsetOffset + kPointerSize;
6384
  static const int kDataOffset = kColumnOffsetOffset + kPointerSize;
6385
  static const int kContextOffset = kDataOffset + kPointerSize;
6386
  static const int kWrapperOffset = kContextOffset + kPointerSize;
6387
  static const int kTypeOffset = kWrapperOffset + kPointerSize;
6388
  static const int kLineEndsOffset = kTypeOffset + kPointerSize;
6389
  static const int kIdOffset = kLineEndsOffset + kPointerSize;
6390
  static const int kEvalFromSharedOffset = kIdOffset + kPointerSize;
6391
  static const int kEvalFrominstructionsOffsetOffset =
6392
      kEvalFromSharedOffset + kPointerSize;
6393
  static const int kFlagsOffset =
6394
      kEvalFrominstructionsOffsetOffset + kPointerSize;
6395
  static const int kSize = kFlagsOffset + kPointerSize;
6396

    
6397
 private:
6398
  // Bit positions in the flags field.
6399
  static const int kCompilationTypeBit = 0;
6400
  static const int kCompilationStateBit = 1;
6401
  static const int kIsSharedCrossOriginBit = 2;
6402

    
6403
  DISALLOW_IMPLICIT_CONSTRUCTORS(Script);
6404
};
6405

    
6406

    
6407
// List of builtin functions we want to identify to improve code
6408
// generation.
6409
//
6410
// Each entry has a name of a global object property holding an object
6411
// optionally followed by ".prototype", a name of a builtin function
6412
// on the object (the one the id is set for), and a label.
6413
//
6414
// Installation of ids for the selected builtin functions is handled
6415
// by the bootstrapper.
6416
#define FUNCTIONS_WITH_ID_LIST(V)                   \
6417
  V(Array.prototype, push, ArrayPush)               \
6418
  V(Array.prototype, pop, ArrayPop)                 \
6419
  V(Function.prototype, apply, FunctionApply)       \
6420
  V(String.prototype, charCodeAt, StringCharCodeAt) \
6421
  V(String.prototype, charAt, StringCharAt)         \
6422
  V(String, fromCharCode, StringFromCharCode)       \
6423
  V(Math, floor, MathFloor)                         \
6424
  V(Math, round, MathRound)                         \
6425
  V(Math, ceil, MathCeil)                           \
6426
  V(Math, abs, MathAbs)                             \
6427
  V(Math, log, MathLog)                             \
6428
  V(Math, sin, MathSin)                             \
6429
  V(Math, cos, MathCos)                             \
6430
  V(Math, tan, MathTan)                             \
6431
  V(Math, asin, MathASin)                           \
6432
  V(Math, acos, MathACos)                           \
6433
  V(Math, atan, MathATan)                           \
6434
  V(Math, exp, MathExp)                             \
6435
  V(Math, sqrt, MathSqrt)                           \
6436
  V(Math, pow, MathPow)                             \
6437
  V(Math, random, MathRandom)                       \
6438
  V(Math, max, MathMax)                             \
6439
  V(Math, min, MathMin)                             \
6440
  V(Math, imul, MathImul)
6441

    
6442
enum BuiltinFunctionId {
6443
  kArrayCode,
6444
#define DECLARE_FUNCTION_ID(ignored1, ignore2, name)    \
6445
  k##name,
6446
  FUNCTIONS_WITH_ID_LIST(DECLARE_FUNCTION_ID)
6447
#undef DECLARE_FUNCTION_ID
6448
  // Fake id for a special case of Math.pow. Note, it continues the
6449
  // list of math functions.
6450
  kMathPowHalf
6451
};
6452

    
6453

    
6454
// SharedFunctionInfo describes the JSFunction information that can be
6455
// shared by multiple instances of the function.
6456
class SharedFunctionInfo: public HeapObject {
6457
 public:
6458
  // [name]: Function name.
6459
  DECL_ACCESSORS(name, Object)
6460

    
6461
  // [code]: Function code.
6462
  DECL_ACCESSORS(code, Code)
6463
  inline void ReplaceCode(Code* code);
6464

    
6465
  // [optimized_code_map]: Map from native context to optimized code
6466
  // and a shared literals array or Smi(0) if none.
6467
  DECL_ACCESSORS(optimized_code_map, Object)
6468

    
6469
  // Returns index i of the entry with the specified context. At position
6470
  // i - 1 is the context, position i the code, and i + 1 the literals array.
6471
  // Returns -1 when no matching entry is found.
6472
  int SearchOptimizedCodeMap(Context* native_context);
6473

    
6474
  // Installs optimized code from the code map on the given closure. The
6475
  // index has to be consistent with a search result as defined above.
6476
  void InstallFromOptimizedCodeMap(JSFunction* function, int index);
6477

    
6478
  // Clear optimized code map.
6479
  void ClearOptimizedCodeMap();
6480

    
6481
  // Removed a specific optimized code object from the optimized code map.
6482
  void EvictFromOptimizedCodeMap(Code* optimized_code, const char* reason);
6483

    
6484
  // Trims the optimized code map after entries have been removed.
6485
  void TrimOptimizedCodeMap(int shrink_by);
6486

    
6487
  // Add a new entry to the optimized code map.
6488
  MUST_USE_RESULT MaybeObject* AddToOptimizedCodeMap(Context* native_context,
6489
                                                     Code* code,
6490
                                                     FixedArray* literals);
6491
  static void AddToOptimizedCodeMap(Handle<SharedFunctionInfo> shared,
6492
                                    Handle<Context> native_context,
6493
                                    Handle<Code> code,
6494
                                    Handle<FixedArray> literals);
6495

    
6496
  // Layout description of the optimized code map.
6497
  static const int kNextMapIndex = 0;
6498
  static const int kEntriesStart = 1;
6499
  static const int kEntryLength = 3;
6500
  static const int kFirstContextSlot = FixedArray::kHeaderSize + kPointerSize;
6501
  static const int kFirstCodeSlot = FixedArray::kHeaderSize + 2 * kPointerSize;
6502
  static const int kSecondEntryIndex = kEntryLength + kEntriesStart;
6503
  static const int kInitialLength = kEntriesStart + kEntryLength;
6504

    
6505
  // [scope_info]: Scope info.
6506
  DECL_ACCESSORS(scope_info, ScopeInfo)
6507

    
6508
  // [construct stub]: Code stub for constructing instances of this function.
6509
  DECL_ACCESSORS(construct_stub, Code)
6510

    
6511
  // Returns if this function has been compiled to native code yet.
6512
  inline bool is_compiled();
6513

    
6514
  // [length]: The function length - usually the number of declared parameters.
6515
  // Use up to 2^30 parameters.
6516
  inline int length();
6517
  inline void set_length(int value);
6518

    
6519
  // [formal parameter count]: The declared number of parameters.
6520
  inline int formal_parameter_count();
6521
  inline void set_formal_parameter_count(int value);
6522

    
6523
  // Set the formal parameter count so the function code will be
6524
  // called without using argument adaptor frames.
6525
  inline void DontAdaptArguments();
6526

    
6527
  // [expected_nof_properties]: Expected number of properties for the function.
6528
  inline int expected_nof_properties();
6529
  inline void set_expected_nof_properties(int value);
6530

    
6531
  // Inobject slack tracking is the way to reclaim unused inobject space.
6532
  //
6533
  // The instance size is initially determined by adding some slack to
6534
  // expected_nof_properties (to allow for a few extra properties added
6535
  // after the constructor). There is no guarantee that the extra space
6536
  // will not be wasted.
6537
  //
6538
  // Here is the algorithm to reclaim the unused inobject space:
6539
  // - Detect the first constructor call for this SharedFunctionInfo.
6540
  //   When it happens enter the "in progress" state: remember the
6541
  //   constructor's initial_map and install a special construct stub that
6542
  //   counts constructor calls.
6543
  // - While the tracking is in progress create objects filled with
6544
  //   one_pointer_filler_map instead of undefined_value. This way they can be
6545
  //   resized quickly and safely.
6546
  // - Once enough (kGenerousAllocationCount) objects have been created
6547
  //   compute the 'slack' (traverse the map transition tree starting from the
6548
  //   initial_map and find the lowest value of unused_property_fields).
6549
  // - Traverse the transition tree again and decrease the instance size
6550
  //   of every map. Existing objects will resize automatically (they are
6551
  //   filled with one_pointer_filler_map). All further allocations will
6552
  //   use the adjusted instance size.
6553
  // - Decrease expected_nof_properties so that an allocations made from
6554
  //   another context will use the adjusted instance size too.
6555
  // - Exit "in progress" state by clearing the reference to the initial_map
6556
  //   and setting the regular construct stub (generic or inline).
6557
  //
6558
  //  The above is the main event sequence. Some special cases are possible
6559
  //  while the tracking is in progress:
6560
  //
6561
  // - GC occurs.
6562
  //   Check if the initial_map is referenced by any live objects (except this
6563
  //   SharedFunctionInfo). If it is, continue tracking as usual.
6564
  //   If it is not, clear the reference and reset the tracking state. The
6565
  //   tracking will be initiated again on the next constructor call.
6566
  //
6567
  // - The constructor is called from another context.
6568
  //   Immediately complete the tracking, perform all the necessary changes
6569
  //   to maps. This is  necessary because there is no efficient way to track
6570
  //   multiple initial_maps.
6571
  //   Proceed to create an object in the current context (with the adjusted
6572
  //   size).
6573
  //
6574
  // - A different constructor function sharing the same SharedFunctionInfo is
6575
  //   called in the same context. This could be another closure in the same
6576
  //   context, or the first function could have been disposed.
6577
  //   This is handled the same way as the previous case.
6578
  //
6579
  //  Important: inobject slack tracking is not attempted during the snapshot
6580
  //  creation.
6581

    
6582
  static const int kGenerousAllocationCount = 8;
6583

    
6584
  // [construction_count]: Counter for constructor calls made during
6585
  // the tracking phase.
6586
  inline int construction_count();
6587
  inline void set_construction_count(int value);
6588

    
6589
  // [initial_map]: initial map of the first function called as a constructor.
6590
  // Saved for the duration of the tracking phase.
6591
  // This is a weak link (GC resets it to undefined_value if no other live
6592
  // object reference this map).
6593
  DECL_ACCESSORS(initial_map, Object)
6594

    
6595
  // True if the initial_map is not undefined and the countdown stub is
6596
  // installed.
6597
  inline bool IsInobjectSlackTrackingInProgress();
6598

    
6599
  // Starts the tracking.
6600
  // Stores the initial map and installs the countdown stub.
6601
  // IsInobjectSlackTrackingInProgress is normally true after this call,
6602
  // except when tracking have not been started (e.g. the map has no unused
6603
  // properties or the snapshot is being built).
6604
  void StartInobjectSlackTracking(Map* map);
6605

    
6606
  // Completes the tracking.
6607
  // IsInobjectSlackTrackingInProgress is false after this call.
6608
  void CompleteInobjectSlackTracking();
6609

    
6610
  // Invoked before pointers in SharedFunctionInfo are being marked.
6611
  // Also clears the optimized code map.
6612
  inline void BeforeVisitingPointers();
6613

    
6614
  // Clears the initial_map before the GC marking phase to ensure the reference
6615
  // is weak. IsInobjectSlackTrackingInProgress is false after this call.
6616
  void DetachInitialMap();
6617

    
6618
  // Restores the link to the initial map after the GC marking phase.
6619
  // IsInobjectSlackTrackingInProgress is true after this call.
6620
  void AttachInitialMap(Map* map);
6621

    
6622
  // False if there are definitely no live objects created from this function.
6623
  // True if live objects _may_ exist (existence not guaranteed).
6624
  // May go back from true to false after GC.
6625
  DECL_BOOLEAN_ACCESSORS(live_objects_may_exist)
6626

    
6627
  // [instance class name]: class name for instances.
6628
  DECL_ACCESSORS(instance_class_name, Object)
6629

    
6630
  // [function data]: This field holds some additional data for function.
6631
  // Currently it either has FunctionTemplateInfo to make benefit the API
6632
  // or Smi identifying a builtin function.
6633
  // In the long run we don't want all functions to have this field but
6634
  // we can fix that when we have a better model for storing hidden data
6635
  // on objects.
6636
  DECL_ACCESSORS(function_data, Object)
6637

    
6638
  inline bool IsApiFunction();
6639
  inline FunctionTemplateInfo* get_api_func_data();
6640
  inline bool HasBuiltinFunctionId();
6641
  inline BuiltinFunctionId builtin_function_id();
6642

    
6643
  // [script info]: Script from which the function originates.
6644
  DECL_ACCESSORS(script, Object)
6645

    
6646
  // [num_literals]: Number of literals used by this function.
6647
  inline int num_literals();
6648
  inline void set_num_literals(int value);
6649

    
6650
  // [start_position_and_type]: Field used to store both the source code
6651
  // position, whether or not the function is a function expression,
6652
  // and whether or not the function is a toplevel function. The two
6653
  // least significants bit indicates whether the function is an
6654
  // expression and the rest contains the source code position.
6655
  inline int start_position_and_type();
6656
  inline void set_start_position_and_type(int value);
6657

    
6658
  // [debug info]: Debug information.
6659
  DECL_ACCESSORS(debug_info, Object)
6660

    
6661
  // [inferred name]: Name inferred from variable or property
6662
  // assignment of this function. Used to facilitate debugging and
6663
  // profiling of JavaScript code written in OO style, where almost
6664
  // all functions are anonymous but are assigned to object
6665
  // properties.
6666
  DECL_ACCESSORS(inferred_name, String)
6667

    
6668
  // The function's name if it is non-empty, otherwise the inferred name.
6669
  String* DebugName();
6670

    
6671
  // Position of the 'function' token in the script source.
6672
  inline int function_token_position();
6673
  inline void set_function_token_position(int function_token_position);
6674

    
6675
  // Position of this function in the script source.
6676
  inline int start_position();
6677
  inline void set_start_position(int start_position);
6678

    
6679
  // End position of this function in the script source.
6680
  inline int end_position();
6681
  inline void set_end_position(int end_position);
6682

    
6683
  // Is this function a function expression in the source code.
6684
  DECL_BOOLEAN_ACCESSORS(is_expression)
6685

    
6686
  // Is this function a top-level function (scripts, evals).
6687
  DECL_BOOLEAN_ACCESSORS(is_toplevel)
6688

    
6689
  // Bit field containing various information collected by the compiler to
6690
  // drive optimization.
6691
  inline int compiler_hints();
6692
  inline void set_compiler_hints(int value);
6693

    
6694
  inline int ast_node_count();
6695
  inline void set_ast_node_count(int count);
6696

    
6697
  inline int profiler_ticks();
6698

    
6699
  // Inline cache age is used to infer whether the function survived a context
6700
  // disposal or not. In the former case we reset the opt_count.
6701
  inline int ic_age();
6702
  inline void set_ic_age(int age);
6703

    
6704
  // Indicates if this function can be lazy compiled.
6705
  // This is used to determine if we can safely flush code from a function
6706
  // when doing GC if we expect that the function will no longer be used.
6707
  DECL_BOOLEAN_ACCESSORS(allows_lazy_compilation)
6708

    
6709
  // Indicates if this function can be lazy compiled without a context.
6710
  // This is used to determine if we can force compilation without reaching
6711
  // the function through program execution but through other means (e.g. heap
6712
  // iteration by the debugger).
6713
  DECL_BOOLEAN_ACCESSORS(allows_lazy_compilation_without_context)
6714

    
6715
  // Indicates whether optimizations have been disabled for this
6716
  // shared function info. If a function is repeatedly optimized or if
6717
  // we cannot optimize the function we disable optimization to avoid
6718
  // spending time attempting to optimize it again.
6719
  DECL_BOOLEAN_ACCESSORS(optimization_disabled)
6720

    
6721
  // Indicates the language mode of the function's code as defined by the
6722
  // current harmony drafts for the next ES language standard. Possible
6723
  // values are:
6724
  // 1. CLASSIC_MODE - Unrestricted syntax and semantics, same as in ES5.
6725
  // 2. STRICT_MODE - Restricted syntax and semantics, same as in ES5.
6726
  // 3. EXTENDED_MODE - Only available under the harmony flag, not part of ES5.
6727
  inline LanguageMode language_mode();
6728
  inline void set_language_mode(LanguageMode language_mode);
6729

    
6730
  // Indicates whether the language mode of this function is CLASSIC_MODE.
6731
  inline bool is_classic_mode();
6732

    
6733
  // Indicates whether the language mode of this function is EXTENDED_MODE.
6734
  inline bool is_extended_mode();
6735

    
6736
  // False if the function definitely does not allocate an arguments object.
6737
  DECL_BOOLEAN_ACCESSORS(uses_arguments)
6738

    
6739
  // True if the function has any duplicated parameter names.
6740
  DECL_BOOLEAN_ACCESSORS(has_duplicate_parameters)
6741

    
6742
  // Indicates whether the function is a native function.
6743
  // These needs special treatment in .call and .apply since
6744
  // null passed as the receiver should not be translated to the
6745
  // global object.
6746
  DECL_BOOLEAN_ACCESSORS(native)
6747

    
6748
  // Indicates that the function was created by the Function function.
6749
  // Though it's anonymous, toString should treat it as if it had the name
6750
  // "anonymous".  We don't set the name itself so that the system does not
6751
  // see a binding for it.
6752
  DECL_BOOLEAN_ACCESSORS(name_should_print_as_anonymous)
6753

    
6754
  // Indicates whether the function is a bound function created using
6755
  // the bind function.
6756
  DECL_BOOLEAN_ACCESSORS(bound)
6757

    
6758
  // Indicates that the function is anonymous (the name field can be set
6759
  // through the API, which does not change this flag).
6760
  DECL_BOOLEAN_ACCESSORS(is_anonymous)
6761

    
6762
  // Is this a function or top-level/eval code.
6763
  DECL_BOOLEAN_ACCESSORS(is_function)
6764

    
6765
  // Indicates that the function cannot be optimized.
6766
  DECL_BOOLEAN_ACCESSORS(dont_optimize)
6767

    
6768
  // Indicates that the function cannot be inlined.
6769
  DECL_BOOLEAN_ACCESSORS(dont_inline)
6770

    
6771
  // Indicates that code for this function cannot be cached.
6772
  DECL_BOOLEAN_ACCESSORS(dont_cache)
6773

    
6774
  // Indicates that code for this function cannot be flushed.
6775
  DECL_BOOLEAN_ACCESSORS(dont_flush)
6776

    
6777
  // Indicates that this function is a generator.
6778
  DECL_BOOLEAN_ACCESSORS(is_generator)
6779

    
6780
  // Indicates whether or not the code in the shared function support
6781
  // deoptimization.
6782
  inline bool has_deoptimization_support();
6783

    
6784
  // Enable deoptimization support through recompiled code.
6785
  void EnableDeoptimizationSupport(Code* recompiled);
6786

    
6787
  // Disable (further) attempted optimization of all functions sharing this
6788
  // shared function info.
6789
  void DisableOptimization(BailoutReason reason);
6790

    
6791
  inline BailoutReason DisableOptimizationReason();
6792

    
6793
  // Lookup the bailout ID and ASSERT that it exists in the non-optimized
6794
  // code, returns whether it asserted (i.e., always true if assertions are
6795
  // disabled).
6796
  bool VerifyBailoutId(BailoutId id);
6797

    
6798
  // [source code]: Source code for the function.
6799
  bool HasSourceCode();
6800
  Handle<Object> GetSourceCode();
6801

    
6802
  // Number of times the function was optimized.
6803
  inline int opt_count();
6804
  inline void set_opt_count(int opt_count);
6805

    
6806
  // Number of times the function was deoptimized.
6807
  inline void set_deopt_count(int value);
6808
  inline int deopt_count();
6809
  inline void increment_deopt_count();
6810

    
6811
  // Number of time we tried to re-enable optimization after it
6812
  // was disabled due to high number of deoptimizations.
6813
  inline void set_opt_reenable_tries(int value);
6814
  inline int opt_reenable_tries();
6815

    
6816
  inline void TryReenableOptimization();
6817

    
6818
  // Stores deopt_count, opt_reenable_tries and ic_age as bit-fields.
6819
  inline void set_counters(int value);
6820
  inline int counters();
6821

    
6822
  // Stores opt_count and bailout_reason as bit-fields.
6823
  inline void set_opt_count_and_bailout_reason(int value);
6824
  inline int opt_count_and_bailout_reason();
6825

    
6826
  void set_bailout_reason(BailoutReason reason) {
6827
    set_opt_count_and_bailout_reason(
6828
        DisabledOptimizationReasonBits::update(opt_count_and_bailout_reason(),
6829
                                               reason));
6830
  }
6831

    
6832
  void set_dont_optimize_reason(BailoutReason reason) {
6833
    set_bailout_reason(reason);
6834
    set_dont_optimize(reason != kNoReason);
6835
  }
6836

    
6837
  // Source size of this function.
6838
  int SourceSize();
6839

    
6840
  // Calculate the instance size.
6841
  int CalculateInstanceSize();
6842

    
6843
  // Calculate the number of in-object properties.
6844
  int CalculateInObjectProperties();
6845

    
6846
  // Dispatched behavior.
6847
  // Set max_length to -1 for unlimited length.
6848
  void SourceCodePrint(StringStream* accumulator, int max_length);
6849
  DECLARE_PRINTER(SharedFunctionInfo)
6850
  DECLARE_VERIFIER(SharedFunctionInfo)
6851

    
6852
  void ResetForNewContext(int new_ic_age);
6853

    
6854
  // Helper to compile the shared code.  Returns true on success, false on
6855
  // failure (e.g., stack overflow during compilation). This is only used by
6856
  // the debugger, it is not possible to compile without a context otherwise.
6857
  static bool CompileLazy(Handle<SharedFunctionInfo> shared,
6858
                          ClearExceptionFlag flag);
6859

    
6860
  // Casting.
6861
  static inline SharedFunctionInfo* cast(Object* obj);
6862

    
6863
  // Constants.
6864
  static const int kDontAdaptArgumentsSentinel = -1;
6865

    
6866
  // Layout description.
6867
  // Pointer fields.
6868
  static const int kNameOffset = HeapObject::kHeaderSize;
6869
  static const int kCodeOffset = kNameOffset + kPointerSize;
6870
  static const int kOptimizedCodeMapOffset = kCodeOffset + kPointerSize;
6871
  static const int kScopeInfoOffset = kOptimizedCodeMapOffset + kPointerSize;
6872
  static const int kConstructStubOffset = kScopeInfoOffset + kPointerSize;
6873
  static const int kInstanceClassNameOffset =
6874
      kConstructStubOffset + kPointerSize;
6875
  static const int kFunctionDataOffset =
6876
      kInstanceClassNameOffset + kPointerSize;
6877
  static const int kScriptOffset = kFunctionDataOffset + kPointerSize;
6878
  static const int kDebugInfoOffset = kScriptOffset + kPointerSize;
6879
  static const int kInferredNameOffset = kDebugInfoOffset + kPointerSize;
6880
  static const int kInitialMapOffset =
6881
      kInferredNameOffset + kPointerSize;
6882
  // ast_node_count is a Smi field. It could be grouped with another Smi field
6883
  // into a PSEUDO_SMI_ACCESSORS pair (on x64), if one becomes available.
6884
  static const int kAstNodeCountOffset =
6885
      kInitialMapOffset + kPointerSize;
6886
#if V8_HOST_ARCH_32_BIT
6887
  // Smi fields.
6888
  static const int kLengthOffset =
6889
      kAstNodeCountOffset + kPointerSize;
6890
  static const int kFormalParameterCountOffset = kLengthOffset + kPointerSize;
6891
  static const int kExpectedNofPropertiesOffset =
6892
      kFormalParameterCountOffset + kPointerSize;
6893
  static const int kNumLiteralsOffset =
6894
      kExpectedNofPropertiesOffset + kPointerSize;
6895
  static const int kStartPositionAndTypeOffset =
6896
      kNumLiteralsOffset + kPointerSize;
6897
  static const int kEndPositionOffset =
6898
      kStartPositionAndTypeOffset + kPointerSize;
6899
  static const int kFunctionTokenPositionOffset =
6900
      kEndPositionOffset + kPointerSize;
6901
  static const int kCompilerHintsOffset =
6902
      kFunctionTokenPositionOffset + kPointerSize;
6903
  static const int kOptCountAndBailoutReasonOffset =
6904
      kCompilerHintsOffset + kPointerSize;
6905
  static const int kCountersOffset =
6906
      kOptCountAndBailoutReasonOffset + kPointerSize;
6907

    
6908
  // Total size.
6909
  static const int kSize = kCountersOffset + kPointerSize;
6910
#else
6911
  // The only reason to use smi fields instead of int fields
6912
  // is to allow iteration without maps decoding during
6913
  // garbage collections.
6914
  // To avoid wasting space on 64-bit architectures we use
6915
  // the following trick: we group integer fields into pairs
6916
  // First integer in each pair is shifted left by 1.
6917
  // By doing this we guarantee that LSB of each kPointerSize aligned
6918
  // word is not set and thus this word cannot be treated as pointer
6919
  // to HeapObject during old space traversal.
6920
  static const int kLengthOffset =
6921
      kAstNodeCountOffset + kPointerSize;
6922
  static const int kFormalParameterCountOffset =
6923
      kLengthOffset + kIntSize;
6924

    
6925
  static const int kExpectedNofPropertiesOffset =
6926
      kFormalParameterCountOffset + kIntSize;
6927
  static const int kNumLiteralsOffset =
6928
      kExpectedNofPropertiesOffset + kIntSize;
6929

    
6930
  static const int kEndPositionOffset =
6931
      kNumLiteralsOffset + kIntSize;
6932
  static const int kStartPositionAndTypeOffset =
6933
      kEndPositionOffset + kIntSize;
6934

    
6935
  static const int kFunctionTokenPositionOffset =
6936
      kStartPositionAndTypeOffset + kIntSize;
6937
  static const int kCompilerHintsOffset =
6938
      kFunctionTokenPositionOffset + kIntSize;
6939

    
6940
  static const int kOptCountAndBailoutReasonOffset =
6941
      kCompilerHintsOffset + kIntSize;
6942

    
6943
  static const int kCountersOffset =
6944
      kOptCountAndBailoutReasonOffset + kIntSize;
6945

    
6946
  // Total size.
6947
  static const int kSize = kCountersOffset + kIntSize;
6948

    
6949
#endif
6950

    
6951
  // The construction counter for inobject slack tracking is stored in the
6952
  // most significant byte of compiler_hints which is otherwise unused.
6953
  // Its offset depends on the endian-ness of the architecture.
6954
#if __BYTE_ORDER == __LITTLE_ENDIAN
6955
  static const int kConstructionCountOffset = kCompilerHintsOffset + 3;
6956
#elif __BYTE_ORDER == __BIG_ENDIAN
6957
  static const int kConstructionCountOffset = kCompilerHintsOffset + 0;
6958
#else
6959
#error Unknown byte ordering
6960
#endif
6961

    
6962
  static const int kAlignedSize = POINTER_SIZE_ALIGN(kSize);
6963

    
6964
  typedef FixedBodyDescriptor<kNameOffset,
6965
                              kInitialMapOffset + kPointerSize,
6966
                              kSize> BodyDescriptor;
6967

    
6968
  // Bit positions in start_position_and_type.
6969
  // The source code start position is in the 30 most significant bits of
6970
  // the start_position_and_type field.
6971
  static const int kIsExpressionBit    = 0;
6972
  static const int kIsTopLevelBit      = 1;
6973
  static const int kStartPositionShift = 2;
6974
  static const int kStartPositionMask  = ~((1 << kStartPositionShift) - 1);
6975

    
6976
  // Bit positions in compiler_hints.
6977
  enum CompilerHints {
6978
    kAllowLazyCompilation,
6979
    kAllowLazyCompilationWithoutContext,
6980
    kLiveObjectsMayExist,
6981
    kOptimizationDisabled,
6982
    kStrictModeFunction,
6983
    kExtendedModeFunction,
6984
    kUsesArguments,
6985
    kHasDuplicateParameters,
6986
    kNative,
6987
    kBoundFunction,
6988
    kIsAnonymous,
6989
    kNameShouldPrintAsAnonymous,
6990
    kIsFunction,
6991
    kDontOptimize,
6992
    kDontInline,
6993
    kDontCache,
6994
    kDontFlush,
6995
    kIsGenerator,
6996
    kCompilerHintsCount  // Pseudo entry
6997
  };
6998

    
6999
  class DeoptCountBits: public BitField<int, 0, 4> {};
7000
  class OptReenableTriesBits: public BitField<int, 4, 18> {};
7001
  class ICAgeBits: public BitField<int, 22, 8> {};
7002

    
7003
  class OptCountBits: public BitField<int, 0, 22> {};
7004
  class DisabledOptimizationReasonBits: public BitField<int, 22, 8> {};
7005

    
7006
 private:
7007
#if V8_HOST_ARCH_32_BIT
7008
  // On 32 bit platforms, compiler hints is a smi.
7009
  static const int kCompilerHintsSmiTagSize = kSmiTagSize;
7010
  static const int kCompilerHintsSize = kPointerSize;
7011
#else
7012
  // On 64 bit platforms, compiler hints is not a smi, see comment above.
7013
  static const int kCompilerHintsSmiTagSize = 0;
7014
  static const int kCompilerHintsSize = kIntSize;
7015
#endif
7016

    
7017
  STATIC_ASSERT(SharedFunctionInfo::kCompilerHintsCount <=
7018
                SharedFunctionInfo::kCompilerHintsSize * kBitsPerByte);
7019

    
7020
 public:
7021
  // Constants for optimizing codegen for strict mode function and
7022
  // native tests.
7023
  // Allows to use byte-width instructions.
7024
  static const int kStrictModeBitWithinByte =
7025
      (kStrictModeFunction + kCompilerHintsSmiTagSize) % kBitsPerByte;
7026

    
7027
  static const int kExtendedModeBitWithinByte =
7028
      (kExtendedModeFunction + kCompilerHintsSmiTagSize) % kBitsPerByte;
7029

    
7030
  static const int kNativeBitWithinByte =
7031
      (kNative + kCompilerHintsSmiTagSize) % kBitsPerByte;
7032

    
7033
#if __BYTE_ORDER == __LITTLE_ENDIAN
7034
  static const int kStrictModeByteOffset = kCompilerHintsOffset +
7035
      (kStrictModeFunction + kCompilerHintsSmiTagSize) / kBitsPerByte;
7036
  static const int kExtendedModeByteOffset = kCompilerHintsOffset +
7037
      (kExtendedModeFunction + kCompilerHintsSmiTagSize) / kBitsPerByte;
7038
  static const int kNativeByteOffset = kCompilerHintsOffset +
7039
      (kNative + kCompilerHintsSmiTagSize) / kBitsPerByte;
7040
#elif __BYTE_ORDER == __BIG_ENDIAN
7041
  static const int kStrictModeByteOffset = kCompilerHintsOffset +
7042
      (kCompilerHintsSize - 1) -
7043
      ((kStrictModeFunction + kCompilerHintsSmiTagSize) / kBitsPerByte);
7044
  static const int kExtendedModeByteOffset = kCompilerHintsOffset +
7045
      (kCompilerHintsSize - 1) -
7046
      ((kExtendedModeFunction + kCompilerHintsSmiTagSize) / kBitsPerByte);
7047
  static const int kNativeByteOffset = kCompilerHintsOffset +
7048
      (kCompilerHintsSize - 1) -
7049
      ((kNative + kCompilerHintsSmiTagSize) / kBitsPerByte);
7050
#else
7051
#error Unknown byte ordering
7052
#endif
7053

    
7054
 private:
7055
  DISALLOW_IMPLICIT_CONSTRUCTORS(SharedFunctionInfo);
7056
};
7057

    
7058

    
7059
class JSGeneratorObject: public JSObject {
7060
 public:
7061
  // [function]: The function corresponding to this generator object.
7062
  DECL_ACCESSORS(function, JSFunction)
7063

    
7064
  // [context]: The context of the suspended computation.
7065
  DECL_ACCESSORS(context, Context)
7066

    
7067
  // [receiver]: The receiver of the suspended computation.
7068
  DECL_ACCESSORS(receiver, Object)
7069

    
7070
  // [continuation]: Offset into code of continuation.
7071
  //
7072
  // A positive offset indicates a suspended generator.  The special
7073
  // kGeneratorExecuting and kGeneratorClosed values indicate that a generator
7074
  // cannot be resumed.
7075
  inline int continuation();
7076
  inline void set_continuation(int continuation);
7077

    
7078
  // [operand_stack]: Saved operand stack.
7079
  DECL_ACCESSORS(operand_stack, FixedArray)
7080

    
7081
  // [stack_handler_index]: Index of first stack handler in operand_stack, or -1
7082
  // if the captured activation had no stack handler.
7083
  inline int stack_handler_index();
7084
  inline void set_stack_handler_index(int stack_handler_index);
7085

    
7086
  // Casting.
7087
  static inline JSGeneratorObject* cast(Object* obj);
7088

    
7089
  // Dispatched behavior.
7090
  DECLARE_PRINTER(JSGeneratorObject)
7091
  DECLARE_VERIFIER(JSGeneratorObject)
7092

    
7093
  // Magic sentinel values for the continuation.
7094
  static const int kGeneratorExecuting = -1;
7095
  static const int kGeneratorClosed = 0;
7096

    
7097
  // Layout description.
7098
  static const int kFunctionOffset = JSObject::kHeaderSize;
7099
  static const int kContextOffset = kFunctionOffset + kPointerSize;
7100
  static const int kReceiverOffset = kContextOffset + kPointerSize;
7101
  static const int kContinuationOffset = kReceiverOffset + kPointerSize;
7102
  static const int kOperandStackOffset = kContinuationOffset + kPointerSize;
7103
  static const int kStackHandlerIndexOffset =
7104
      kOperandStackOffset + kPointerSize;
7105
  static const int kSize = kStackHandlerIndexOffset + kPointerSize;
7106

    
7107
  // Resume mode, for use by runtime functions.
7108
  enum ResumeMode { NEXT, THROW };
7109

    
7110
  // Yielding from a generator returns an object with the following inobject
7111
  // properties.  See Context::generator_result_map() for the map.
7112
  static const int kResultValuePropertyIndex = 0;
7113
  static const int kResultDonePropertyIndex = 1;
7114
  static const int kResultPropertyCount = 2;
7115

    
7116
  static const int kResultValuePropertyOffset = JSObject::kHeaderSize;
7117
  static const int kResultDonePropertyOffset =
7118
      kResultValuePropertyOffset + kPointerSize;
7119
  static const int kResultSize = kResultDonePropertyOffset + kPointerSize;
7120

    
7121
 private:
7122
  DISALLOW_IMPLICIT_CONSTRUCTORS(JSGeneratorObject);
7123
};
7124

    
7125

    
7126
// Representation for module instance objects.
7127
class JSModule: public JSObject {
7128
 public:
7129
  // [context]: the context holding the module's locals, or undefined if none.
7130
  DECL_ACCESSORS(context, Object)
7131

    
7132
  // [scope_info]: Scope info.
7133
  DECL_ACCESSORS(scope_info, ScopeInfo)
7134

    
7135
  // Casting.
7136
  static inline JSModule* cast(Object* obj);
7137

    
7138
  // Dispatched behavior.
7139
  DECLARE_PRINTER(JSModule)
7140
  DECLARE_VERIFIER(JSModule)
7141

    
7142
  // Layout description.
7143
  static const int kContextOffset = JSObject::kHeaderSize;
7144
  static const int kScopeInfoOffset = kContextOffset + kPointerSize;
7145
  static const int kSize = kScopeInfoOffset + kPointerSize;
7146

    
7147
 private:
7148
  DISALLOW_IMPLICIT_CONSTRUCTORS(JSModule);
7149
};
7150

    
7151

    
7152
// JSFunction describes JavaScript functions.
7153
class JSFunction: public JSObject {
7154
 public:
7155
  // [prototype_or_initial_map]:
7156
  DECL_ACCESSORS(prototype_or_initial_map, Object)
7157

    
7158
  // [shared]: The information about the function that
7159
  // can be shared by instances.
7160
  DECL_ACCESSORS(shared, SharedFunctionInfo)
7161

    
7162
  // [context]: The context for this function.
7163
  inline Context* context();
7164
  inline void set_context(Object* context);
7165

    
7166
  // [code]: The generated code object for this function.  Executed
7167
  // when the function is invoked, e.g. foo() or new foo(). See
7168
  // [[Call]] and [[Construct]] description in ECMA-262, section
7169
  // 8.6.2, page 27.
7170
  inline Code* code();
7171
  inline void set_code(Code* code);
7172
  inline void set_code_no_write_barrier(Code* code);
7173
  inline void ReplaceCode(Code* code);
7174

    
7175
  // Tells whether this function is builtin.
7176
  inline bool IsBuiltin();
7177

    
7178
  // Tells whether or not the function needs arguments adaption.
7179
  inline bool NeedsArgumentsAdaption();
7180

    
7181
  // Tells whether or not this function has been optimized.
7182
  inline bool IsOptimized();
7183

    
7184
  // Tells whether or not this function can be optimized.
7185
  inline bool IsOptimizable();
7186

    
7187
  // Mark this function for lazy recompilation. The function will be
7188
  // recompiled the next time it is executed.
7189
  void MarkForLazyRecompilation();
7190
  void MarkForConcurrentRecompilation();
7191
  void MarkInRecompileQueue();
7192

    
7193
  // Helpers to compile this function.  Returns true on success, false on
7194
  // failure (e.g., stack overflow during compilation).
7195
  static bool EnsureCompiled(Handle<JSFunction> function,
7196
                             ClearExceptionFlag flag);
7197
  static bool CompileLazy(Handle<JSFunction> function,
7198
                          ClearExceptionFlag flag);
7199
  static Handle<Code> CompileOsr(Handle<JSFunction> function,
7200
                                 BailoutId osr_ast_id,
7201
                                 ClearExceptionFlag flag);
7202
  static bool CompileOptimized(Handle<JSFunction> function,
7203
                               ClearExceptionFlag flag);
7204

    
7205
  // Tells whether or not the function is already marked for lazy
7206
  // recompilation.
7207
  inline bool IsMarkedForLazyRecompilation();
7208
  inline bool IsMarkedForConcurrentRecompilation();
7209

    
7210
  // Tells whether or not the function is on the concurrent recompilation queue.
7211
  inline bool IsInRecompileQueue();
7212

    
7213
  // Check whether or not this function is inlineable.
7214
  bool IsInlineable();
7215

    
7216
  // [literals_or_bindings]: Fixed array holding either
7217
  // the materialized literals or the bindings of a bound function.
7218
  //
7219
  // If the function contains object, regexp or array literals, the
7220
  // literals array prefix contains the object, regexp, and array
7221
  // function to be used when creating these literals.  This is
7222
  // necessary so that we do not dynamically lookup the object, regexp
7223
  // or array functions.  Performing a dynamic lookup, we might end up
7224
  // using the functions from a new context that we should not have
7225
  // access to.
7226
  //
7227
  // On bound functions, the array is a (copy-on-write) fixed-array containing
7228
  // the function that was bound, bound this-value and any bound
7229
  // arguments. Bound functions never contain literals.
7230
  DECL_ACCESSORS(literals_or_bindings, FixedArray)
7231

    
7232
  inline FixedArray* literals();
7233
  inline void set_literals(FixedArray* literals);
7234

    
7235
  inline FixedArray* function_bindings();
7236
  inline void set_function_bindings(FixedArray* bindings);
7237

    
7238
  // The initial map for an object created by this constructor.
7239
  inline Map* initial_map();
7240
  inline void set_initial_map(Map* value);
7241
  inline bool has_initial_map();
7242

    
7243
  // Get and set the prototype property on a JSFunction. If the
7244
  // function has an initial map the prototype is set on the initial
7245
  // map. Otherwise, the prototype is put in the initial map field
7246
  // until an initial map is needed.
7247
  inline bool has_prototype();
7248
  inline bool has_instance_prototype();
7249
  inline Object* prototype();
7250
  inline Object* instance_prototype();
7251
  static void SetPrototype(Handle<JSFunction> function,
7252
                           Handle<Object> value);
7253
  static void SetInstancePrototype(Handle<JSFunction> function,
7254
                                   Handle<Object> value);
7255

    
7256
  // After prototype is removed, it will not be created when accessed, and
7257
  // [[Construct]] from this function will not be allowed.
7258
  void RemovePrototype();
7259
  inline bool should_have_prototype();
7260

    
7261
  // Accessor for this function's initial map's [[class]]
7262
  // property. This is primarily used by ECMA native functions.  This
7263
  // method sets the class_name field of this function's initial map
7264
  // to a given value. It creates an initial map if this function does
7265
  // not have one. Note that this method does not copy the initial map
7266
  // if it has one already, but simply replaces it with the new value.
7267
  // Instances created afterwards will have a map whose [[class]] is
7268
  // set to 'value', but there is no guarantees on instances created
7269
  // before.
7270
  void SetInstanceClassName(String* name);
7271

    
7272
  // Returns if this function has been compiled to native code yet.
7273
  inline bool is_compiled();
7274

    
7275
  // [next_function_link]: Links functions into various lists, e.g. the list
7276
  // of optimized functions hanging off the native_context. The CodeFlusher
7277
  // uses this link to chain together flushing candidates. Treated weakly
7278
  // by the garbage collector.
7279
  DECL_ACCESSORS(next_function_link, Object)
7280

    
7281
  // Prints the name of the function using PrintF.
7282
  void PrintName(FILE* out = stdout);
7283

    
7284
  // Casting.
7285
  static inline JSFunction* cast(Object* obj);
7286

    
7287
  // Iterates the objects, including code objects indirectly referenced
7288
  // through pointers to the first instruction in the code object.
7289
  void JSFunctionIterateBody(int object_size, ObjectVisitor* v);
7290

    
7291
  // Dispatched behavior.
7292
  DECLARE_PRINTER(JSFunction)
7293
  DECLARE_VERIFIER(JSFunction)
7294

    
7295
  // Returns the number of allocated literals.
7296
  inline int NumberOfLiterals();
7297

    
7298
  // Retrieve the native context from a function's literal array.
7299
  static Context* NativeContextFromLiterals(FixedArray* literals);
7300

    
7301
  // Used for flags such as --hydrogen-filter.
7302
  bool PassesFilter(const char* raw_filter);
7303

    
7304
  // Layout descriptors. The last property (from kNonWeakFieldsEndOffset to
7305
  // kSize) is weak and has special handling during garbage collection.
7306
  static const int kCodeEntryOffset = JSObject::kHeaderSize;
7307
  static const int kPrototypeOrInitialMapOffset =
7308
      kCodeEntryOffset + kPointerSize;
7309
  static const int kSharedFunctionInfoOffset =
7310
      kPrototypeOrInitialMapOffset + kPointerSize;
7311
  static const int kContextOffset = kSharedFunctionInfoOffset + kPointerSize;
7312
  static const int kLiteralsOffset = kContextOffset + kPointerSize;
7313
  static const int kNonWeakFieldsEndOffset = kLiteralsOffset + kPointerSize;
7314
  static const int kNextFunctionLinkOffset = kNonWeakFieldsEndOffset;
7315
  static const int kSize = kNextFunctionLinkOffset + kPointerSize;
7316

    
7317
  // Layout of the literals array.
7318
  static const int kLiteralsPrefixSize = 1;
7319
  static const int kLiteralNativeContextIndex = 0;
7320

    
7321
  // Layout of the bound-function binding array.
7322
  static const int kBoundFunctionIndex = 0;
7323
  static const int kBoundThisIndex = 1;
7324
  static const int kBoundArgumentsStartIndex = 2;
7325

    
7326
 private:
7327
  DISALLOW_IMPLICIT_CONSTRUCTORS(JSFunction);
7328
};
7329

    
7330

    
7331
// JSGlobalProxy's prototype must be a JSGlobalObject or null,
7332
// and the prototype is hidden. JSGlobalProxy always delegates
7333
// property accesses to its prototype if the prototype is not null.
7334
//
7335
// A JSGlobalProxy can be reinitialized which will preserve its identity.
7336
//
7337
// Accessing a JSGlobalProxy requires security check.
7338

    
7339
class JSGlobalProxy : public JSObject {
7340
 public:
7341
  // [native_context]: the owner native context of this global proxy object.
7342
  // It is null value if this object is not used by any context.
7343
  DECL_ACCESSORS(native_context, Object)
7344

    
7345
  // Casting.
7346
  static inline JSGlobalProxy* cast(Object* obj);
7347

    
7348
  // Dispatched behavior.
7349
  DECLARE_PRINTER(JSGlobalProxy)
7350
  DECLARE_VERIFIER(JSGlobalProxy)
7351

    
7352
  // Layout description.
7353
  static const int kNativeContextOffset = JSObject::kHeaderSize;
7354
  static const int kSize = kNativeContextOffset + kPointerSize;
7355

    
7356
 private:
7357
  DISALLOW_IMPLICIT_CONSTRUCTORS(JSGlobalProxy);
7358
};
7359

    
7360

    
7361
// Forward declaration.
7362
class JSBuiltinsObject;
7363

    
7364
// Common super class for JavaScript global objects and the special
7365
// builtins global objects.
7366
class GlobalObject: public JSObject {
7367
 public:
7368
  // [builtins]: the object holding the runtime routines written in JS.
7369
  DECL_ACCESSORS(builtins, JSBuiltinsObject)
7370

    
7371
  // [native context]: the natives corresponding to this global object.
7372
  DECL_ACCESSORS(native_context, Context)
7373

    
7374
  // [global context]: the most recent (i.e. innermost) global context.
7375
  DECL_ACCESSORS(global_context, Context)
7376

    
7377
  // [global receiver]: the global receiver object of the context
7378
  DECL_ACCESSORS(global_receiver, JSObject)
7379

    
7380
  // Retrieve the property cell used to store a property.
7381
  PropertyCell* GetPropertyCell(LookupResult* result);
7382

    
7383
  // This is like GetProperty, but is used when you know the lookup won't fail
7384
  // by throwing an exception.  This is for the debug and builtins global
7385
  // objects, where it is known which properties can be expected to be present
7386
  // on the object.
7387
  Object* GetPropertyNoExceptionThrown(Name* key) {
7388
    Object* answer = GetProperty(key)->ToObjectUnchecked();
7389
    return answer;
7390
  }
7391

    
7392
  // Ensure that the global object has a cell for the given property name.
7393
  static Handle<PropertyCell> EnsurePropertyCell(Handle<GlobalObject> global,
7394
                                                 Handle<Name> name);
7395

    
7396
  // Casting.
7397
  static inline GlobalObject* cast(Object* obj);
7398

    
7399
  // Layout description.
7400
  static const int kBuiltinsOffset = JSObject::kHeaderSize;
7401
  static const int kNativeContextOffset = kBuiltinsOffset + kPointerSize;
7402
  static const int kGlobalContextOffset = kNativeContextOffset + kPointerSize;
7403
  static const int kGlobalReceiverOffset = kGlobalContextOffset + kPointerSize;
7404
  static const int kHeaderSize = kGlobalReceiverOffset + kPointerSize;
7405

    
7406
 private:
7407
  DISALLOW_IMPLICIT_CONSTRUCTORS(GlobalObject);
7408
};
7409

    
7410

    
7411
// JavaScript global object.
7412
class JSGlobalObject: public GlobalObject {
7413
 public:
7414
  // Casting.
7415
  static inline JSGlobalObject* cast(Object* obj);
7416

    
7417
  // Dispatched behavior.
7418
  DECLARE_PRINTER(JSGlobalObject)
7419
  DECLARE_VERIFIER(JSGlobalObject)
7420

    
7421
  // Layout description.
7422
  static const int kSize = GlobalObject::kHeaderSize;
7423

    
7424
 private:
7425
  DISALLOW_IMPLICIT_CONSTRUCTORS(JSGlobalObject);
7426
};
7427

    
7428

    
7429
// Builtins global object which holds the runtime routines written in
7430
// JavaScript.
7431
class JSBuiltinsObject: public GlobalObject {
7432
 public:
7433
  // Accessors for the runtime routines written in JavaScript.
7434
  inline Object* javascript_builtin(Builtins::JavaScript id);
7435
  inline void set_javascript_builtin(Builtins::JavaScript id, Object* value);
7436

    
7437
  // Accessors for code of the runtime routines written in JavaScript.
7438
  inline Code* javascript_builtin_code(Builtins::JavaScript id);
7439
  inline void set_javascript_builtin_code(Builtins::JavaScript id, Code* value);
7440

    
7441
  // Casting.
7442
  static inline JSBuiltinsObject* cast(Object* obj);
7443

    
7444
  // Dispatched behavior.
7445
  DECLARE_PRINTER(JSBuiltinsObject)
7446
  DECLARE_VERIFIER(JSBuiltinsObject)
7447

    
7448
  // Layout description.  The size of the builtins object includes
7449
  // room for two pointers per runtime routine written in javascript
7450
  // (function and code object).
7451
  static const int kJSBuiltinsCount = Builtins::id_count;
7452
  static const int kJSBuiltinsOffset = GlobalObject::kHeaderSize;
7453
  static const int kJSBuiltinsCodeOffset =
7454
      GlobalObject::kHeaderSize + (kJSBuiltinsCount * kPointerSize);
7455
  static const int kSize =
7456
      kJSBuiltinsCodeOffset + (kJSBuiltinsCount * kPointerSize);
7457

    
7458
  static int OffsetOfFunctionWithId(Builtins::JavaScript id) {
7459
    return kJSBuiltinsOffset + id * kPointerSize;
7460
  }
7461

    
7462
  static int OffsetOfCodeWithId(Builtins::JavaScript id) {
7463
    return kJSBuiltinsCodeOffset + id * kPointerSize;
7464
  }
7465

    
7466
 private:
7467
  DISALLOW_IMPLICIT_CONSTRUCTORS(JSBuiltinsObject);
7468
};
7469

    
7470

    
7471
// Representation for JS Wrapper objects, String, Number, Boolean, etc.
7472
class JSValue: public JSObject {
7473
 public:
7474
  // [value]: the object being wrapped.
7475
  DECL_ACCESSORS(value, Object)
7476

    
7477
  // Casting.
7478
  static inline JSValue* cast(Object* obj);
7479

    
7480
  // Dispatched behavior.
7481
  DECLARE_PRINTER(JSValue)
7482
  DECLARE_VERIFIER(JSValue)
7483

    
7484
  // Layout description.
7485
  static const int kValueOffset = JSObject::kHeaderSize;
7486
  static const int kSize = kValueOffset + kPointerSize;
7487

    
7488
 private:
7489
  DISALLOW_IMPLICIT_CONSTRUCTORS(JSValue);
7490
};
7491

    
7492

    
7493
class DateCache;
7494

    
7495
// Representation for JS date objects.
7496
class JSDate: public JSObject {
7497
 public:
7498
  // If one component is NaN, all of them are, indicating a NaN time value.
7499
  // [value]: the time value.
7500
  DECL_ACCESSORS(value, Object)
7501
  // [year]: caches year. Either undefined, smi, or NaN.
7502
  DECL_ACCESSORS(year, Object)
7503
  // [month]: caches month. Either undefined, smi, or NaN.
7504
  DECL_ACCESSORS(month, Object)
7505
  // [day]: caches day. Either undefined, smi, or NaN.
7506
  DECL_ACCESSORS(day, Object)
7507
  // [weekday]: caches day of week. Either undefined, smi, or NaN.
7508
  DECL_ACCESSORS(weekday, Object)
7509
  // [hour]: caches hours. Either undefined, smi, or NaN.
7510
  DECL_ACCESSORS(hour, Object)
7511
  // [min]: caches minutes. Either undefined, smi, or NaN.
7512
  DECL_ACCESSORS(min, Object)
7513
  // [sec]: caches seconds. Either undefined, smi, or NaN.
7514
  DECL_ACCESSORS(sec, Object)
7515
  // [cache stamp]: sample of the date cache stamp at the
7516
  // moment when local fields were cached.
7517
  DECL_ACCESSORS(cache_stamp, Object)
7518

    
7519
  // Casting.
7520
  static inline JSDate* cast(Object* obj);
7521

    
7522
  // Returns the date field with the specified index.
7523
  // See FieldIndex for the list of date fields.
7524
  static Object* GetField(Object* date, Smi* index);
7525

    
7526
  void SetValue(Object* value, bool is_value_nan);
7527

    
7528

    
7529
  // Dispatched behavior.
7530
  DECLARE_PRINTER(JSDate)
7531
  DECLARE_VERIFIER(JSDate)
7532

    
7533
  // The order is important. It must be kept in sync with date macros
7534
  // in macros.py.
7535
  enum FieldIndex {
7536
    kDateValue,
7537
    kYear,
7538
    kMonth,
7539
    kDay,
7540
    kWeekday,
7541
    kHour,
7542
    kMinute,
7543
    kSecond,
7544
    kFirstUncachedField,
7545
    kMillisecond = kFirstUncachedField,
7546
    kDays,
7547
    kTimeInDay,
7548
    kFirstUTCField,
7549
    kYearUTC = kFirstUTCField,
7550
    kMonthUTC,
7551
    kDayUTC,
7552
    kWeekdayUTC,
7553
    kHourUTC,
7554
    kMinuteUTC,
7555
    kSecondUTC,
7556
    kMillisecondUTC,
7557
    kDaysUTC,
7558
    kTimeInDayUTC,
7559
    kTimezoneOffset
7560
  };
7561

    
7562
  // Layout description.
7563
  static const int kValueOffset = JSObject::kHeaderSize;
7564
  static const int kYearOffset = kValueOffset + kPointerSize;
7565
  static const int kMonthOffset = kYearOffset + kPointerSize;
7566
  static const int kDayOffset = kMonthOffset + kPointerSize;
7567
  static const int kWeekdayOffset = kDayOffset + kPointerSize;
7568
  static const int kHourOffset = kWeekdayOffset  + kPointerSize;
7569
  static const int kMinOffset = kHourOffset + kPointerSize;
7570
  static const int kSecOffset = kMinOffset + kPointerSize;
7571
  static const int kCacheStampOffset = kSecOffset + kPointerSize;
7572
  static const int kSize = kCacheStampOffset + kPointerSize;
7573

    
7574
 private:
7575
  inline Object* DoGetField(FieldIndex index);
7576

    
7577
  Object* GetUTCField(FieldIndex index, double value, DateCache* date_cache);
7578

    
7579
  // Computes and caches the cacheable fields of the date.
7580
  inline void SetLocalFields(int64_t local_time_ms, DateCache* date_cache);
7581

    
7582

    
7583
  DISALLOW_IMPLICIT_CONSTRUCTORS(JSDate);
7584
};
7585

    
7586

    
7587
// Representation of message objects used for error reporting through
7588
// the API. The messages are formatted in JavaScript so this object is
7589
// a real JavaScript object. The information used for formatting the
7590
// error messages are not directly accessible from JavaScript to
7591
// prevent leaking information to user code called during error
7592
// formatting.
7593
class JSMessageObject: public JSObject {
7594
 public:
7595
  // [type]: the type of error message.
7596
  DECL_ACCESSORS(type, String)
7597

    
7598
  // [arguments]: the arguments for formatting the error message.
7599
  DECL_ACCESSORS(arguments, JSArray)
7600

    
7601
  // [script]: the script from which the error message originated.
7602
  DECL_ACCESSORS(script, Object)
7603

    
7604
  // [stack_trace]: the stack trace for this error message.
7605
  DECL_ACCESSORS(stack_trace, Object)
7606

    
7607
  // [stack_frames]: an array of stack frames for this error object.
7608
  DECL_ACCESSORS(stack_frames, Object)
7609

    
7610
  // [start_position]: the start position in the script for the error message.
7611
  inline int start_position();
7612
  inline void set_start_position(int value);
7613

    
7614
  // [end_position]: the end position in the script for the error message.
7615
  inline int end_position();
7616
  inline void set_end_position(int value);
7617

    
7618
  // Casting.
7619
  static inline JSMessageObject* cast(Object* obj);
7620

    
7621
  // Dispatched behavior.
7622
  DECLARE_PRINTER(JSMessageObject)
7623
  DECLARE_VERIFIER(JSMessageObject)
7624

    
7625
  // Layout description.
7626
  static const int kTypeOffset = JSObject::kHeaderSize;
7627
  static const int kArgumentsOffset = kTypeOffset + kPointerSize;
7628
  static const int kScriptOffset = kArgumentsOffset + kPointerSize;
7629
  static const int kStackTraceOffset = kScriptOffset + kPointerSize;
7630
  static const int kStackFramesOffset = kStackTraceOffset + kPointerSize;
7631
  static const int kStartPositionOffset = kStackFramesOffset + kPointerSize;
7632
  static const int kEndPositionOffset = kStartPositionOffset + kPointerSize;
7633
  static const int kSize = kEndPositionOffset + kPointerSize;
7634

    
7635
  typedef FixedBodyDescriptor<HeapObject::kMapOffset,
7636
                              kStackFramesOffset + kPointerSize,
7637
                              kSize> BodyDescriptor;
7638
};
7639

    
7640

    
7641
// Regular expressions
7642
// The regular expression holds a single reference to a FixedArray in
7643
// the kDataOffset field.
7644
// The FixedArray contains the following data:
7645
// - tag : type of regexp implementation (not compiled yet, atom or irregexp)
7646
// - reference to the original source string
7647
// - reference to the original flag string
7648
// If it is an atom regexp
7649
// - a reference to a literal string to search for
7650
// If it is an irregexp regexp:
7651
// - a reference to code for ASCII inputs (bytecode or compiled), or a smi
7652
// used for tracking the last usage (used for code flushing).
7653
// - a reference to code for UC16 inputs (bytecode or compiled), or a smi
7654
// used for tracking the last usage (used for code flushing)..
7655
// - max number of registers used by irregexp implementations.
7656
// - number of capture registers (output values) of the regexp.
7657
class JSRegExp: public JSObject {
7658
 public:
7659
  // Meaning of Type:
7660
  // NOT_COMPILED: Initial value. No data has been stored in the JSRegExp yet.
7661
  // ATOM: A simple string to match against using an indexOf operation.
7662
  // IRREGEXP: Compiled with Irregexp.
7663
  // IRREGEXP_NATIVE: Compiled to native code with Irregexp.
7664
  enum Type { NOT_COMPILED, ATOM, IRREGEXP };
7665
  enum Flag { NONE = 0, GLOBAL = 1, IGNORE_CASE = 2, MULTILINE = 4 };
7666

    
7667
  class Flags {
7668
   public:
7669
    explicit Flags(uint32_t value) : value_(value) { }
7670
    bool is_global() { return (value_ & GLOBAL) != 0; }
7671
    bool is_ignore_case() { return (value_ & IGNORE_CASE) != 0; }
7672
    bool is_multiline() { return (value_ & MULTILINE) != 0; }
7673
    uint32_t value() { return value_; }
7674
   private:
7675
    uint32_t value_;
7676
  };
7677

    
7678
  DECL_ACCESSORS(data, Object)
7679

    
7680
  inline Type TypeTag();
7681
  inline int CaptureCount();
7682
  inline Flags GetFlags();
7683
  inline String* Pattern();
7684
  inline Object* DataAt(int index);
7685
  // Set implementation data after the object has been prepared.
7686
  inline void SetDataAt(int index, Object* value);
7687

    
7688
  static int code_index(bool is_ascii) {
7689
    if (is_ascii) {
7690
      return kIrregexpASCIICodeIndex;
7691
    } else {
7692
      return kIrregexpUC16CodeIndex;
7693
    }
7694
  }
7695

    
7696
  static int saved_code_index(bool is_ascii) {
7697
    if (is_ascii) {
7698
      return kIrregexpASCIICodeSavedIndex;
7699
    } else {
7700
      return kIrregexpUC16CodeSavedIndex;
7701
    }
7702
  }
7703

    
7704
  static inline JSRegExp* cast(Object* obj);
7705

    
7706
  // Dispatched behavior.
7707
  DECLARE_VERIFIER(JSRegExp)
7708

    
7709
  static const int kDataOffset = JSObject::kHeaderSize;
7710
  static const int kSize = kDataOffset + kPointerSize;
7711

    
7712
  // Indices in the data array.
7713
  static const int kTagIndex = 0;
7714
  static const int kSourceIndex = kTagIndex + 1;
7715
  static const int kFlagsIndex = kSourceIndex + 1;
7716
  static const int kDataIndex = kFlagsIndex + 1;
7717
  // The data fields are used in different ways depending on the
7718
  // value of the tag.
7719
  // Atom regexps (literal strings).
7720
  static const int kAtomPatternIndex = kDataIndex;
7721

    
7722
  static const int kAtomDataSize = kAtomPatternIndex + 1;
7723

    
7724
  // Irregexp compiled code or bytecode for ASCII. If compilation
7725
  // fails, this fields hold an exception object that should be
7726
  // thrown if the regexp is used again.
7727
  static const int kIrregexpASCIICodeIndex = kDataIndex;
7728
  // Irregexp compiled code or bytecode for UC16.  If compilation
7729
  // fails, this fields hold an exception object that should be
7730
  // thrown if the regexp is used again.
7731
  static const int kIrregexpUC16CodeIndex = kDataIndex + 1;
7732

    
7733
  // Saved instance of Irregexp compiled code or bytecode for ASCII that
7734
  // is a potential candidate for flushing.
7735
  static const int kIrregexpASCIICodeSavedIndex = kDataIndex + 2;
7736
  // Saved instance of Irregexp compiled code or bytecode for UC16 that is
7737
  // a potential candidate for flushing.
7738
  static const int kIrregexpUC16CodeSavedIndex = kDataIndex + 3;
7739

    
7740
  // Maximal number of registers used by either ASCII or UC16.
7741
  // Only used to check that there is enough stack space
7742
  static const int kIrregexpMaxRegisterCountIndex = kDataIndex + 4;
7743
  // Number of captures in the compiled regexp.
7744
  static const int kIrregexpCaptureCountIndex = kDataIndex + 5;
7745

    
7746
  static const int kIrregexpDataSize = kIrregexpCaptureCountIndex + 1;
7747

    
7748
  // Offsets directly into the data fixed array.
7749
  static const int kDataTagOffset =
7750
      FixedArray::kHeaderSize + kTagIndex * kPointerSize;
7751
  static const int kDataAsciiCodeOffset =
7752
      FixedArray::kHeaderSize + kIrregexpASCIICodeIndex * kPointerSize;
7753
  static const int kDataUC16CodeOffset =
7754
      FixedArray::kHeaderSize + kIrregexpUC16CodeIndex * kPointerSize;
7755
  static const int kIrregexpCaptureCountOffset =
7756
      FixedArray::kHeaderSize + kIrregexpCaptureCountIndex * kPointerSize;
7757

    
7758
  // In-object fields.
7759
  static const int kSourceFieldIndex = 0;
7760
  static const int kGlobalFieldIndex = 1;
7761
  static const int kIgnoreCaseFieldIndex = 2;
7762
  static const int kMultilineFieldIndex = 3;
7763
  static const int kLastIndexFieldIndex = 4;
7764
  static const int kInObjectFieldCount = 5;
7765

    
7766
  // The uninitialized value for a regexp code object.
7767
  static const int kUninitializedValue = -1;
7768

    
7769
  // The compilation error value for the regexp code object. The real error
7770
  // object is in the saved code field.
7771
  static const int kCompilationErrorValue = -2;
7772

    
7773
  // When we store the sweep generation at which we moved the code from the
7774
  // code index to the saved code index we mask it of to be in the [0:255]
7775
  // range.
7776
  static const int kCodeAgeMask = 0xff;
7777
};
7778

    
7779

    
7780
class CompilationCacheShape : public BaseShape<HashTableKey*> {
7781
 public:
7782
  static inline bool IsMatch(HashTableKey* key, Object* value) {
7783
    return key->IsMatch(value);
7784
  }
7785

    
7786
  static inline uint32_t Hash(HashTableKey* key) {
7787
    return key->Hash();
7788
  }
7789

    
7790
  static inline uint32_t HashForObject(HashTableKey* key, Object* object) {
7791
    return key->HashForObject(object);
7792
  }
7793

    
7794
  MUST_USE_RESULT static MaybeObject* AsObject(Heap* heap,
7795
                                               HashTableKey* key) {
7796
    return key->AsObject(heap);
7797
  }
7798

    
7799
  static const int kPrefixSize = 0;
7800
  static const int kEntrySize = 2;
7801
};
7802

    
7803

    
7804
class CompilationCacheTable: public HashTable<CompilationCacheShape,
7805
                                              HashTableKey*> {
7806
 public:
7807
  // Find cached value for a string key, otherwise return null.
7808
  Object* Lookup(String* src, Context* context);
7809
  Object* LookupEval(String* src,
7810
                     Context* context,
7811
                     LanguageMode language_mode,
7812
                     int scope_position);
7813
  Object* LookupRegExp(String* source, JSRegExp::Flags flags);
7814
  MUST_USE_RESULT MaybeObject* Put(String* src,
7815
                                   Context* context,
7816
                                   Object* value);
7817
  MUST_USE_RESULT MaybeObject* PutEval(String* src,
7818
                                       Context* context,
7819
                                       SharedFunctionInfo* value,
7820
                                       int scope_position);
7821
  MUST_USE_RESULT MaybeObject* PutRegExp(String* src,
7822
                                         JSRegExp::Flags flags,
7823
                                         FixedArray* value);
7824

    
7825
  // Remove given value from cache.
7826
  void Remove(Object* value);
7827

    
7828
  static inline CompilationCacheTable* cast(Object* obj);
7829

    
7830
 private:
7831
  DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationCacheTable);
7832
};
7833

    
7834

    
7835
class CodeCache: public Struct {
7836
 public:
7837
  DECL_ACCESSORS(default_cache, FixedArray)
7838
  DECL_ACCESSORS(normal_type_cache, Object)
7839

    
7840
  // Add the code object to the cache.
7841
  MUST_USE_RESULT MaybeObject* Update(Name* name, Code* code);
7842

    
7843
  // Lookup code object in the cache. Returns code object if found and undefined
7844
  // if not.
7845
  Object* Lookup(Name* name, Code::Flags flags);
7846

    
7847
  // Get the internal index of a code object in the cache. Returns -1 if the
7848
  // code object is not in that cache. This index can be used to later call
7849
  // RemoveByIndex. The cache cannot be modified between a call to GetIndex and
7850
  // RemoveByIndex.
7851
  int GetIndex(Object* name, Code* code);
7852

    
7853
  // Remove an object from the cache with the provided internal index.
7854
  void RemoveByIndex(Object* name, Code* code, int index);
7855

    
7856
  static inline CodeCache* cast(Object* obj);
7857

    
7858
  // Dispatched behavior.
7859
  DECLARE_PRINTER(CodeCache)
7860
  DECLARE_VERIFIER(CodeCache)
7861

    
7862
  static const int kDefaultCacheOffset = HeapObject::kHeaderSize;
7863
  static const int kNormalTypeCacheOffset =
7864
      kDefaultCacheOffset + kPointerSize;
7865
  static const int kSize = kNormalTypeCacheOffset + kPointerSize;
7866

    
7867
 private:
7868
  MUST_USE_RESULT MaybeObject* UpdateDefaultCache(Name* name, Code* code);
7869
  MUST_USE_RESULT MaybeObject* UpdateNormalTypeCache(Name* name, Code* code);
7870
  Object* LookupDefaultCache(Name* name, Code::Flags flags);
7871
  Object* LookupNormalTypeCache(Name* name, Code::Flags flags);
7872

    
7873
  // Code cache layout of the default cache. Elements are alternating name and
7874
  // code objects for non normal load/store/call IC's.
7875
  static const int kCodeCacheEntrySize = 2;
7876
  static const int kCodeCacheEntryNameOffset = 0;
7877
  static const int kCodeCacheEntryCodeOffset = 1;
7878

    
7879
  DISALLOW_IMPLICIT_CONSTRUCTORS(CodeCache);
7880
};
7881

    
7882

    
7883
class CodeCacheHashTableShape : public BaseShape<HashTableKey*> {
7884
 public:
7885
  static inline bool IsMatch(HashTableKey* key, Object* value) {
7886
    return key->IsMatch(value);
7887
  }
7888

    
7889
  static inline uint32_t Hash(HashTableKey* key) {
7890
    return key->Hash();
7891
  }
7892

    
7893
  static inline uint32_t HashForObject(HashTableKey* key, Object* object) {
7894
    return key->HashForObject(object);
7895
  }
7896

    
7897
  MUST_USE_RESULT static MaybeObject* AsObject(Heap* heap,
7898
                                               HashTableKey* key) {
7899
    return key->AsObject(heap);
7900
  }
7901

    
7902
  static const int kPrefixSize = 0;
7903
  static const int kEntrySize = 2;
7904
};
7905

    
7906

    
7907
class CodeCacheHashTable: public HashTable<CodeCacheHashTableShape,
7908
                                           HashTableKey*> {
7909
 public:
7910
  Object* Lookup(Name* name, Code::Flags flags);
7911
  MUST_USE_RESULT MaybeObject* Put(Name* name, Code* code);
7912

    
7913
  int GetIndex(Name* name, Code::Flags flags);
7914
  void RemoveByIndex(int index);
7915

    
7916
  static inline CodeCacheHashTable* cast(Object* obj);
7917

    
7918
  // Initial size of the fixed array backing the hash table.
7919
  static const int kInitialSize = 64;
7920

    
7921
 private:
7922
  DISALLOW_IMPLICIT_CONSTRUCTORS(CodeCacheHashTable);
7923
};
7924

    
7925

    
7926
class PolymorphicCodeCache: public Struct {
7927
 public:
7928
  DECL_ACCESSORS(cache, Object)
7929

    
7930
  static void Update(Handle<PolymorphicCodeCache> cache,
7931
                     MapHandleList* maps,
7932
                     Code::Flags flags,
7933
                     Handle<Code> code);
7934

    
7935
  MUST_USE_RESULT MaybeObject* Update(MapHandleList* maps,
7936
                                      Code::Flags flags,
7937
                                      Code* code);
7938

    
7939
  // Returns an undefined value if the entry is not found.
7940
  Handle<Object> Lookup(MapHandleList* maps, Code::Flags flags);
7941

    
7942
  static inline PolymorphicCodeCache* cast(Object* obj);
7943

    
7944
  // Dispatched behavior.
7945
  DECLARE_PRINTER(PolymorphicCodeCache)
7946
  DECLARE_VERIFIER(PolymorphicCodeCache)
7947

    
7948
  static const int kCacheOffset = HeapObject::kHeaderSize;
7949
  static const int kSize = kCacheOffset + kPointerSize;
7950

    
7951
 private:
7952
  DISALLOW_IMPLICIT_CONSTRUCTORS(PolymorphicCodeCache);
7953
};
7954

    
7955

    
7956
class PolymorphicCodeCacheHashTable
7957
    : public HashTable<CodeCacheHashTableShape, HashTableKey*> {
7958
 public:
7959
  Object* Lookup(MapHandleList* maps, int code_kind);
7960

    
7961
  MUST_USE_RESULT MaybeObject* Put(MapHandleList* maps,
7962
                                   int code_kind,
7963
                                   Code* code);
7964

    
7965
  static inline PolymorphicCodeCacheHashTable* cast(Object* obj);
7966

    
7967
  static const int kInitialSize = 64;
7968
 private:
7969
  DISALLOW_IMPLICIT_CONSTRUCTORS(PolymorphicCodeCacheHashTable);
7970
};
7971

    
7972

    
7973
class TypeFeedbackInfo: public Struct {
7974
 public:
7975
  inline int ic_total_count();
7976
  inline void set_ic_total_count(int count);
7977

    
7978
  inline int ic_with_type_info_count();
7979
  inline void change_ic_with_type_info_count(int count);
7980

    
7981
  inline void initialize_storage();
7982

    
7983
  inline void change_own_type_change_checksum();
7984
  inline int own_type_change_checksum();
7985

    
7986
  inline void set_inlined_type_change_checksum(int checksum);
7987
  inline bool matches_inlined_type_change_checksum(int checksum);
7988

    
7989
  DECL_ACCESSORS(type_feedback_cells, TypeFeedbackCells)
7990

    
7991
  static inline TypeFeedbackInfo* cast(Object* obj);
7992

    
7993
  // Dispatched behavior.
7994
  DECLARE_PRINTER(TypeFeedbackInfo)
7995
  DECLARE_VERIFIER(TypeFeedbackInfo)
7996

    
7997
  static const int kStorage1Offset = HeapObject::kHeaderSize;
7998
  static const int kStorage2Offset = kStorage1Offset + kPointerSize;
7999
  static const int kTypeFeedbackCellsOffset = kStorage2Offset + kPointerSize;
8000
  static const int kSize = kTypeFeedbackCellsOffset + kPointerSize;
8001

    
8002
 private:
8003
  static const int kTypeChangeChecksumBits = 7;
8004

    
8005
  class ICTotalCountField: public BitField<int, 0,
8006
      kSmiValueSize - kTypeChangeChecksumBits> {};  // NOLINT
8007
  class OwnTypeChangeChecksum: public BitField<int,
8008
      kSmiValueSize - kTypeChangeChecksumBits,
8009
      kTypeChangeChecksumBits> {};  // NOLINT
8010
  class ICsWithTypeInfoCountField: public BitField<int, 0,
8011
      kSmiValueSize - kTypeChangeChecksumBits> {};  // NOLINT
8012
  class InlinedTypeChangeChecksum: public BitField<int,
8013
      kSmiValueSize - kTypeChangeChecksumBits,
8014
      kTypeChangeChecksumBits> {};  // NOLINT
8015

    
8016
  DISALLOW_IMPLICIT_CONSTRUCTORS(TypeFeedbackInfo);
8017
};
8018

    
8019

    
8020
enum AllocationSiteMode {
8021
  DONT_TRACK_ALLOCATION_SITE,
8022
  TRACK_ALLOCATION_SITE,
8023
  LAST_ALLOCATION_SITE_MODE = TRACK_ALLOCATION_SITE
8024
};
8025

    
8026

    
8027
class AllocationSite: public Struct {
8028
 public:
8029
  static const uint32_t kMaximumArrayBytesToPretransition = 8 * 1024;
8030

    
8031
  DECL_ACCESSORS(transition_info, Object)
8032
  // nested_site threads a list of sites that represent nested literals
8033
  // walked in a particular order. So [[1, 2], 1, 2] will have one
8034
  // nested_site, but [[1, 2], 3, [4]] will have a list of two.
8035
  DECL_ACCESSORS(nested_site, Object)
8036
  DECL_ACCESSORS(dependent_code, DependentCode)
8037
  DECL_ACCESSORS(weak_next, Object)
8038

    
8039
  inline void Initialize();
8040

    
8041
  bool HasNestedSites() {
8042
    return nested_site()->IsAllocationSite();
8043
  }
8044

    
8045
  // This method is expensive, it should only be called for reporting.
8046
  bool IsNestedSite();
8047

    
8048
  ElementsKind GetElementsKind() {
8049
    ASSERT(!SitePointsToLiteral());
8050
    return static_cast<ElementsKind>(Smi::cast(transition_info())->value());
8051
  }
8052

    
8053
  void SetElementsKind(ElementsKind kind) {
8054
    set_transition_info(Smi::FromInt(static_cast<int>(kind)));
8055
  }
8056

    
8057
  bool SitePointsToLiteral() {
8058
    // If transition_info is a smi, then it represents an ElementsKind
8059
    // for a constructed array. Otherwise, it must be a boilerplate
8060
    // for an object or array literal.
8061
    return transition_info()->IsJSArray() || transition_info()->IsJSObject();
8062
  }
8063

    
8064
  DECLARE_PRINTER(AllocationSite)
8065
  DECLARE_VERIFIER(AllocationSite)
8066

    
8067
  static inline AllocationSite* cast(Object* obj);
8068
  static inline AllocationSiteMode GetMode(
8069
      ElementsKind boilerplate_elements_kind);
8070
  static inline AllocationSiteMode GetMode(ElementsKind from, ElementsKind to);
8071
  static inline bool CanTrack(InstanceType type);
8072

    
8073
  static const int kTransitionInfoOffset = HeapObject::kHeaderSize;
8074
  static const int kNestedSiteOffset = kTransitionInfoOffset + kPointerSize;
8075
  static const int kDependentCodeOffset = kNestedSiteOffset + kPointerSize;
8076
  static const int kWeakNextOffset = kDependentCodeOffset + kPointerSize;
8077
  static const int kSize = kWeakNextOffset + kPointerSize;
8078

    
8079
  typedef FixedBodyDescriptor<HeapObject::kHeaderSize,
8080
                              kDependentCodeOffset + kPointerSize,
8081
                              kSize> BodyDescriptor;
8082

    
8083
 private:
8084
  DISALLOW_IMPLICIT_CONSTRUCTORS(AllocationSite);
8085
};
8086

    
8087

    
8088
class AllocationMemento: public Struct {
8089
 public:
8090
  static const int kAllocationSiteOffset = HeapObject::kHeaderSize;
8091
  static const int kSize = kAllocationSiteOffset + kPointerSize;
8092

    
8093
  DECL_ACCESSORS(allocation_site, Object)
8094

    
8095
  bool IsValid() { return allocation_site()->IsAllocationSite(); }
8096
  AllocationSite* GetAllocationSite() {
8097
    ASSERT(IsValid());
8098
    return AllocationSite::cast(allocation_site());
8099
  }
8100

    
8101
  DECLARE_PRINTER(AllocationMemento)
8102
  DECLARE_VERIFIER(AllocationMemento)
8103

    
8104
  // Returns NULL if no AllocationMemento is available for object.
8105
  static AllocationMemento* FindForJSObject(JSObject* object,
8106
                                            bool in_GC = false);
8107
  static inline AllocationMemento* cast(Object* obj);
8108

    
8109
 private:
8110
  DISALLOW_IMPLICIT_CONSTRUCTORS(AllocationMemento);
8111
};
8112

    
8113

    
8114
// Representation of a slow alias as part of a non-strict arguments objects.
8115
// For fast aliases (if HasNonStrictArgumentsElements()):
8116
// - the parameter map contains an index into the context
8117
// - all attributes of the element have default values
8118
// For slow aliases (if HasDictionaryArgumentsElements()):
8119
// - the parameter map contains no fast alias mapping (i.e. the hole)
8120
// - this struct (in the slow backing store) contains an index into the context
8121
// - all attributes are available as part if the property details
8122
class AliasedArgumentsEntry: public Struct {
8123
 public:
8124
  inline int aliased_context_slot();
8125
  inline void set_aliased_context_slot(int count);
8126

    
8127
  static inline AliasedArgumentsEntry* cast(Object* obj);
8128

    
8129
  // Dispatched behavior.
8130
  DECLARE_PRINTER(AliasedArgumentsEntry)
8131
  DECLARE_VERIFIER(AliasedArgumentsEntry)
8132

    
8133
  static const int kAliasedContextSlot = HeapObject::kHeaderSize;
8134
  static const int kSize = kAliasedContextSlot + kPointerSize;
8135

    
8136
 private:
8137
  DISALLOW_IMPLICIT_CONSTRUCTORS(AliasedArgumentsEntry);
8138
};
8139

    
8140

    
8141
enum AllowNullsFlag {ALLOW_NULLS, DISALLOW_NULLS};
8142
enum RobustnessFlag {ROBUST_STRING_TRAVERSAL, FAST_STRING_TRAVERSAL};
8143

    
8144

    
8145
class StringHasher {
8146
 public:
8147
  explicit inline StringHasher(int length, uint32_t seed);
8148

    
8149
  template <typename schar>
8150
  static inline uint32_t HashSequentialString(const schar* chars,
8151
                                              int length,
8152
                                              uint32_t seed);
8153

    
8154
  // Reads all the data, even for long strings and computes the utf16 length.
8155
  static uint32_t ComputeUtf8Hash(Vector<const char> chars,
8156
                                  uint32_t seed,
8157
                                  int* utf16_length_out);
8158

    
8159
  // Calculated hash value for a string consisting of 1 to
8160
  // String::kMaxArrayIndexSize digits with no leading zeros (except "0").
8161
  // value is represented decimal value.
8162
  static uint32_t MakeArrayIndexHash(uint32_t value, int length);
8163

    
8164
  // No string is allowed to have a hash of zero.  That value is reserved
8165
  // for internal properties.  If the hash calculation yields zero then we
8166
  // use 27 instead.
8167
  static const int kZeroHash = 27;
8168

    
8169
  // Reusable parts of the hashing algorithm.
8170
  INLINE(static uint32_t AddCharacterCore(uint32_t running_hash, uint16_t c));
8171
  INLINE(static uint32_t GetHashCore(uint32_t running_hash));
8172

    
8173
 protected:
8174
  // Returns the value to store in the hash field of a string with
8175
  // the given length and contents.
8176
  uint32_t GetHashField();
8177
  // Returns true if the hash of this string can be computed without
8178
  // looking at the contents.
8179
  inline bool has_trivial_hash();
8180
  // Adds a block of characters to the hash.
8181
  template<typename Char>
8182
  inline void AddCharacters(const Char* chars, int len);
8183

    
8184
 private:
8185
  // Add a character to the hash.
8186
  inline void AddCharacter(uint16_t c);
8187
  // Update index. Returns true if string is still an index.
8188
  inline bool UpdateIndex(uint16_t c);
8189

    
8190
  int length_;
8191
  uint32_t raw_running_hash_;
8192
  uint32_t array_index_;
8193
  bool is_array_index_;
8194
  bool is_first_char_;
8195
  DISALLOW_COPY_AND_ASSIGN(StringHasher);
8196
};
8197

    
8198

    
8199
// The characteristics of a string are stored in its map.  Retrieving these
8200
// few bits of information is moderately expensive, involving two memory
8201
// loads where the second is dependent on the first.  To improve efficiency
8202
// the shape of the string is given its own class so that it can be retrieved
8203
// once and used for several string operations.  A StringShape is small enough
8204
// to be passed by value and is immutable, but be aware that flattening a
8205
// string can potentially alter its shape.  Also be aware that a GC caused by
8206
// something else can alter the shape of a string due to ConsString
8207
// shortcutting.  Keeping these restrictions in mind has proven to be error-
8208
// prone and so we no longer put StringShapes in variables unless there is a
8209
// concrete performance benefit at that particular point in the code.
8210
class StringShape BASE_EMBEDDED {
8211
 public:
8212
  inline explicit StringShape(String* s);
8213
  inline explicit StringShape(Map* s);
8214
  inline explicit StringShape(InstanceType t);
8215
  inline bool IsSequential();
8216
  inline bool IsExternal();
8217
  inline bool IsCons();
8218
  inline bool IsSliced();
8219
  inline bool IsIndirect();
8220
  inline bool IsExternalAscii();
8221
  inline bool IsExternalTwoByte();
8222
  inline bool IsSequentialAscii();
8223
  inline bool IsSequentialTwoByte();
8224
  inline bool IsInternalized();
8225
  inline StringRepresentationTag representation_tag();
8226
  inline uint32_t encoding_tag();
8227
  inline uint32_t full_representation_tag();
8228
  inline uint32_t size_tag();
8229
#ifdef DEBUG
8230
  inline uint32_t type() { return type_; }
8231
  inline void invalidate() { valid_ = false; }
8232
  inline bool valid() { return valid_; }
8233
#else
8234
  inline void invalidate() { }
8235
#endif
8236

    
8237
 private:
8238
  uint32_t type_;
8239
#ifdef DEBUG
8240
  inline void set_valid() { valid_ = true; }
8241
  bool valid_;
8242
#else
8243
  inline void set_valid() { }
8244
#endif
8245
};
8246

    
8247

    
8248
// The Name abstract class captures anything that can be used as a property
8249
// name, i.e., strings and symbols.  All names store a hash value.
8250
class Name: public HeapObject {
8251
 public:
8252
  // Get and set the hash field of the name.
8253
  inline uint32_t hash_field();
8254
  inline void set_hash_field(uint32_t value);
8255

    
8256
  // Tells whether the hash code has been computed.
8257
  inline bool HasHashCode();
8258

    
8259
  // Returns a hash value used for the property table
8260
  inline uint32_t Hash();
8261

    
8262
  // Equality operations.
8263
  inline bool Equals(Name* other);
8264

    
8265
  // Conversion.
8266
  inline bool AsArrayIndex(uint32_t* index);
8267

    
8268
  // Casting.
8269
  static inline Name* cast(Object* obj);
8270

    
8271
  bool IsCacheable(Isolate* isolate);
8272

    
8273
  DECLARE_PRINTER(Name)
8274

    
8275
  // Layout description.
8276
  static const int kHashFieldOffset = HeapObject::kHeaderSize;
8277
  static const int kSize = kHashFieldOffset + kPointerSize;
8278

    
8279
  // Mask constant for checking if a name has a computed hash code
8280
  // and if it is a string that is an array index.  The least significant bit
8281
  // indicates whether a hash code has been computed.  If the hash code has
8282
  // been computed the 2nd bit tells whether the string can be used as an
8283
  // array index.
8284
  static const int kHashNotComputedMask = 1;
8285
  static const int kIsNotArrayIndexMask = 1 << 1;
8286
  static const int kNofHashBitFields = 2;
8287

    
8288
  // Shift constant retrieving hash code from hash field.
8289
  static const int kHashShift = kNofHashBitFields;
8290

    
8291
  // Only these bits are relevant in the hash, since the top two are shifted
8292
  // out.
8293
  static const uint32_t kHashBitMask = 0xffffffffu >> kHashShift;
8294

    
8295
  // Array index strings this short can keep their index in the hash field.
8296
  static const int kMaxCachedArrayIndexLength = 7;
8297

    
8298
  // For strings which are array indexes the hash value has the string length
8299
  // mixed into the hash, mainly to avoid a hash value of zero which would be
8300
  // the case for the string '0'. 24 bits are used for the array index value.
8301
  static const int kArrayIndexValueBits = 24;
8302
  static const int kArrayIndexLengthBits =
8303
      kBitsPerInt - kArrayIndexValueBits - kNofHashBitFields;
8304

    
8305
  STATIC_CHECK((kArrayIndexLengthBits > 0));
8306

    
8307
  static const int kArrayIndexHashLengthShift =
8308
      kArrayIndexValueBits + kNofHashBitFields;
8309

    
8310
  static const int kArrayIndexHashMask = (1 << kArrayIndexHashLengthShift) - 1;
8311

    
8312
  static const int kArrayIndexValueMask =
8313
      ((1 << kArrayIndexValueBits) - 1) << kHashShift;
8314

    
8315
  // Check that kMaxCachedArrayIndexLength + 1 is a power of two so we
8316
  // could use a mask to test if the length of string is less than or equal to
8317
  // kMaxCachedArrayIndexLength.
8318
  STATIC_CHECK(IS_POWER_OF_TWO(kMaxCachedArrayIndexLength + 1));
8319

    
8320
  static const int kContainsCachedArrayIndexMask =
8321
      (~kMaxCachedArrayIndexLength << kArrayIndexHashLengthShift) |
8322
      kIsNotArrayIndexMask;
8323

    
8324
  // Value of empty hash field indicating that the hash is not computed.
8325
  static const int kEmptyHashField =
8326
      kIsNotArrayIndexMask | kHashNotComputedMask;
8327

    
8328
 protected:
8329
  static inline bool IsHashFieldComputed(uint32_t field);
8330

    
8331
 private:
8332
  DISALLOW_IMPLICIT_CONSTRUCTORS(Name);
8333
};
8334

    
8335

    
8336
// ES6 symbols.
8337
class Symbol: public Name {
8338
 public:
8339
  // [name]: the print name of a symbol, or undefined if none.
8340
  DECL_ACCESSORS(name, Object)
8341

    
8342
  // Casting.
8343
  static inline Symbol* cast(Object* obj);
8344

    
8345
  // Dispatched behavior.
8346
  DECLARE_PRINTER(Symbol)
8347
  DECLARE_VERIFIER(Symbol)
8348

    
8349
  // Layout description.
8350
  static const int kNameOffset = Name::kSize;
8351
  static const int kSize = kNameOffset + kPointerSize;
8352

    
8353
  typedef FixedBodyDescriptor<kNameOffset, kNameOffset + kPointerSize, kSize>
8354
          BodyDescriptor;
8355

    
8356
 private:
8357
  DISALLOW_IMPLICIT_CONSTRUCTORS(Symbol);
8358
};
8359

    
8360

    
8361
class ConsString;
8362

    
8363
// The String abstract class captures JavaScript string values:
8364
//
8365
// Ecma-262:
8366
//  4.3.16 String Value
8367
//    A string value is a member of the type String and is a finite
8368
//    ordered sequence of zero or more 16-bit unsigned integer values.
8369
//
8370
// All string values have a length field.
8371
class String: public Name {
8372
 public:
8373
  enum Encoding { ONE_BYTE_ENCODING, TWO_BYTE_ENCODING };
8374

    
8375
  // Representation of the flat content of a String.
8376
  // A non-flat string doesn't have flat content.
8377
  // A flat string has content that's encoded as a sequence of either
8378
  // ASCII chars or two-byte UC16.
8379
  // Returned by String::GetFlatContent().
8380
  class FlatContent {
8381
   public:
8382
    // Returns true if the string is flat and this structure contains content.
8383
    bool IsFlat() { return state_ != NON_FLAT; }
8384
    // Returns true if the structure contains ASCII content.
8385
    bool IsAscii() { return state_ == ASCII; }
8386
    // Returns true if the structure contains two-byte content.
8387
    bool IsTwoByte() { return state_ == TWO_BYTE; }
8388

    
8389
    // Return the one byte content of the string. Only use if IsAscii() returns
8390
    // true.
8391
    Vector<const uint8_t> ToOneByteVector() {
8392
      ASSERT_EQ(ASCII, state_);
8393
      return buffer_;
8394
    }
8395
    // Return the two-byte content of the string. Only use if IsTwoByte()
8396
    // returns true.
8397
    Vector<const uc16> ToUC16Vector() {
8398
      ASSERT_EQ(TWO_BYTE, state_);
8399
      return Vector<const uc16>::cast(buffer_);
8400
    }
8401

    
8402
   private:
8403
    enum State { NON_FLAT, ASCII, TWO_BYTE };
8404

    
8405
    // Constructors only used by String::GetFlatContent().
8406
    explicit FlatContent(Vector<const uint8_t> chars)
8407
        : buffer_(chars),
8408
          state_(ASCII) { }
8409
    explicit FlatContent(Vector<const uc16> chars)
8410
        : buffer_(Vector<const byte>::cast(chars)),
8411
          state_(TWO_BYTE) { }
8412
    FlatContent() : buffer_(), state_(NON_FLAT) { }
8413

    
8414
    Vector<const uint8_t> buffer_;
8415
    State state_;
8416

    
8417
    friend class String;
8418
  };
8419

    
8420
  // Get and set the length of the string.
8421
  inline int length();
8422
  inline void set_length(int value);
8423

    
8424
  // Returns whether this string has only ASCII chars, i.e. all of them can
8425
  // be ASCII encoded.  This might be the case even if the string is
8426
  // two-byte.  Such strings may appear when the embedder prefers
8427
  // two-byte external representations even for ASCII data.
8428
  inline bool IsOneByteRepresentation();
8429
  inline bool IsTwoByteRepresentation();
8430

    
8431
  // Cons and slices have an encoding flag that may not represent the actual
8432
  // encoding of the underlying string.  This is taken into account here.
8433
  // Requires: this->IsFlat()
8434
  inline bool IsOneByteRepresentationUnderneath();
8435
  inline bool IsTwoByteRepresentationUnderneath();
8436

    
8437
  // NOTE: this should be considered only a hint.  False negatives are
8438
  // possible.
8439
  inline bool HasOnlyOneByteChars();
8440

    
8441
  // Get and set individual two byte chars in the string.
8442
  inline void Set(int index, uint16_t value);
8443
  // Get individual two byte char in the string.  Repeated calls
8444
  // to this method are not efficient unless the string is flat.
8445
  INLINE(uint16_t Get(int index));
8446

    
8447
  // Try to flatten the string.  Checks first inline to see if it is
8448
  // necessary.  Does nothing if the string is not a cons string.
8449
  // Flattening allocates a sequential string with the same data as
8450
  // the given string and mutates the cons string to a degenerate
8451
  // form, where the first component is the new sequential string and
8452
  // the second component is the empty string.  If allocation fails,
8453
  // this function returns a failure.  If flattening succeeds, this
8454
  // function returns the sequential string that is now the first
8455
  // component of the cons string.
8456
  //
8457
  // Degenerate cons strings are handled specially by the garbage
8458
  // collector (see IsShortcutCandidate).
8459
  //
8460
  // Use FlattenString from Handles.cc to flatten even in case an
8461
  // allocation failure happens.
8462
  inline MaybeObject* TryFlatten(PretenureFlag pretenure = NOT_TENURED);
8463

    
8464
  // Convenience function.  Has exactly the same behavior as
8465
  // TryFlatten(), except in the case of failure returns the original
8466
  // string.
8467
  inline String* TryFlattenGetString(PretenureFlag pretenure = NOT_TENURED);
8468

    
8469
  // Tries to return the content of a flat string as a structure holding either
8470
  // a flat vector of char or of uc16.
8471
  // If the string isn't flat, and therefore doesn't have flat content, the
8472
  // returned structure will report so, and can't provide a vector of either
8473
  // kind.
8474
  FlatContent GetFlatContent();
8475

    
8476
  // Returns the parent of a sliced string or first part of a flat cons string.
8477
  // Requires: StringShape(this).IsIndirect() && this->IsFlat()
8478
  inline String* GetUnderlying();
8479

    
8480
  // Mark the string as an undetectable object. It only applies to
8481
  // ASCII and two byte string types.
8482
  bool MarkAsUndetectable();
8483

    
8484
  // Return a substring.
8485
  MUST_USE_RESULT MaybeObject* SubString(int from,
8486
                                         int to,
8487
                                         PretenureFlag pretenure = NOT_TENURED);
8488

    
8489
  // String equality operations.
8490
  inline bool Equals(String* other);
8491
  bool IsUtf8EqualTo(Vector<const char> str, bool allow_prefix_match = false);
8492
  bool IsOneByteEqualTo(Vector<const uint8_t> str);
8493
  bool IsTwoByteEqualTo(Vector<const uc16> str);
8494

    
8495
  // Return a UTF8 representation of the string.  The string is null
8496
  // terminated but may optionally contain nulls.  Length is returned
8497
  // in length_output if length_output is not a null pointer  The string
8498
  // should be nearly flat, otherwise the performance of this method may
8499
  // be very slow (quadratic in the length).  Setting robustness_flag to
8500
  // ROBUST_STRING_TRAVERSAL invokes behaviour that is robust  This means it
8501
  // handles unexpected data without causing assert failures and it does not
8502
  // do any heap allocations.  This is useful when printing stack traces.
8503
  SmartArrayPointer<char> ToCString(AllowNullsFlag allow_nulls,
8504
                                    RobustnessFlag robustness_flag,
8505
                                    int offset,
8506
                                    int length,
8507
                                    int* length_output = 0);
8508
  SmartArrayPointer<char> ToCString(
8509
      AllowNullsFlag allow_nulls = DISALLOW_NULLS,
8510
      RobustnessFlag robustness_flag = FAST_STRING_TRAVERSAL,
8511
      int* length_output = 0);
8512

    
8513
  // Return a 16 bit Unicode representation of the string.
8514
  // The string should be nearly flat, otherwise the performance of
8515
  // of this method may be very bad.  Setting robustness_flag to
8516
  // ROBUST_STRING_TRAVERSAL invokes behaviour that is robust  This means it
8517
  // handles unexpected data without causing assert failures and it does not
8518
  // do any heap allocations.  This is useful when printing stack traces.
8519
  SmartArrayPointer<uc16> ToWideCString(
8520
      RobustnessFlag robustness_flag = FAST_STRING_TRAVERSAL);
8521

    
8522
  bool ComputeArrayIndex(uint32_t* index);
8523

    
8524
  // Externalization.
8525
  bool MakeExternal(v8::String::ExternalStringResource* resource);
8526
  bool MakeExternal(v8::String::ExternalAsciiStringResource* resource);
8527

    
8528
  // Conversion.
8529
  inline bool AsArrayIndex(uint32_t* index);
8530

    
8531
  // Casting.
8532
  static inline String* cast(Object* obj);
8533

    
8534
  void PrintOn(FILE* out);
8535

    
8536
  // For use during stack traces.  Performs rudimentary sanity check.
8537
  bool LooksValid();
8538

    
8539
  // Dispatched behavior.
8540
  void StringShortPrint(StringStream* accumulator);
8541
#ifdef OBJECT_PRINT
8542
  char* ToAsciiArray();
8543
#endif
8544
  DECLARE_PRINTER(String)
8545
  DECLARE_VERIFIER(String)
8546

    
8547
  inline bool IsFlat();
8548

    
8549
  // Layout description.
8550
  static const int kLengthOffset = Name::kSize;
8551
  static const int kSize = kLengthOffset + kPointerSize;
8552

    
8553
  // Maximum number of characters to consider when trying to convert a string
8554
  // value into an array index.
8555
  static const int kMaxArrayIndexSize = 10;
8556
  STATIC_CHECK(kMaxArrayIndexSize < (1 << kArrayIndexLengthBits));
8557

    
8558
  // Max char codes.
8559
  static const int32_t kMaxOneByteCharCode = unibrow::Latin1::kMaxChar;
8560
  static const uint32_t kMaxOneByteCharCodeU = unibrow::Latin1::kMaxChar;
8561
  static const int kMaxUtf16CodeUnit = 0xffff;
8562

    
8563
  // Value of hash field containing computed hash equal to zero.
8564
  static const int kEmptyStringHash = kIsNotArrayIndexMask;
8565

    
8566
  // Maximal string length.
8567
  static const int kMaxLength = (1 << (32 - 2)) - 1;
8568

    
8569
  // Max length for computing hash. For strings longer than this limit the
8570
  // string length is used as the hash value.
8571
  static const int kMaxHashCalcLength = 16383;
8572

    
8573
  // Limit for truncation in short printing.
8574
  static const int kMaxShortPrintLength = 1024;
8575

    
8576
  // Support for regular expressions.
8577
  const uc16* GetTwoByteData();
8578
  const uc16* GetTwoByteData(unsigned start);
8579

    
8580
  // Helper function for flattening strings.
8581
  template <typename sinkchar>
8582
  static void WriteToFlat(String* source,
8583
                          sinkchar* sink,
8584
                          int from,
8585
                          int to);
8586

    
8587
  // The return value may point to the first aligned word containing the
8588
  // first non-ascii character, rather than directly to the non-ascii character.
8589
  // If the return value is >= the passed length, the entire string was ASCII.
8590
  static inline int NonAsciiStart(const char* chars, int length) {
8591
    const char* start = chars;
8592
    const char* limit = chars + length;
8593
#ifdef V8_HOST_CAN_READ_UNALIGNED
8594
    ASSERT(unibrow::Utf8::kMaxOneByteChar == 0x7F);
8595
    const uintptr_t non_ascii_mask = kUintptrAllBitsSet / 0xFF * 0x80;
8596
    while (chars + sizeof(uintptr_t) <= limit) {
8597
      if (*reinterpret_cast<const uintptr_t*>(chars) & non_ascii_mask) {
8598
        return static_cast<int>(chars - start);
8599
      }
8600
      chars += sizeof(uintptr_t);
8601
    }
8602
#endif
8603
    while (chars < limit) {
8604
      if (static_cast<uint8_t>(*chars) > unibrow::Utf8::kMaxOneByteChar) {
8605
        return static_cast<int>(chars - start);
8606
      }
8607
      ++chars;
8608
    }
8609
    return static_cast<int>(chars - start);
8610
  }
8611

    
8612
  static inline bool IsAscii(const char* chars, int length) {
8613
    return NonAsciiStart(chars, length) >= length;
8614
  }
8615

    
8616
  static inline bool IsAscii(const uint8_t* chars, int length) {
8617
    return
8618
        NonAsciiStart(reinterpret_cast<const char*>(chars), length) >= length;
8619
  }
8620

    
8621
  static inline int NonOneByteStart(const uc16* chars, int length) {
8622
    const uc16* limit = chars + length;
8623
    const uc16* start = chars;
8624
    while (chars < limit) {
8625
      if (*chars > kMaxOneByteCharCodeU) return static_cast<int>(chars - start);
8626
      ++chars;
8627
    }
8628
    return static_cast<int>(chars - start);
8629
  }
8630

    
8631
  static inline bool IsOneByte(const uc16* chars, int length) {
8632
    return NonOneByteStart(chars, length) >= length;
8633
  }
8634

    
8635
  // TODO(dcarney): Replace all instances of this with VisitFlat.
8636
  template<class Visitor, class ConsOp>
8637
  static inline void Visit(String* string,
8638
                           unsigned offset,
8639
                           Visitor& visitor,
8640
                           ConsOp& cons_op,
8641
                           int32_t type,
8642
                           unsigned length);
8643

    
8644
  template<class Visitor>
8645
  static inline ConsString* VisitFlat(Visitor* visitor,
8646
                                      String* string,
8647
                                      int offset,
8648
                                      int length,
8649
                                      int32_t type);
8650

    
8651
  template<class Visitor>
8652
  static inline ConsString* VisitFlat(Visitor* visitor,
8653
                                      String* string,
8654
                                      int offset = 0) {
8655
    int32_t type = string->map()->instance_type();
8656
    return VisitFlat(visitor, string, offset, string->length(), type);
8657
  }
8658

    
8659
 private:
8660
  friend class Name;
8661

    
8662
  // Try to flatten the top level ConsString that is hiding behind this
8663
  // string.  This is a no-op unless the string is a ConsString.  Flatten
8664
  // mutates the ConsString and might return a failure.
8665
  MUST_USE_RESULT MaybeObject* SlowTryFlatten(PretenureFlag pretenure);
8666

    
8667
  // Slow case of String::Equals.  This implementation works on any strings
8668
  // but it is most efficient on strings that are almost flat.
8669
  bool SlowEquals(String* other);
8670

    
8671
  // Slow case of AsArrayIndex.
8672
  bool SlowAsArrayIndex(uint32_t* index);
8673

    
8674
  // Compute and set the hash code.
8675
  uint32_t ComputeAndSetHash();
8676

    
8677
  DISALLOW_IMPLICIT_CONSTRUCTORS(String);
8678
};
8679

    
8680

    
8681
// The SeqString abstract class captures sequential string values.
8682
class SeqString: public String {
8683
 public:
8684
  // Casting.
8685
  static inline SeqString* cast(Object* obj);
8686

    
8687
  // Layout description.
8688
  static const int kHeaderSize = String::kSize;
8689

    
8690
  // Truncate the string in-place if possible and return the result.
8691
  // In case of new_length == 0, the empty string is returned without
8692
  // truncating the original string.
8693
  MUST_USE_RESULT static Handle<String> Truncate(Handle<SeqString> string,
8694
                                                 int new_length);
8695
 private:
8696
  DISALLOW_IMPLICIT_CONSTRUCTORS(SeqString);
8697
};
8698

    
8699

    
8700
// The AsciiString class captures sequential ASCII string objects.
8701
// Each character in the AsciiString is an ASCII character.
8702
class SeqOneByteString: public SeqString {
8703
 public:
8704
  static const bool kHasAsciiEncoding = true;
8705

    
8706
  // Dispatched behavior.
8707
  inline uint16_t SeqOneByteStringGet(int index);
8708
  inline void SeqOneByteStringSet(int index, uint16_t value);
8709

    
8710
  // Get the address of the characters in this string.
8711
  inline Address GetCharsAddress();
8712

    
8713
  inline uint8_t* GetChars();
8714

    
8715
  // Casting
8716
  static inline SeqOneByteString* cast(Object* obj);
8717

    
8718
  // Garbage collection support.  This method is called by the
8719
  // garbage collector to compute the actual size of an AsciiString
8720
  // instance.
8721
  inline int SeqOneByteStringSize(InstanceType instance_type);
8722

    
8723
  // Computes the size for an AsciiString instance of a given length.
8724
  static int SizeFor(int length) {
8725
    return OBJECT_POINTER_ALIGN(kHeaderSize + length * kCharSize);
8726
  }
8727

    
8728
  // Maximal memory usage for a single sequential ASCII string.
8729
  static const int kMaxSize = 512 * MB - 1;
8730
  // Maximal length of a single sequential ASCII string.
8731
  // Q.v. String::kMaxLength which is the maximal size of concatenated strings.
8732
  static const int kMaxLength = (kMaxSize - kHeaderSize);
8733

    
8734
 private:
8735
  DISALLOW_IMPLICIT_CONSTRUCTORS(SeqOneByteString);
8736
};
8737

    
8738

    
8739
// The TwoByteString class captures sequential unicode string objects.
8740
// Each character in the TwoByteString is a two-byte uint16_t.
8741
class SeqTwoByteString: public SeqString {
8742
 public:
8743
  static const bool kHasAsciiEncoding = false;
8744

    
8745
  // Dispatched behavior.
8746
  inline uint16_t SeqTwoByteStringGet(int index);
8747
  inline void SeqTwoByteStringSet(int index, uint16_t value);
8748

    
8749
  // Get the address of the characters in this string.
8750
  inline Address GetCharsAddress();
8751

    
8752
  inline uc16* GetChars();
8753

    
8754
  // For regexp code.
8755
  const uint16_t* SeqTwoByteStringGetData(unsigned start);
8756

    
8757
  // Casting
8758
  static inline SeqTwoByteString* cast(Object* obj);
8759

    
8760
  // Garbage collection support.  This method is called by the
8761
  // garbage collector to compute the actual size of a TwoByteString
8762
  // instance.
8763
  inline int SeqTwoByteStringSize(InstanceType instance_type);
8764

    
8765
  // Computes the size for a TwoByteString instance of a given length.
8766
  static int SizeFor(int length) {
8767
    return OBJECT_POINTER_ALIGN(kHeaderSize + length * kShortSize);
8768
  }
8769

    
8770
  // Maximal memory usage for a single sequential two-byte string.
8771
  static const int kMaxSize = 512 * MB - 1;
8772
  // Maximal length of a single sequential two-byte string.
8773
  // Q.v. String::kMaxLength which is the maximal size of concatenated strings.
8774
  static const int kMaxLength = (kMaxSize - kHeaderSize) / sizeof(uint16_t);
8775

    
8776
 private:
8777
  DISALLOW_IMPLICIT_CONSTRUCTORS(SeqTwoByteString);
8778
};
8779

    
8780

    
8781
// The ConsString class describes string values built by using the
8782
// addition operator on strings.  A ConsString is a pair where the
8783
// first and second components are pointers to other string values.
8784
// One or both components of a ConsString can be pointers to other
8785
// ConsStrings, creating a binary tree of ConsStrings where the leaves
8786
// are non-ConsString string values.  The string value represented by
8787
// a ConsString can be obtained by concatenating the leaf string
8788
// values in a left-to-right depth-first traversal of the tree.
8789
class ConsString: public String {
8790
 public:
8791
  // First string of the cons cell.
8792
  inline String* first();
8793
  // Doesn't check that the result is a string, even in debug mode.  This is
8794
  // useful during GC where the mark bits confuse the checks.
8795
  inline Object* unchecked_first();
8796
  inline void set_first(String* first,
8797
                        WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
8798

    
8799
  // Second string of the cons cell.
8800
  inline String* second();
8801
  // Doesn't check that the result is a string, even in debug mode.  This is
8802
  // useful during GC where the mark bits confuse the checks.
8803
  inline Object* unchecked_second();
8804
  inline void set_second(String* second,
8805
                         WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
8806

    
8807
  // Dispatched behavior.
8808
  uint16_t ConsStringGet(int index);
8809

    
8810
  // Casting.
8811
  static inline ConsString* cast(Object* obj);
8812

    
8813
  // Layout description.
8814
  static const int kFirstOffset = POINTER_SIZE_ALIGN(String::kSize);
8815
  static const int kSecondOffset = kFirstOffset + kPointerSize;
8816
  static const int kSize = kSecondOffset + kPointerSize;
8817

    
8818
  // Minimum length for a cons string.
8819
  static const int kMinLength = 13;
8820

    
8821
  typedef FixedBodyDescriptor<kFirstOffset, kSecondOffset + kPointerSize, kSize>
8822
          BodyDescriptor;
8823

    
8824
  DECLARE_VERIFIER(ConsString)
8825

    
8826
 private:
8827
  DISALLOW_IMPLICIT_CONSTRUCTORS(ConsString);
8828
};
8829

    
8830

    
8831
// The Sliced String class describes strings that are substrings of another
8832
// sequential string.  The motivation is to save time and memory when creating
8833
// a substring.  A Sliced String is described as a pointer to the parent,
8834
// the offset from the start of the parent string and the length.  Using
8835
// a Sliced String therefore requires unpacking of the parent string and
8836
// adding the offset to the start address.  A substring of a Sliced String
8837
// are not nested since the double indirection is simplified when creating
8838
// such a substring.
8839
// Currently missing features are:
8840
//  - handling externalized parent strings
8841
//  - external strings as parent
8842
//  - truncating sliced string to enable otherwise unneeded parent to be GC'ed.
8843
class SlicedString: public String {
8844
 public:
8845
  inline String* parent();
8846
  inline void set_parent(String* parent,
8847
                         WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
8848
  inline int offset();
8849
  inline void set_offset(int offset);
8850

    
8851
  // Dispatched behavior.
8852
  uint16_t SlicedStringGet(int index);
8853

    
8854
  // Casting.
8855
  static inline SlicedString* cast(Object* obj);
8856

    
8857
  // Layout description.
8858
  static const int kParentOffset = POINTER_SIZE_ALIGN(String::kSize);
8859
  static const int kOffsetOffset = kParentOffset + kPointerSize;
8860
  static const int kSize = kOffsetOffset + kPointerSize;
8861

    
8862
  // Minimum length for a sliced string.
8863
  static const int kMinLength = 13;
8864

    
8865
  typedef FixedBodyDescriptor<kParentOffset,
8866
                              kOffsetOffset + kPointerSize, kSize>
8867
          BodyDescriptor;
8868

    
8869
  DECLARE_VERIFIER(SlicedString)
8870

    
8871
 private:
8872
  DISALLOW_IMPLICIT_CONSTRUCTORS(SlicedString);
8873
};
8874

    
8875

    
8876
// The ExternalString class describes string values that are backed by
8877
// a string resource that lies outside the V8 heap.  ExternalStrings
8878
// consist of the length field common to all strings, a pointer to the
8879
// external resource.  It is important to ensure (externally) that the
8880
// resource is not deallocated while the ExternalString is live in the
8881
// V8 heap.
8882
//
8883
// The API expects that all ExternalStrings are created through the
8884
// API.  Therefore, ExternalStrings should not be used internally.
8885
class ExternalString: public String {
8886
 public:
8887
  // Casting
8888
  static inline ExternalString* cast(Object* obj);
8889

    
8890
  // Layout description.
8891
  static const int kResourceOffset = POINTER_SIZE_ALIGN(String::kSize);
8892
  static const int kShortSize = kResourceOffset + kPointerSize;
8893
  static const int kResourceDataOffset = kResourceOffset + kPointerSize;
8894
  static const int kSize = kResourceDataOffset + kPointerSize;
8895

    
8896
  static const int kMaxShortLength =
8897
      (kShortSize - SeqString::kHeaderSize) / kCharSize;
8898

    
8899
  // Return whether external string is short (data pointer is not cached).
8900
  inline bool is_short();
8901

    
8902
  STATIC_CHECK(kResourceOffset == Internals::kStringResourceOffset);
8903

    
8904
 private:
8905
  DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalString);
8906
};
8907

    
8908

    
8909
// The ExternalAsciiString class is an external string backed by an
8910
// ASCII string.
8911
class ExternalAsciiString: public ExternalString {
8912
 public:
8913
  static const bool kHasAsciiEncoding = true;
8914

    
8915
  typedef v8::String::ExternalAsciiStringResource Resource;
8916

    
8917
  // The underlying resource.
8918
  inline const Resource* resource();
8919
  inline void set_resource(const Resource* buffer);
8920

    
8921
  // Update the pointer cache to the external character array.
8922
  // The cached pointer is always valid, as the external character array does =
8923
  // not move during lifetime.  Deserialization is the only exception, after
8924
  // which the pointer cache has to be refreshed.
8925
  inline void update_data_cache();
8926

    
8927
  inline const uint8_t* GetChars();
8928

    
8929
  // Dispatched behavior.
8930
  inline uint16_t ExternalAsciiStringGet(int index);
8931

    
8932
  // Casting.
8933
  static inline ExternalAsciiString* cast(Object* obj);
8934

    
8935
  // Garbage collection support.
8936
  inline void ExternalAsciiStringIterateBody(ObjectVisitor* v);
8937

    
8938
  template<typename StaticVisitor>
8939
  inline void ExternalAsciiStringIterateBody();
8940

    
8941
 private:
8942
  DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalAsciiString);
8943
};
8944

    
8945

    
8946
// The ExternalTwoByteString class is an external string backed by a UTF-16
8947
// encoded string.
8948
class ExternalTwoByteString: public ExternalString {
8949
 public:
8950
  static const bool kHasAsciiEncoding = false;
8951

    
8952
  typedef v8::String::ExternalStringResource Resource;
8953

    
8954
  // The underlying string resource.
8955
  inline const Resource* resource();
8956
  inline void set_resource(const Resource* buffer);
8957

    
8958
  // Update the pointer cache to the external character array.
8959
  // The cached pointer is always valid, as the external character array does =
8960
  // not move during lifetime.  Deserialization is the only exception, after
8961
  // which the pointer cache has to be refreshed.
8962
  inline void update_data_cache();
8963

    
8964
  inline const uint16_t* GetChars();
8965

    
8966
  // Dispatched behavior.
8967
  inline uint16_t ExternalTwoByteStringGet(int index);
8968

    
8969
  // For regexp code.
8970
  inline const uint16_t* ExternalTwoByteStringGetData(unsigned start);
8971

    
8972
  // Casting.
8973
  static inline ExternalTwoByteString* cast(Object* obj);
8974

    
8975
  // Garbage collection support.
8976
  inline void ExternalTwoByteStringIterateBody(ObjectVisitor* v);
8977

    
8978
  template<typename StaticVisitor>
8979
  inline void ExternalTwoByteStringIterateBody();
8980

    
8981
 private:
8982
  DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalTwoByteString);
8983
};
8984

    
8985

    
8986
// Utility superclass for stack-allocated objects that must be updated
8987
// on gc.  It provides two ways for the gc to update instances, either
8988
// iterating or updating after gc.
8989
class Relocatable BASE_EMBEDDED {
8990
 public:
8991
  explicit inline Relocatable(Isolate* isolate);
8992
  inline virtual ~Relocatable();
8993
  virtual void IterateInstance(ObjectVisitor* v) { }
8994
  virtual void PostGarbageCollection() { }
8995

    
8996
  static void PostGarbageCollectionProcessing(Isolate* isolate);
8997
  static int ArchiveSpacePerThread();
8998
  static char* ArchiveState(Isolate* isolate, char* to);
8999
  static char* RestoreState(Isolate* isolate, char* from);
9000
  static void Iterate(Isolate* isolate, ObjectVisitor* v);
9001
  static void Iterate(ObjectVisitor* v, Relocatable* top);
9002
  static char* Iterate(ObjectVisitor* v, char* t);
9003

    
9004
 private:
9005
  Isolate* isolate_;
9006
  Relocatable* prev_;
9007
};
9008

    
9009

    
9010
// A flat string reader provides random access to the contents of a
9011
// string independent of the character width of the string.  The handle
9012
// must be valid as long as the reader is being used.
9013
class FlatStringReader : public Relocatable {
9014
 public:
9015
  FlatStringReader(Isolate* isolate, Handle<String> str);
9016
  FlatStringReader(Isolate* isolate, Vector<const char> input);
9017
  void PostGarbageCollection();
9018
  inline uc32 Get(int index);
9019
  int length() { return length_; }
9020
 private:
9021
  String** str_;
9022
  bool is_ascii_;
9023
  int length_;
9024
  const void* start_;
9025
};
9026

    
9027

    
9028
// A ConsStringOp that returns null.
9029
// Useful when the operation to apply on a ConsString
9030
// requires an expensive data structure.
9031
class ConsStringNullOp {
9032
 public:
9033
  inline ConsStringNullOp() {}
9034
  static inline String* Operate(String*, unsigned*, int32_t*, unsigned*);
9035
 private:
9036
  DISALLOW_COPY_AND_ASSIGN(ConsStringNullOp);
9037
};
9038

    
9039

    
9040
// This maintains an off-stack representation of the stack frames required
9041
// to traverse a ConsString, allowing an entirely iterative and restartable
9042
// traversal of the entire string
9043
// Note: this class is not GC-safe.
9044
class ConsStringIteratorOp {
9045
 public:
9046
  inline ConsStringIteratorOp() {}
9047
  String* Operate(String* string,
9048
                  unsigned* offset_out,
9049
                  int32_t* type_out,
9050
                  unsigned* length_out);
9051
  inline String* ContinueOperation(int32_t* type_out, unsigned* length_out);
9052
  inline void Reset();
9053
  inline bool HasMore();
9054

    
9055
 private:
9056
  // TODO(dcarney): Templatize this out for different stack sizes.
9057
  static const unsigned kStackSize = 32;
9058
  // Use a mask instead of doing modulo operations for stack wrapping.
9059
  static const unsigned kDepthMask = kStackSize-1;
9060
  STATIC_ASSERT(IS_POWER_OF_TWO(kStackSize));
9061
  static inline unsigned OffsetForDepth(unsigned depth);
9062

    
9063
  inline void PushLeft(ConsString* string);
9064
  inline void PushRight(ConsString* string);
9065
  inline void AdjustMaximumDepth();
9066
  inline void Pop();
9067
  String* NextLeaf(bool* blew_stack, int32_t* type_out, unsigned* length_out);
9068
  String* Search(unsigned* offset_out,
9069
                 int32_t* type_out,
9070
                 unsigned* length_out);
9071

    
9072
  unsigned depth_;
9073
  unsigned maximum_depth_;
9074
  // Stack must always contain only frames for which right traversal
9075
  // has not yet been performed.
9076
  ConsString* frames_[kStackSize];
9077
  unsigned consumed_;
9078
  ConsString* root_;
9079
  DISALLOW_COPY_AND_ASSIGN(ConsStringIteratorOp);
9080
};
9081

    
9082

    
9083
// Note: this class is not GC-safe.
9084
class StringCharacterStream {
9085
 public:
9086
  inline StringCharacterStream(String* string,
9087
                               ConsStringIteratorOp* op,
9088
                               unsigned offset = 0);
9089
  inline uint16_t GetNext();
9090
  inline bool HasMore();
9091
  inline void Reset(String* string, unsigned offset = 0);
9092
  inline void VisitOneByteString(const uint8_t* chars, unsigned length);
9093
  inline void VisitTwoByteString(const uint16_t* chars, unsigned length);
9094

    
9095
 private:
9096
  bool is_one_byte_;
9097
  union {
9098
    const uint8_t* buffer8_;
9099
    const uint16_t* buffer16_;
9100
  };
9101
  const uint8_t* end_;
9102
  ConsStringIteratorOp* op_;
9103
  DISALLOW_COPY_AND_ASSIGN(StringCharacterStream);
9104
};
9105

    
9106

    
9107
template <typename T>
9108
class VectorIterator {
9109
 public:
9110
  VectorIterator(T* d, int l) : data_(Vector<const T>(d, l)), index_(0) { }
9111
  explicit VectorIterator(Vector<const T> data) : data_(data), index_(0) { }
9112
  T GetNext() { return data_[index_++]; }
9113
  bool has_more() { return index_ < data_.length(); }
9114
 private:
9115
  Vector<const T> data_;
9116
  int index_;
9117
};
9118

    
9119

    
9120
// The Oddball describes objects null, undefined, true, and false.
9121
class Oddball: public HeapObject {
9122
 public:
9123
  // [to_string]: Cached to_string computed at startup.
9124
  DECL_ACCESSORS(to_string, String)
9125

    
9126
  // [to_number]: Cached to_number computed at startup.
9127
  DECL_ACCESSORS(to_number, Object)
9128

    
9129
  inline byte kind();
9130
  inline void set_kind(byte kind);
9131

    
9132
  // Casting.
9133
  static inline Oddball* cast(Object* obj);
9134

    
9135
  // Dispatched behavior.
9136
  DECLARE_VERIFIER(Oddball)
9137

    
9138
  // Initialize the fields.
9139
  MUST_USE_RESULT MaybeObject* Initialize(Heap* heap,
9140
                                          const char* to_string,
9141
                                          Object* to_number,
9142
                                          byte kind);
9143

    
9144
  // Layout description.
9145
  static const int kToStringOffset = HeapObject::kHeaderSize;
9146
  static const int kToNumberOffset = kToStringOffset + kPointerSize;
9147
  static const int kKindOffset = kToNumberOffset + kPointerSize;
9148
  static const int kSize = kKindOffset + kPointerSize;
9149

    
9150
  static const byte kFalse = 0;
9151
  static const byte kTrue = 1;
9152
  static const byte kNotBooleanMask = ~1;
9153
  static const byte kTheHole = 2;
9154
  static const byte kNull = 3;
9155
  static const byte kArgumentMarker = 4;
9156
  static const byte kUndefined = 5;
9157
  static const byte kUninitialized = 6;
9158
  static const byte kOther = 7;
9159

    
9160
  typedef FixedBodyDescriptor<kToStringOffset,
9161
                              kToNumberOffset + kPointerSize,
9162
                              kSize> BodyDescriptor;
9163

    
9164
  STATIC_CHECK(kKindOffset == Internals::kOddballKindOffset);
9165
  STATIC_CHECK(kNull == Internals::kNullOddballKind);
9166
  STATIC_CHECK(kUndefined == Internals::kUndefinedOddballKind);
9167

    
9168
 private:
9169
  DISALLOW_IMPLICIT_CONSTRUCTORS(Oddball);
9170
};
9171

    
9172

    
9173
class Cell: public HeapObject {
9174
 public:
9175
  // [value]: value of the global property.
9176
  DECL_ACCESSORS(value, Object)
9177

    
9178
  // Casting.
9179
  static inline Cell* cast(Object* obj);
9180

    
9181
  static inline Cell* FromValueAddress(Address value) {
9182
    Object* result = FromAddress(value - kValueOffset);
9183
    ASSERT(result->IsCell() || result->IsPropertyCell());
9184
    return static_cast<Cell*>(result);
9185
  }
9186

    
9187
  inline Address ValueAddress() {
9188
    return address() + kValueOffset;
9189
  }
9190

    
9191
  // Dispatched behavior.
9192
  DECLARE_PRINTER(Cell)
9193
  DECLARE_VERIFIER(Cell)
9194

    
9195
  // Layout description.
9196
  static const int kValueOffset = HeapObject::kHeaderSize;
9197
  static const int kSize = kValueOffset + kPointerSize;
9198

    
9199
  typedef FixedBodyDescriptor<kValueOffset,
9200
                              kValueOffset + kPointerSize,
9201
                              kSize> BodyDescriptor;
9202

    
9203
 private:
9204
  DISALLOW_IMPLICIT_CONSTRUCTORS(Cell);
9205
};
9206

    
9207

    
9208
class PropertyCell: public Cell {
9209
 public:
9210
  // [type]: type of the global property.
9211
  Type* type();
9212
  void set_type(Type* value, WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
9213

    
9214
  // [dependent_code]: dependent code that depends on the type of the global
9215
  // property.
9216
  DECL_ACCESSORS(dependent_code, DependentCode)
9217

    
9218
  // Sets the value of the cell and updates the type field to be the union
9219
  // of the cell's current type and the value's type. If the change causes
9220
  // a change of the type of the cell's contents, code dependent on the cell
9221
  // will be deoptimized.
9222
  static void SetValueInferType(Handle<PropertyCell> cell,
9223
                                Handle<Object> value);
9224

    
9225
  // Computes the new type of the cell's contents for the given value, but
9226
  // without actually modifying the 'type' field.
9227
  static Handle<Type> UpdatedType(Handle<PropertyCell> cell,
9228
                                  Handle<Object> value);
9229

    
9230
  void AddDependentCompilationInfo(CompilationInfo* info);
9231

    
9232
  void AddDependentCode(Handle<Code> code);
9233

    
9234
  // Casting.
9235
  static inline PropertyCell* cast(Object* obj);
9236

    
9237
  inline Address TypeAddress() {
9238
    return address() + kTypeOffset;
9239
  }
9240

    
9241
  // Dispatched behavior.
9242
  DECLARE_PRINTER(PropertyCell)
9243
  DECLARE_VERIFIER(PropertyCell)
9244

    
9245
  // Layout description.
9246
  static const int kTypeOffset = kValueOffset + kPointerSize;
9247
  static const int kDependentCodeOffset = kTypeOffset + kPointerSize;
9248
  static const int kSize = kDependentCodeOffset + kPointerSize;
9249

    
9250
  static const int kPointerFieldsBeginOffset = kValueOffset;
9251
  static const int kPointerFieldsEndOffset = kDependentCodeOffset;
9252

    
9253
  typedef FixedBodyDescriptor<kValueOffset,
9254
                              kSize,
9255
                              kSize> BodyDescriptor;
9256

    
9257
 private:
9258
  DECL_ACCESSORS(type_raw, Object)
9259
  DISALLOW_IMPLICIT_CONSTRUCTORS(PropertyCell);
9260
};
9261

    
9262

    
9263
// The JSProxy describes EcmaScript Harmony proxies
9264
class JSProxy: public JSReceiver {
9265
 public:
9266
  // [handler]: The handler property.
9267
  DECL_ACCESSORS(handler, Object)
9268

    
9269
  // [hash]: The hash code property (undefined if not initialized yet).
9270
  DECL_ACCESSORS(hash, Object)
9271

    
9272
  // Casting.
9273
  static inline JSProxy* cast(Object* obj);
9274

    
9275
  MUST_USE_RESULT MaybeObject* GetPropertyWithHandler(
9276
      Object* receiver,
9277
      Name* name);
9278
  MUST_USE_RESULT MaybeObject* GetElementWithHandler(
9279
      Object* receiver,
9280
      uint32_t index);
9281

    
9282
  // If the handler defines an accessor property with a setter, invoke it.
9283
  // If it defines an accessor property without a setter, or a data property
9284
  // that is read-only, throw. In all these cases set '*done' to true,
9285
  // otherwise set it to false.
9286
  static Handle<Object> SetPropertyViaPrototypesWithHandler(
9287
      Handle<JSProxy> proxy,
9288
      Handle<JSReceiver> receiver,
9289
      Handle<Name> name,
9290
      Handle<Object> value,
9291
      PropertyAttributes attributes,
9292
      StrictModeFlag strict_mode,
9293
      bool* done);
9294

    
9295
  MUST_USE_RESULT PropertyAttributes GetPropertyAttributeWithHandler(
9296
      JSReceiver* receiver,
9297
      Name* name);
9298
  MUST_USE_RESULT PropertyAttributes GetElementAttributeWithHandler(
9299
      JSReceiver* receiver,
9300
      uint32_t index);
9301

    
9302
  // Turn the proxy into an (empty) JSObject.
9303
  static void Fix(Handle<JSProxy> proxy);
9304

    
9305
  // Initializes the body after the handler slot.
9306
  inline void InitializeBody(int object_size, Object* value);
9307

    
9308
  // Invoke a trap by name. If the trap does not exist on this's handler,
9309
  // but derived_trap is non-NULL, invoke that instead.  May cause GC.
9310
  Handle<Object> CallTrap(const char* name,
9311
                          Handle<Object> derived_trap,
9312
                          int argc,
9313
                          Handle<Object> args[]);
9314

    
9315
  // Dispatched behavior.
9316
  DECLARE_PRINTER(JSProxy)
9317
  DECLARE_VERIFIER(JSProxy)
9318

    
9319
  // Layout description. We add padding so that a proxy has the same
9320
  // size as a virgin JSObject. This is essential for becoming a JSObject
9321
  // upon freeze.
9322
  static const int kHandlerOffset = HeapObject::kHeaderSize;
9323
  static const int kHashOffset = kHandlerOffset + kPointerSize;
9324
  static const int kPaddingOffset = kHashOffset + kPointerSize;
9325
  static const int kSize = JSObject::kHeaderSize;
9326
  static const int kHeaderSize = kPaddingOffset;
9327
  static const int kPaddingSize = kSize - kPaddingOffset;
9328

    
9329
  STATIC_CHECK(kPaddingSize >= 0);
9330

    
9331
  typedef FixedBodyDescriptor<kHandlerOffset,
9332
                              kPaddingOffset,
9333
                              kSize> BodyDescriptor;
9334

    
9335
 private:
9336
  friend class JSReceiver;
9337

    
9338
  static Handle<Object> SetPropertyWithHandler(Handle<JSProxy> proxy,
9339
                                               Handle<JSReceiver> receiver,
9340
                                               Handle<Name> name,
9341
                                               Handle<Object> value,
9342
                                               PropertyAttributes attributes,
9343
                                               StrictModeFlag strict_mode);
9344
  static Handle<Object> SetElementWithHandler(Handle<JSProxy> proxy,
9345
                                              Handle<JSReceiver> receiver,
9346
                                              uint32_t index,
9347
                                              Handle<Object> value,
9348
                                              StrictModeFlag strict_mode);
9349

    
9350
  static bool HasPropertyWithHandler(Handle<JSProxy> proxy, Handle<Name> name);
9351
  static bool HasElementWithHandler(Handle<JSProxy> proxy, uint32_t index);
9352

    
9353
  static Handle<Object> DeletePropertyWithHandler(Handle<JSProxy> proxy,
9354
                                                  Handle<Name> name,
9355
                                                  DeleteMode mode);
9356
  static Handle<Object> DeleteElementWithHandler(Handle<JSProxy> proxy,
9357
                                                 uint32_t index,
9358
                                                 DeleteMode mode);
9359

    
9360
  MUST_USE_RESULT MaybeObject* GetIdentityHash(CreationFlag flag);
9361
  static Handle<Object> GetIdentityHash(Handle<JSProxy> proxy,
9362
                                        CreationFlag flag);
9363

    
9364
  DISALLOW_IMPLICIT_CONSTRUCTORS(JSProxy);
9365
};
9366

    
9367

    
9368
class JSFunctionProxy: public JSProxy {
9369
 public:
9370
  // [call_trap]: The call trap.
9371
  DECL_ACCESSORS(call_trap, Object)
9372

    
9373
  // [construct_trap]: The construct trap.
9374
  DECL_ACCESSORS(construct_trap, Object)
9375

    
9376
  // Casting.
9377
  static inline JSFunctionProxy* cast(Object* obj);
9378

    
9379
  // Dispatched behavior.
9380
  DECLARE_PRINTER(JSFunctionProxy)
9381
  DECLARE_VERIFIER(JSFunctionProxy)
9382

    
9383
  // Layout description.
9384
  static const int kCallTrapOffset = JSProxy::kPaddingOffset;
9385
  static const int kConstructTrapOffset = kCallTrapOffset + kPointerSize;
9386
  static const int kPaddingOffset = kConstructTrapOffset + kPointerSize;
9387
  static const int kSize = JSFunction::kSize;
9388
  static const int kPaddingSize = kSize - kPaddingOffset;
9389

    
9390
  STATIC_CHECK(kPaddingSize >= 0);
9391

    
9392
  typedef FixedBodyDescriptor<kHandlerOffset,
9393
                              kConstructTrapOffset + kPointerSize,
9394
                              kSize> BodyDescriptor;
9395

    
9396
 private:
9397
  DISALLOW_IMPLICIT_CONSTRUCTORS(JSFunctionProxy);
9398
};
9399

    
9400

    
9401
// The JSSet describes EcmaScript Harmony sets
9402
class JSSet: public JSObject {
9403
 public:
9404
  // [set]: the backing hash set containing keys.
9405
  DECL_ACCESSORS(table, Object)
9406

    
9407
  // Casting.
9408
  static inline JSSet* cast(Object* obj);
9409

    
9410
  // Dispatched behavior.
9411
  DECLARE_PRINTER(JSSet)
9412
  DECLARE_VERIFIER(JSSet)
9413

    
9414
  static const int kTableOffset = JSObject::kHeaderSize;
9415
  static const int kSize = kTableOffset + kPointerSize;
9416

    
9417
 private:
9418
  DISALLOW_IMPLICIT_CONSTRUCTORS(JSSet);
9419
};
9420

    
9421

    
9422
// The JSMap describes EcmaScript Harmony maps
9423
class JSMap: public JSObject {
9424
 public:
9425
  // [table]: the backing hash table mapping keys to values.
9426
  DECL_ACCESSORS(table, Object)
9427

    
9428
  // Casting.
9429
  static inline JSMap* cast(Object* obj);
9430

    
9431
  // Dispatched behavior.
9432
  DECLARE_PRINTER(JSMap)
9433
  DECLARE_VERIFIER(JSMap)
9434

    
9435
  static const int kTableOffset = JSObject::kHeaderSize;
9436
  static const int kSize = kTableOffset + kPointerSize;
9437

    
9438
 private:
9439
  DISALLOW_IMPLICIT_CONSTRUCTORS(JSMap);
9440
};
9441

    
9442

    
9443
// Base class for both JSWeakMap and JSWeakSet
9444
class JSWeakCollection: public JSObject {
9445
 public:
9446
  // [table]: the backing hash table mapping keys to values.
9447
  DECL_ACCESSORS(table, Object)
9448

    
9449
  // [next]: linked list of encountered weak maps during GC.
9450
  DECL_ACCESSORS(next, Object)
9451

    
9452
  static const int kTableOffset = JSObject::kHeaderSize;
9453
  static const int kNextOffset = kTableOffset + kPointerSize;
9454
  static const int kSize = kNextOffset + kPointerSize;
9455

    
9456
 private:
9457
  DISALLOW_IMPLICIT_CONSTRUCTORS(JSWeakCollection);
9458
};
9459

    
9460

    
9461
// The JSWeakMap describes EcmaScript Harmony weak maps
9462
class JSWeakMap: public JSWeakCollection {
9463
 public:
9464
  // Casting.
9465
  static inline JSWeakMap* cast(Object* obj);
9466

    
9467
  // Dispatched behavior.
9468
  DECLARE_PRINTER(JSWeakMap)
9469
  DECLARE_VERIFIER(JSWeakMap)
9470

    
9471
 private:
9472
  DISALLOW_IMPLICIT_CONSTRUCTORS(JSWeakMap);
9473
};
9474

    
9475

    
9476
// The JSWeakSet describes EcmaScript Harmony weak sets
9477
class JSWeakSet: public JSWeakCollection {
9478
 public:
9479
  // Casting.
9480
  static inline JSWeakSet* cast(Object* obj);
9481

    
9482
  // Dispatched behavior.
9483
  DECLARE_PRINTER(JSWeakSet)
9484
  DECLARE_VERIFIER(JSWeakSet)
9485

    
9486
 private:
9487
  DISALLOW_IMPLICIT_CONSTRUCTORS(JSWeakSet);
9488
};
9489

    
9490

    
9491
class JSArrayBuffer: public JSObject {
9492
 public:
9493
  // [backing_store]: backing memory for this array
9494
  DECL_ACCESSORS(backing_store, void)
9495

    
9496
  // [byte_length]: length in bytes
9497
  DECL_ACCESSORS(byte_length, Object)
9498

    
9499
  // [flags]
9500
  DECL_ACCESSORS(flag, Smi)
9501

    
9502
  inline bool is_external();
9503
  inline void set_is_external(bool value);
9504

    
9505
  // [weak_next]: linked list of array buffers.
9506
  DECL_ACCESSORS(weak_next, Object)
9507

    
9508
  // [weak_first_array]: weak linked list of views.
9509
  DECL_ACCESSORS(weak_first_view, Object)
9510

    
9511
  // Casting.
9512
  static inline JSArrayBuffer* cast(Object* obj);
9513

    
9514
  // Neutering. Only neuters the buffer, not associated typed arrays.
9515
  void Neuter();
9516

    
9517
  // Dispatched behavior.
9518
  DECLARE_PRINTER(JSArrayBuffer)
9519
  DECLARE_VERIFIER(JSArrayBuffer)
9520

    
9521
  static const int kBackingStoreOffset = JSObject::kHeaderSize;
9522
  static const int kByteLengthOffset = kBackingStoreOffset + kPointerSize;
9523
  static const int kFlagOffset = kByteLengthOffset + kPointerSize;
9524
  static const int kWeakNextOffset = kFlagOffset + kPointerSize;
9525
  static const int kWeakFirstViewOffset = kWeakNextOffset + kPointerSize;
9526
  static const int kSize = kWeakFirstViewOffset + kPointerSize;
9527

    
9528
  static const int kSizeWithInternalFields =
9529
      kSize + v8::ArrayBuffer::kInternalFieldCount * kPointerSize;
9530

    
9531
 private:
9532
  // Bit position in a flag
9533
  static const int kIsExternalBit = 0;
9534

    
9535
  DISALLOW_IMPLICIT_CONSTRUCTORS(JSArrayBuffer);
9536
};
9537

    
9538

    
9539
class JSArrayBufferView: public JSObject {
9540
 public:
9541
  // [buffer]: ArrayBuffer that this typed array views.
9542
  DECL_ACCESSORS(buffer, Object)
9543

    
9544
  // [byte_length]: offset of typed array in bytes.
9545
  DECL_ACCESSORS(byte_offset, Object)
9546

    
9547
  // [byte_length]: length of typed array in bytes.
9548
  DECL_ACCESSORS(byte_length, Object)
9549

    
9550
  // [weak_next]: linked list of typed arrays over the same array buffer.
9551
  DECL_ACCESSORS(weak_next, Object)
9552

    
9553
  // Casting.
9554
  static inline JSArrayBufferView* cast(Object* obj);
9555

    
9556
  DECLARE_VERIFIER(JSArrayBufferView)
9557

    
9558
  static const int kBufferOffset = JSObject::kHeaderSize;
9559
  static const int kByteOffsetOffset = kBufferOffset + kPointerSize;
9560
  static const int kByteLengthOffset = kByteOffsetOffset + kPointerSize;
9561
  static const int kWeakNextOffset = kByteLengthOffset + kPointerSize;
9562
  static const int kViewSize = kWeakNextOffset + kPointerSize;
9563

    
9564
 protected:
9565
  void NeuterView();
9566

    
9567
 private:
9568
  DISALLOW_IMPLICIT_CONSTRUCTORS(JSArrayBufferView);
9569
};
9570

    
9571

    
9572
class JSTypedArray: public JSArrayBufferView {
9573
 public:
9574
  // [length]: length of typed array in elements.
9575
  DECL_ACCESSORS(length, Object)
9576

    
9577
  // Neutering. Only neuters this typed array.
9578
  void Neuter();
9579

    
9580
  // Casting.
9581
  static inline JSTypedArray* cast(Object* obj);
9582

    
9583
  ExternalArrayType type();
9584
  size_t element_size();
9585

    
9586
  // Dispatched behavior.
9587
  DECLARE_PRINTER(JSTypedArray)
9588
  DECLARE_VERIFIER(JSTypedArray)
9589

    
9590
  static const int kLengthOffset = kViewSize + kPointerSize;
9591
  static const int kSize = kLengthOffset + kPointerSize;
9592

    
9593
  static const int kSizeWithInternalFields =
9594
      kSize + v8::ArrayBufferView::kInternalFieldCount * kPointerSize;
9595

    
9596
 private:
9597
  DISALLOW_IMPLICIT_CONSTRUCTORS(JSTypedArray);
9598
};
9599

    
9600

    
9601
class JSDataView: public JSArrayBufferView {
9602
 public:
9603
  // Only neuters this DataView
9604
  void Neuter();
9605

    
9606
  // Casting.
9607
  static inline JSDataView* cast(Object* obj);
9608

    
9609
  // Dispatched behavior.
9610
  DECLARE_PRINTER(JSDataView)
9611
  DECLARE_VERIFIER(JSDataView)
9612

    
9613
  static const int kSize = kViewSize;
9614

    
9615
  static const int kSizeWithInternalFields =
9616
      kSize + v8::ArrayBufferView::kInternalFieldCount * kPointerSize;
9617

    
9618
 private:
9619
  DISALLOW_IMPLICIT_CONSTRUCTORS(JSDataView);
9620
};
9621

    
9622

    
9623
// Foreign describes objects pointing from JavaScript to C structures.
9624
// Since they cannot contain references to JS HeapObjects they can be
9625
// placed in old_data_space.
9626
class Foreign: public HeapObject {
9627
 public:
9628
  // [address]: field containing the address.
9629
  inline Address foreign_address();
9630
  inline void set_foreign_address(Address value);
9631

    
9632
  // Casting.
9633
  static inline Foreign* cast(Object* obj);
9634

    
9635
  // Dispatched behavior.
9636
  inline void ForeignIterateBody(ObjectVisitor* v);
9637

    
9638
  template<typename StaticVisitor>
9639
  inline void ForeignIterateBody();
9640

    
9641
  // Dispatched behavior.
9642
  DECLARE_PRINTER(Foreign)
9643
  DECLARE_VERIFIER(Foreign)
9644

    
9645
  // Layout description.
9646

    
9647
  static const int kForeignAddressOffset = HeapObject::kHeaderSize;
9648
  static const int kSize = kForeignAddressOffset + kPointerSize;
9649

    
9650
  STATIC_CHECK(kForeignAddressOffset == Internals::kForeignAddressOffset);
9651

    
9652
 private:
9653
  DISALLOW_IMPLICIT_CONSTRUCTORS(Foreign);
9654
};
9655

    
9656

    
9657
// The JSArray describes JavaScript Arrays
9658
//  Such an array can be in one of two modes:
9659
//    - fast, backing storage is a FixedArray and length <= elements.length();
9660
//       Please note: push and pop can be used to grow and shrink the array.
9661
//    - slow, backing storage is a HashTable with numbers as keys.
9662
class JSArray: public JSObject {
9663
 public:
9664
  // [length]: The length property.
9665
  DECL_ACCESSORS(length, Object)
9666

    
9667
  // Overload the length setter to skip write barrier when the length
9668
  // is set to a smi. This matches the set function on FixedArray.
9669
  inline void set_length(Smi* length);
9670

    
9671
  MUST_USE_RESULT MaybeObject* JSArrayUpdateLengthFromIndex(uint32_t index,
9672
                                                            Object* value);
9673

    
9674
  // Initialize the array with the given capacity. The function may
9675
  // fail due to out-of-memory situations, but only if the requested
9676
  // capacity is non-zero.
9677
  MUST_USE_RESULT MaybeObject* Initialize(int capacity, int length = 0);
9678

    
9679
  // Initializes the array to a certain length.
9680
  inline bool AllowsSetElementsLength();
9681
  // Can cause GC.
9682
  MUST_USE_RESULT MaybeObject* SetElementsLength(Object* length);
9683

    
9684
  // Set the content of the array to the content of storage.
9685
  MUST_USE_RESULT inline MaybeObject* SetContent(FixedArrayBase* storage);
9686

    
9687
  // Casting.
9688
  static inline JSArray* cast(Object* obj);
9689

    
9690
  // Uses handles.  Ensures that the fixed array backing the JSArray has at
9691
  // least the stated size.
9692
  inline void EnsureSize(int minimum_size_of_backing_fixed_array);
9693

    
9694
  // Dispatched behavior.
9695
  DECLARE_PRINTER(JSArray)
9696
  DECLARE_VERIFIER(JSArray)
9697

    
9698
  // Number of element slots to pre-allocate for an empty array.
9699
  static const int kPreallocatedArrayElements = 4;
9700

    
9701
  // Layout description.
9702
  static const int kLengthOffset = JSObject::kHeaderSize;
9703
  static const int kSize = kLengthOffset + kPointerSize;
9704

    
9705
 private:
9706
  // Expand the fixed array backing of a fast-case JSArray to at least
9707
  // the requested size.
9708
  void Expand(int minimum_size_of_backing_fixed_array);
9709

    
9710
  DISALLOW_IMPLICIT_CONSTRUCTORS(JSArray);
9711
};
9712

    
9713

    
9714
Handle<Object> CacheInitialJSArrayMaps(Handle<Context> native_context,
9715
                                       Handle<Map> initial_map);
9716

    
9717

    
9718
// JSRegExpResult is just a JSArray with a specific initial map.
9719
// This initial map adds in-object properties for "index" and "input"
9720
// properties, as assigned by RegExp.prototype.exec, which allows
9721
// faster creation of RegExp exec results.
9722
// This class just holds constants used when creating the result.
9723
// After creation the result must be treated as a JSArray in all regards.
9724
class JSRegExpResult: public JSArray {
9725
 public:
9726
  // Offsets of object fields.
9727
  static const int kIndexOffset = JSArray::kSize;
9728
  static const int kInputOffset = kIndexOffset + kPointerSize;
9729
  static const int kSize = kInputOffset + kPointerSize;
9730
  // Indices of in-object properties.
9731
  static const int kIndexIndex = 0;
9732
  static const int kInputIndex = 1;
9733
 private:
9734
  DISALLOW_IMPLICIT_CONSTRUCTORS(JSRegExpResult);
9735
};
9736

    
9737

    
9738
class AccessorInfo: public Struct {
9739
 public:
9740
  DECL_ACCESSORS(name, Object)
9741
  DECL_ACCESSORS(flag, Smi)
9742
  DECL_ACCESSORS(expected_receiver_type, Object)
9743

    
9744
  inline bool all_can_read();
9745
  inline void set_all_can_read(bool value);
9746

    
9747
  inline bool all_can_write();
9748
  inline void set_all_can_write(bool value);
9749

    
9750
  inline bool prohibits_overwriting();
9751
  inline void set_prohibits_overwriting(bool value);
9752

    
9753
  inline PropertyAttributes property_attributes();
9754
  inline void set_property_attributes(PropertyAttributes attributes);
9755

    
9756
  // Checks whether the given receiver is compatible with this accessor.
9757
  inline bool IsCompatibleReceiver(Object* receiver);
9758

    
9759
  static inline AccessorInfo* cast(Object* obj);
9760

    
9761
  // Dispatched behavior.
9762
  DECLARE_VERIFIER(AccessorInfo)
9763

    
9764
  // Append all descriptors to the array that are not already there.
9765
  // Return number added.
9766
  static int AppendUnique(Handle<Object> descriptors,
9767
                          Handle<FixedArray> array,
9768
                          int valid_descriptors);
9769

    
9770
  static const int kNameOffset = HeapObject::kHeaderSize;
9771
  static const int kFlagOffset = kNameOffset + kPointerSize;
9772
  static const int kExpectedReceiverTypeOffset = kFlagOffset + kPointerSize;
9773
  static const int kSize = kExpectedReceiverTypeOffset + kPointerSize;
9774

    
9775
 private:
9776
  // Bit positions in flag.
9777
  static const int kAllCanReadBit = 0;
9778
  static const int kAllCanWriteBit = 1;
9779
  static const int kProhibitsOverwritingBit = 2;
9780
  class AttributesField: public BitField<PropertyAttributes, 3, 3> {};
9781

    
9782
  DISALLOW_IMPLICIT_CONSTRUCTORS(AccessorInfo);
9783
};
9784

    
9785

    
9786
enum AccessorDescriptorType {
9787
  kDescriptorBitmaskCompare,
9788
  kDescriptorPointerCompare,
9789
  kDescriptorPrimitiveValue,
9790
  kDescriptorObjectDereference,
9791
  kDescriptorPointerDereference,
9792
  kDescriptorPointerShift,
9793
  kDescriptorReturnObject
9794
};
9795

    
9796

    
9797
struct BitmaskCompareDescriptor {
9798
  uint32_t bitmask;
9799
  uint32_t compare_value;
9800
  uint8_t size;  // Must be in {1,2,4}.
9801
};
9802

    
9803

    
9804
struct PointerCompareDescriptor {
9805
  void* compare_value;
9806
};
9807

    
9808

    
9809
struct PrimitiveValueDescriptor {
9810
  v8::DeclaredAccessorDescriptorDataType data_type;
9811
  uint8_t bool_offset;  // Must be in [0,7], used for kDescriptorBoolType.
9812
};
9813

    
9814

    
9815
struct ObjectDerefenceDescriptor {
9816
  uint8_t internal_field;
9817
};
9818

    
9819

    
9820
struct PointerShiftDescriptor {
9821
  int16_t byte_offset;
9822
};
9823

    
9824

    
9825
struct DeclaredAccessorDescriptorData {
9826
  AccessorDescriptorType type;
9827
  union {
9828
    struct BitmaskCompareDescriptor bitmask_compare_descriptor;
9829
    struct PointerCompareDescriptor pointer_compare_descriptor;
9830
    struct PrimitiveValueDescriptor primitive_value_descriptor;
9831
    struct ObjectDerefenceDescriptor object_dereference_descriptor;
9832
    struct PointerShiftDescriptor pointer_shift_descriptor;
9833
  };
9834
};
9835

    
9836

    
9837
class DeclaredAccessorDescriptor;
9838

    
9839

    
9840
class DeclaredAccessorDescriptorIterator {
9841
 public:
9842
  explicit DeclaredAccessorDescriptorIterator(
9843
      DeclaredAccessorDescriptor* descriptor);
9844
  const DeclaredAccessorDescriptorData* Next();
9845
  bool Complete() const { return length_ == offset_; }
9846
 private:
9847
  uint8_t* array_;
9848
  const int length_;
9849
  int offset_;
9850
  DISALLOW_IMPLICIT_CONSTRUCTORS(DeclaredAccessorDescriptorIterator);
9851
};
9852

    
9853

    
9854
class DeclaredAccessorDescriptor: public Struct {
9855
 public:
9856
  DECL_ACCESSORS(serialized_data, ByteArray)
9857

    
9858
  static inline DeclaredAccessorDescriptor* cast(Object* obj);
9859

    
9860
  static Handle<DeclaredAccessorDescriptor> Create(
9861
      Isolate* isolate,
9862
      const DeclaredAccessorDescriptorData& data,
9863
      Handle<DeclaredAccessorDescriptor> previous);
9864

    
9865
  // Dispatched behavior.
9866
  DECLARE_PRINTER(DeclaredAccessorDescriptor)
9867
  DECLARE_VERIFIER(DeclaredAccessorDescriptor)
9868

    
9869
  static const int kSerializedDataOffset = HeapObject::kHeaderSize;
9870
  static const int kSize = kSerializedDataOffset + kPointerSize;
9871

    
9872
 private:
9873
  DISALLOW_IMPLICIT_CONSTRUCTORS(DeclaredAccessorDescriptor);
9874
};
9875

    
9876

    
9877
class DeclaredAccessorInfo: public AccessorInfo {
9878
 public:
9879
  DECL_ACCESSORS(descriptor, DeclaredAccessorDescriptor)
9880

    
9881
  static inline DeclaredAccessorInfo* cast(Object* obj);
9882

    
9883
  // Dispatched behavior.
9884
  DECLARE_PRINTER(DeclaredAccessorInfo)
9885
  DECLARE_VERIFIER(DeclaredAccessorInfo)
9886

    
9887
  static const int kDescriptorOffset = AccessorInfo::kSize;
9888
  static const int kSize = kDescriptorOffset + kPointerSize;
9889

    
9890
 private:
9891
  DISALLOW_IMPLICIT_CONSTRUCTORS(DeclaredAccessorInfo);
9892
};
9893

    
9894

    
9895
// An accessor must have a getter, but can have no setter.
9896
//
9897
// When setting a property, V8 searches accessors in prototypes.
9898
// If an accessor was found and it does not have a setter,
9899
// the request is ignored.
9900
//
9901
// If the accessor in the prototype has the READ_ONLY property attribute, then
9902
// a new value is added to the local object when the property is set.
9903
// This shadows the accessor in the prototype.
9904
class ExecutableAccessorInfo: public AccessorInfo {
9905
 public:
9906
  DECL_ACCESSORS(getter, Object)
9907
  DECL_ACCESSORS(setter, Object)
9908
  DECL_ACCESSORS(data, Object)
9909

    
9910
  static inline ExecutableAccessorInfo* cast(Object* obj);
9911

    
9912
  // Dispatched behavior.
9913
  DECLARE_PRINTER(ExecutableAccessorInfo)
9914
  DECLARE_VERIFIER(ExecutableAccessorInfo)
9915

    
9916
  static const int kGetterOffset = AccessorInfo::kSize;
9917
  static const int kSetterOffset = kGetterOffset + kPointerSize;
9918
  static const int kDataOffset = kSetterOffset + kPointerSize;
9919
  static const int kSize = kDataOffset + kPointerSize;
9920

    
9921
 private:
9922
  DISALLOW_IMPLICIT_CONSTRUCTORS(ExecutableAccessorInfo);
9923
};
9924

    
9925

    
9926
// Support for JavaScript accessors: A pair of a getter and a setter. Each
9927
// accessor can either be
9928
//   * a pointer to a JavaScript function or proxy: a real accessor
9929
//   * undefined: considered an accessor by the spec, too, strangely enough
9930
//   * the hole: an accessor which has not been set
9931
//   * a pointer to a map: a transition used to ensure map sharing
9932
// access_flags provides the ability to override access checks on access check
9933
// failure.
9934
class AccessorPair: public Struct {
9935
 public:
9936
  DECL_ACCESSORS(getter, Object)
9937
  DECL_ACCESSORS(setter, Object)
9938
  DECL_ACCESSORS(access_flags, Smi)
9939

    
9940
  inline void set_access_flags(v8::AccessControl access_control);
9941
  inline bool all_can_read();
9942
  inline bool all_can_write();
9943
  inline bool prohibits_overwriting();
9944

    
9945
  static inline AccessorPair* cast(Object* obj);
9946

    
9947
  static Handle<AccessorPair> Copy(Handle<AccessorPair> pair);
9948

    
9949
  Object* get(AccessorComponent component) {
9950
    return component == ACCESSOR_GETTER ? getter() : setter();
9951
  }
9952

    
9953
  void set(AccessorComponent component, Object* value) {
9954
    if (component == ACCESSOR_GETTER) {
9955
      set_getter(value);
9956
    } else {
9957
      set_setter(value);
9958
    }
9959
  }
9960

    
9961
  // Note: Returns undefined instead in case of a hole.
9962
  Object* GetComponent(AccessorComponent component);
9963

    
9964
  // Set both components, skipping arguments which are a JavaScript null.
9965
  void SetComponents(Object* getter, Object* setter) {
9966
    if (!getter->IsNull()) set_getter(getter);
9967
    if (!setter->IsNull()) set_setter(setter);
9968
  }
9969

    
9970
  bool ContainsAccessor() {
9971
    return IsJSAccessor(getter()) || IsJSAccessor(setter());
9972
  }
9973

    
9974
  // Dispatched behavior.
9975
  DECLARE_PRINTER(AccessorPair)
9976
  DECLARE_VERIFIER(AccessorPair)
9977

    
9978
  static const int kGetterOffset = HeapObject::kHeaderSize;
9979
  static const int kSetterOffset = kGetterOffset + kPointerSize;
9980
  static const int kAccessFlagsOffset = kSetterOffset + kPointerSize;
9981
  static const int kSize = kAccessFlagsOffset + kPointerSize;
9982

    
9983
 private:
9984
  static const int kAllCanReadBit = 0;
9985
  static const int kAllCanWriteBit = 1;
9986
  static const int kProhibitsOverwritingBit = 2;
9987

    
9988
  // Strangely enough, in addition to functions and harmony proxies, the spec
9989
  // requires us to consider undefined as a kind of accessor, too:
9990
  //    var obj = {};
9991
  //    Object.defineProperty(obj, "foo", {get: undefined});
9992
  //    assertTrue("foo" in obj);
9993
  bool IsJSAccessor(Object* obj) {
9994
    return obj->IsSpecFunction() || obj->IsUndefined();
9995
  }
9996

    
9997
  DISALLOW_IMPLICIT_CONSTRUCTORS(AccessorPair);
9998
};
9999

    
10000

    
10001
class AccessCheckInfo: public Struct {
10002
 public:
10003
  DECL_ACCESSORS(named_callback, Object)
10004
  DECL_ACCESSORS(indexed_callback, Object)
10005
  DECL_ACCESSORS(data, Object)
10006

    
10007
  static inline AccessCheckInfo* cast(Object* obj);
10008

    
10009
  // Dispatched behavior.
10010
  DECLARE_PRINTER(AccessCheckInfo)
10011
  DECLARE_VERIFIER(AccessCheckInfo)
10012

    
10013
  static const int kNamedCallbackOffset   = HeapObject::kHeaderSize;
10014
  static const int kIndexedCallbackOffset = kNamedCallbackOffset + kPointerSize;
10015
  static const int kDataOffset = kIndexedCallbackOffset + kPointerSize;
10016
  static const int kSize = kDataOffset + kPointerSize;
10017

    
10018
 private:
10019
  DISALLOW_IMPLICIT_CONSTRUCTORS(AccessCheckInfo);
10020
};
10021

    
10022

    
10023
class InterceptorInfo: public Struct {
10024
 public:
10025
  DECL_ACCESSORS(getter, Object)
10026
  DECL_ACCESSORS(setter, Object)
10027
  DECL_ACCESSORS(query, Object)
10028
  DECL_ACCESSORS(deleter, Object)
10029
  DECL_ACCESSORS(enumerator, Object)
10030
  DECL_ACCESSORS(data, Object)
10031

    
10032
  static inline InterceptorInfo* cast(Object* obj);
10033

    
10034
  // Dispatched behavior.
10035
  DECLARE_PRINTER(InterceptorInfo)
10036
  DECLARE_VERIFIER(InterceptorInfo)
10037

    
10038
  static const int kGetterOffset = HeapObject::kHeaderSize;
10039
  static const int kSetterOffset = kGetterOffset + kPointerSize;
10040
  static const int kQueryOffset = kSetterOffset + kPointerSize;
10041
  static const int kDeleterOffset = kQueryOffset + kPointerSize;
10042
  static const int kEnumeratorOffset = kDeleterOffset + kPointerSize;
10043
  static const int kDataOffset = kEnumeratorOffset + kPointerSize;
10044
  static const int kSize = kDataOffset + kPointerSize;
10045

    
10046
 private:
10047
  DISALLOW_IMPLICIT_CONSTRUCTORS(InterceptorInfo);
10048
};
10049

    
10050

    
10051
class CallHandlerInfo: public Struct {
10052
 public:
10053
  DECL_ACCESSORS(callback, Object)
10054
  DECL_ACCESSORS(data, Object)
10055

    
10056
  static inline CallHandlerInfo* cast(Object* obj);
10057

    
10058
  // Dispatched behavior.
10059
  DECLARE_PRINTER(CallHandlerInfo)
10060
  DECLARE_VERIFIER(CallHandlerInfo)
10061

    
10062
  static const int kCallbackOffset = HeapObject::kHeaderSize;
10063
  static const int kDataOffset = kCallbackOffset + kPointerSize;
10064
  static const int kSize = kDataOffset + kPointerSize;
10065

    
10066
 private:
10067
  DISALLOW_IMPLICIT_CONSTRUCTORS(CallHandlerInfo);
10068
};
10069

    
10070

    
10071
class TemplateInfo: public Struct {
10072
 public:
10073
  DECL_ACCESSORS(tag, Object)
10074
  DECL_ACCESSORS(property_list, Object)
10075
  DECL_ACCESSORS(property_accessors, Object)
10076

    
10077
  DECLARE_VERIFIER(TemplateInfo)
10078

    
10079
  static const int kTagOffset = HeapObject::kHeaderSize;
10080
  static const int kPropertyListOffset = kTagOffset + kPointerSize;
10081
  static const int kPropertyAccessorsOffset =
10082
      kPropertyListOffset + kPointerSize;
10083
  static const int kHeaderSize = kPropertyAccessorsOffset + kPointerSize;
10084

    
10085
 private:
10086
  DISALLOW_IMPLICIT_CONSTRUCTORS(TemplateInfo);
10087
};
10088

    
10089

    
10090
class FunctionTemplateInfo: public TemplateInfo {
10091
 public:
10092
  DECL_ACCESSORS(serial_number, Object)
10093
  DECL_ACCESSORS(call_code, Object)
10094
  DECL_ACCESSORS(prototype_template, Object)
10095
  DECL_ACCESSORS(parent_template, Object)
10096
  DECL_ACCESSORS(named_property_handler, Object)
10097
  DECL_ACCESSORS(indexed_property_handler, Object)
10098
  DECL_ACCESSORS(instance_template, Object)
10099
  DECL_ACCESSORS(class_name, Object)
10100
  DECL_ACCESSORS(signature, Object)
10101
  DECL_ACCESSORS(instance_call_handler, Object)
10102
  DECL_ACCESSORS(access_check_info, Object)
10103
  DECL_ACCESSORS(flag, Smi)
10104

    
10105
  inline int length();
10106
  inline void set_length(int value);
10107

    
10108
  // Following properties use flag bits.
10109
  DECL_BOOLEAN_ACCESSORS(hidden_prototype)
10110
  DECL_BOOLEAN_ACCESSORS(undetectable)
10111
  // If the bit is set, object instances created by this function
10112
  // requires access check.
10113
  DECL_BOOLEAN_ACCESSORS(needs_access_check)
10114
  DECL_BOOLEAN_ACCESSORS(read_only_prototype)
10115
  DECL_BOOLEAN_ACCESSORS(remove_prototype)
10116
  DECL_BOOLEAN_ACCESSORS(do_not_cache)
10117

    
10118
  static inline FunctionTemplateInfo* cast(Object* obj);
10119

    
10120
  // Dispatched behavior.
10121
  DECLARE_PRINTER(FunctionTemplateInfo)
10122
  DECLARE_VERIFIER(FunctionTemplateInfo)
10123

    
10124
  static const int kSerialNumberOffset = TemplateInfo::kHeaderSize;
10125
  static const int kCallCodeOffset = kSerialNumberOffset + kPointerSize;
10126
  static const int kPrototypeTemplateOffset =
10127
      kCallCodeOffset + kPointerSize;
10128
  static const int kParentTemplateOffset =
10129
      kPrototypeTemplateOffset + kPointerSize;
10130
  static const int kNamedPropertyHandlerOffset =
10131
      kParentTemplateOffset + kPointerSize;
10132
  static const int kIndexedPropertyHandlerOffset =
10133
      kNamedPropertyHandlerOffset + kPointerSize;
10134
  static const int kInstanceTemplateOffset =
10135
      kIndexedPropertyHandlerOffset + kPointerSize;
10136
  static const int kClassNameOffset = kInstanceTemplateOffset + kPointerSize;
10137
  static const int kSignatureOffset = kClassNameOffset + kPointerSize;
10138
  static const int kInstanceCallHandlerOffset = kSignatureOffset + kPointerSize;
10139
  static const int kAccessCheckInfoOffset =
10140
      kInstanceCallHandlerOffset + kPointerSize;
10141
  static const int kFlagOffset = kAccessCheckInfoOffset + kPointerSize;
10142
  static const int kLengthOffset = kFlagOffset + kPointerSize;
10143
  static const int kSize = kLengthOffset + kPointerSize;
10144

    
10145
 private:
10146
  // Bit position in the flag, from least significant bit position.
10147
  static const int kHiddenPrototypeBit   = 0;
10148
  static const int kUndetectableBit      = 1;
10149
  static const int kNeedsAccessCheckBit  = 2;
10150
  static const int kReadOnlyPrototypeBit = 3;
10151
  static const int kRemovePrototypeBit   = 4;
10152
  static const int kDoNotCacheBit        = 5;
10153

    
10154
  DISALLOW_IMPLICIT_CONSTRUCTORS(FunctionTemplateInfo);
10155
};
10156

    
10157

    
10158
class ObjectTemplateInfo: public TemplateInfo {
10159
 public:
10160
  DECL_ACCESSORS(constructor, Object)
10161
  DECL_ACCESSORS(internal_field_count, Object)
10162

    
10163
  static inline ObjectTemplateInfo* cast(Object* obj);
10164

    
10165
  // Dispatched behavior.
10166
  DECLARE_PRINTER(ObjectTemplateInfo)
10167
  DECLARE_VERIFIER(ObjectTemplateInfo)
10168

    
10169
  static const int kConstructorOffset = TemplateInfo::kHeaderSize;
10170
  static const int kInternalFieldCountOffset =
10171
      kConstructorOffset + kPointerSize;
10172
  static const int kSize = kInternalFieldCountOffset + kPointerSize;
10173
};
10174

    
10175

    
10176
class SignatureInfo: public Struct {
10177
 public:
10178
  DECL_ACCESSORS(receiver, Object)
10179
  DECL_ACCESSORS(args, Object)
10180

    
10181
  static inline SignatureInfo* cast(Object* obj);
10182

    
10183
  // Dispatched behavior.
10184
  DECLARE_PRINTER(SignatureInfo)
10185
  DECLARE_VERIFIER(SignatureInfo)
10186

    
10187
  static const int kReceiverOffset = Struct::kHeaderSize;
10188
  static const int kArgsOffset     = kReceiverOffset + kPointerSize;
10189
  static const int kSize           = kArgsOffset + kPointerSize;
10190

    
10191
 private:
10192
  DISALLOW_IMPLICIT_CONSTRUCTORS(SignatureInfo);
10193
};
10194

    
10195

    
10196
class TypeSwitchInfo: public Struct {
10197
 public:
10198
  DECL_ACCESSORS(types, Object)
10199

    
10200
  static inline TypeSwitchInfo* cast(Object* obj);
10201

    
10202
  // Dispatched behavior.
10203
  DECLARE_PRINTER(TypeSwitchInfo)
10204
  DECLARE_VERIFIER(TypeSwitchInfo)
10205

    
10206
  static const int kTypesOffset = Struct::kHeaderSize;
10207
  static const int kSize        = kTypesOffset + kPointerSize;
10208
};
10209

    
10210

    
10211
#ifdef ENABLE_DEBUGGER_SUPPORT
10212
// The DebugInfo class holds additional information for a function being
10213
// debugged.
10214
class DebugInfo: public Struct {
10215
 public:
10216
  // The shared function info for the source being debugged.
10217
  DECL_ACCESSORS(shared, SharedFunctionInfo)
10218
  // Code object for the original code.
10219
  DECL_ACCESSORS(original_code, Code)
10220
  // Code object for the patched code. This code object is the code object
10221
  // currently active for the function.
10222
  DECL_ACCESSORS(code, Code)
10223
  // Fixed array holding status information for each active break point.
10224
  DECL_ACCESSORS(break_points, FixedArray)
10225

    
10226
  // Check if there is a break point at a code position.
10227
  bool HasBreakPoint(int code_position);
10228
  // Get the break point info object for a code position.
10229
  Object* GetBreakPointInfo(int code_position);
10230
  // Clear a break point.
10231
  static void ClearBreakPoint(Handle<DebugInfo> debug_info,
10232
                              int code_position,
10233
                              Handle<Object> break_point_object);
10234
  // Set a break point.
10235
  static void SetBreakPoint(Handle<DebugInfo> debug_info, int code_position,
10236
                            int source_position, int statement_position,
10237
                            Handle<Object> break_point_object);
10238
  // Get the break point objects for a code position.
10239
  Object* GetBreakPointObjects(int code_position);
10240
  // Find the break point info holding this break point object.
10241
  static Object* FindBreakPointInfo(Handle<DebugInfo> debug_info,
10242
                                    Handle<Object> break_point_object);
10243
  // Get the number of break points for this function.
10244
  int GetBreakPointCount();
10245

    
10246
  static inline DebugInfo* cast(Object* obj);
10247

    
10248
  // Dispatched behavior.
10249
  DECLARE_PRINTER(DebugInfo)
10250
  DECLARE_VERIFIER(DebugInfo)
10251

    
10252
  static const int kSharedFunctionInfoIndex = Struct::kHeaderSize;
10253
  static const int kOriginalCodeIndex = kSharedFunctionInfoIndex + kPointerSize;
10254
  static const int kPatchedCodeIndex = kOriginalCodeIndex + kPointerSize;
10255
  static const int kActiveBreakPointsCountIndex =
10256
      kPatchedCodeIndex + kPointerSize;
10257
  static const int kBreakPointsStateIndex =
10258
      kActiveBreakPointsCountIndex + kPointerSize;
10259
  static const int kSize = kBreakPointsStateIndex + kPointerSize;
10260

    
10261
 private:
10262
  static const int kNoBreakPointInfo = -1;
10263

    
10264
  // Lookup the index in the break_points array for a code position.
10265
  int GetBreakPointInfoIndex(int code_position);
10266

    
10267
  DISALLOW_IMPLICIT_CONSTRUCTORS(DebugInfo);
10268
};
10269

    
10270

    
10271
// The BreakPointInfo class holds information for break points set in a
10272
// function. The DebugInfo object holds a BreakPointInfo object for each code
10273
// position with one or more break points.
10274
class BreakPointInfo: public Struct {
10275
 public:
10276
  // The position in the code for the break point.
10277
  DECL_ACCESSORS(code_position, Smi)
10278
  // The position in the source for the break position.
10279
  DECL_ACCESSORS(source_position, Smi)
10280
  // The position in the source for the last statement before this break
10281
  // position.
10282
  DECL_ACCESSORS(statement_position, Smi)
10283
  // List of related JavaScript break points.
10284
  DECL_ACCESSORS(break_point_objects, Object)
10285

    
10286
  // Removes a break point.
10287
  static void ClearBreakPoint(Handle<BreakPointInfo> info,
10288
                              Handle<Object> break_point_object);
10289
  // Set a break point.
10290
  static void SetBreakPoint(Handle<BreakPointInfo> info,
10291
                            Handle<Object> break_point_object);
10292
  // Check if break point info has this break point object.
10293
  static bool HasBreakPointObject(Handle<BreakPointInfo> info,
10294
                                  Handle<Object> break_point_object);
10295
  // Get the number of break points for this code position.
10296
  int GetBreakPointCount();
10297

    
10298
  static inline BreakPointInfo* cast(Object* obj);
10299

    
10300
  // Dispatched behavior.
10301
  DECLARE_PRINTER(BreakPointInfo)
10302
  DECLARE_VERIFIER(BreakPointInfo)
10303

    
10304
  static const int kCodePositionIndex = Struct::kHeaderSize;
10305
  static const int kSourcePositionIndex = kCodePositionIndex + kPointerSize;
10306
  static const int kStatementPositionIndex =
10307
      kSourcePositionIndex + kPointerSize;
10308
  static const int kBreakPointObjectsIndex =
10309
      kStatementPositionIndex + kPointerSize;
10310
  static const int kSize = kBreakPointObjectsIndex + kPointerSize;
10311

    
10312
 private:
10313
  DISALLOW_IMPLICIT_CONSTRUCTORS(BreakPointInfo);
10314
};
10315
#endif  // ENABLE_DEBUGGER_SUPPORT
10316

    
10317

    
10318
#undef DECL_BOOLEAN_ACCESSORS
10319
#undef DECL_ACCESSORS
10320
#undef DECLARE_VERIFIER
10321

    
10322
#define VISITOR_SYNCHRONIZATION_TAGS_LIST(V)                            \
10323
  V(kStringTable, "string_table", "(Internalized strings)")             \
10324
  V(kExternalStringsTable, "external_strings_table", "(External strings)") \
10325
  V(kStrongRootList, "strong_root_list", "(Strong roots)")              \
10326
  V(kInternalizedString, "internalized_string", "(Internal string)")    \
10327
  V(kBootstrapper, "bootstrapper", "(Bootstrapper)")                    \
10328
  V(kTop, "top", "(Isolate)")                                           \
10329
  V(kRelocatable, "relocatable", "(Relocatable)")                       \
10330
  V(kDebug, "debug", "(Debugger)")                                      \
10331
  V(kCompilationCache, "compilationcache", "(Compilation cache)")       \
10332
  V(kHandleScope, "handlescope", "(Handle scope)")                      \
10333
  V(kBuiltins, "builtins", "(Builtins)")                                \
10334
  V(kGlobalHandles, "globalhandles", "(Global handles)")                \
10335
  V(kEternalHandles, "eternalhandles", "(Eternal handles)")             \
10336
  V(kThreadManager, "threadmanager", "(Thread manager)")                \
10337
  V(kExtensions, "Extensions", "(Extensions)")
10338

    
10339
class VisitorSynchronization : public AllStatic {
10340
 public:
10341
#define DECLARE_ENUM(enum_item, ignore1, ignore2) enum_item,
10342
  enum SyncTag {
10343
    VISITOR_SYNCHRONIZATION_TAGS_LIST(DECLARE_ENUM)
10344
    kNumberOfSyncTags
10345
  };
10346
#undef DECLARE_ENUM
10347

    
10348
  static const char* const kTags[kNumberOfSyncTags];
10349
  static const char* const kTagNames[kNumberOfSyncTags];
10350
};
10351

    
10352
// Abstract base class for visiting, and optionally modifying, the
10353
// pointers contained in Objects. Used in GC and serialization/deserialization.
10354
class ObjectVisitor BASE_EMBEDDED {
10355
 public:
10356
  virtual ~ObjectVisitor() {}
10357

    
10358
  // Visits a contiguous arrays of pointers in the half-open range
10359
  // [start, end). Any or all of the values may be modified on return.
10360
  virtual void VisitPointers(Object** start, Object** end) = 0;
10361

    
10362
  // Handy shorthand for visiting a single pointer.
10363
  virtual void VisitPointer(Object** p) { VisitPointers(p, p + 1); }
10364

    
10365
  // To allow lazy clearing of inline caches the visitor has
10366
  // a rich interface for iterating over Code objects..
10367

    
10368
  // Visits a code target in the instruction stream.
10369
  virtual void VisitCodeTarget(RelocInfo* rinfo);
10370

    
10371
  // Visits a code entry in a JS function.
10372
  virtual void VisitCodeEntry(Address entry_address);
10373

    
10374
  // Visits a global property cell reference in the instruction stream.
10375
  virtual void VisitCell(RelocInfo* rinfo);
10376

    
10377
  // Visits a runtime entry in the instruction stream.
10378
  virtual void VisitRuntimeEntry(RelocInfo* rinfo) {}
10379

    
10380
  // Visits the resource of an ASCII or two-byte string.
10381
  virtual void VisitExternalAsciiString(
10382
      v8::String::ExternalAsciiStringResource** resource) {}
10383
  virtual void VisitExternalTwoByteString(
10384
      v8::String::ExternalStringResource** resource) {}
10385

    
10386
  // Visits a debug call target in the instruction stream.
10387
  virtual void VisitDebugTarget(RelocInfo* rinfo);
10388

    
10389
  // Visits the byte sequence in a function's prologue that contains information
10390
  // about the code's age.
10391
  virtual void VisitCodeAgeSequence(RelocInfo* rinfo);
10392

    
10393
  // Visit pointer embedded into a code object.
10394
  virtual void VisitEmbeddedPointer(RelocInfo* rinfo);
10395

    
10396
  // Visits an external reference embedded into a code object.
10397
  virtual void VisitExternalReference(RelocInfo* rinfo);
10398

    
10399
  // Visits an external reference. The value may be modified on return.
10400
  virtual void VisitExternalReference(Address* p) {}
10401

    
10402
  // Visits a handle that has an embedder-assigned class ID.
10403
  virtual void VisitEmbedderReference(Object** p, uint16_t class_id) {}
10404

    
10405
  // Intended for serialization/deserialization checking: insert, or
10406
  // check for the presence of, a tag at this position in the stream.
10407
  // Also used for marking up GC roots in heap snapshots.
10408
  virtual void Synchronize(VisitorSynchronization::SyncTag tag) {}
10409
};
10410

    
10411

    
10412
class StructBodyDescriptor : public
10413
  FlexibleBodyDescriptor<HeapObject::kHeaderSize> {
10414
 public:
10415
  static inline int SizeOf(Map* map, HeapObject* object) {
10416
    return map->instance_size();
10417
  }
10418
};
10419

    
10420

    
10421
// BooleanBit is a helper class for setting and getting a bit in an
10422
// integer or Smi.
10423
class BooleanBit : public AllStatic {
10424
 public:
10425
  static inline bool get(Smi* smi, int bit_position) {
10426
    return get(smi->value(), bit_position);
10427
  }
10428

    
10429
  static inline bool get(int value, int bit_position) {
10430
    return (value & (1 << bit_position)) != 0;
10431
  }
10432

    
10433
  static inline Smi* set(Smi* smi, int bit_position, bool v) {
10434
    return Smi::FromInt(set(smi->value(), bit_position, v));
10435
  }
10436

    
10437
  static inline int set(int value, int bit_position, bool v) {
10438
    if (v) {
10439
      value |= (1 << bit_position);
10440
    } else {
10441
      value &= ~(1 << bit_position);
10442
    }
10443
    return value;
10444
  }
10445
};
10446

    
10447
} }  // namespace v8::internal
10448

    
10449
#endif  // V8_OBJECTS_H_