13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved.
2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without
3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are
4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met:
5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Redistributions of source code must retain the above copyright
7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       notice, this list of conditions and the following disclaimer.
8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Redistributions in binary form must reproduce the above
9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       copyright notice, this list of conditions and the following
10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       disclaimer in the documentation and/or other materials provided
11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       with the distribution.
12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Neither the name of Google Inc. nor the names of its
13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       contributors may be used to endorse or promote products derived
14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       from this software without specific prior written permission.
15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifndef V8_OBJECTS_H_
29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define V8_OBJECTS_H_
30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
31257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#include "allocation.h"
32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "builtins.h"
33257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#include "list.h"
343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#include "property-details.h"
35589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch#include "smart-array-pointer.h"
36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "unicode-inl.h"
373ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block#if V8_TARGET_ARCH_ARM
383ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block#include "arm/constants-arm.h"
393100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu#elif V8_TARGET_ARCH_MIPS
403100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu#include "mips/constants-mips.h"
413ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block#endif
423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#include "v8checks.h"
433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
4650ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen// Most object types in the V8 JavaScript are described in this file.
47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Inheritance hierarchy:
495913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck// - MaybeObject    (an object or a failure)
505913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck//   - Failure      (immediate for marking failed operation)
51a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//   - Object
52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     - Smi          (immediate small integer)
53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     - HeapObject   (superclass for everything allocated in the heap)
543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch//       - JSReceiver  (suitable for property access)
553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch//         - JSObject
563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch//           - JSArray
573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch//           - JSSet
583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch//           - JSMap
5969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch//           - JSWeakMap
603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch//           - JSRegExp
613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch//           - JSFunction
623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch//           - GlobalObject
633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch//             - JSGlobalObject
643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch//             - JSBuiltinsObject
653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch//           - JSGlobalProxy
663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch//           - JSValue
673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch//             - JSDate
683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch//           - JSMessageObject
693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch//         - JSProxy
703fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch//           - JSFunctionProxy
7169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch//       - FixedArrayBase
7269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch//         - ByteArray
7369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch//         - FixedArray
7469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch//           - DescriptorArray
7569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch//           - HashTable
7669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch//             - Dictionary
7769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch//             - SymbolTable
7869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch//             - CompilationCacheTable
7969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch//             - CodeCacheHashTable
8069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch//             - MapCache
8169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch//           - Context
8269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch//           - JSFunctionResultCache
833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch//           - ScopeInfo
8469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch//         - FixedDoubleArray
8569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch//         - ExternalArray
8669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch//           - ExternalPixelArray
8769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch//           - ExternalByteArray
8869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch//           - ExternalUnsignedByteArray
8969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch//           - ExternalShortArray
9069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch//           - ExternalUnsignedShortArray
9169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch//           - ExternalIntArray
9269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch//           - ExternalUnsignedIntArray
9369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch//           - ExternalFloatArray
94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       - String
95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//         - SeqString
96a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//           - SeqAsciiString
97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//           - SeqTwoByteString
9869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch//         - SlicedString
99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//         - ConsString
100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//         - ExternalString
101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//           - ExternalAsciiString
102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//           - ExternalTwoByteString
103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       - HeapNumber
104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       - Code
105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       - Map
106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       - Oddball
107257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch//       - Foreign
108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       - SharedFunctionInfo
109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       - Struct
110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//         - AccessorInfo
1113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch//         - AccessorPair
112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//         - AccessCheckInfo
113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//         - InterceptorInfo
114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//         - CallHandlerInfo
115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//         - TemplateInfo
116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//           - FunctionTemplateInfo
117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//           - ObjectTemplateInfo
118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//         - Script
119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//         - SignatureInfo
120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//         - TypeSwitchInfo
121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//         - DebugInfo
122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//         - BreakPointInfo
1236ded16be15dd865a9b21ea304d5273c8be299c87Steve Block//         - CodeCache
124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Formats of Object*:
126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//  Smi:        [31 bit signed int] 0
127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//  HeapObject: [32 bit direct pointer] (4 byte aligned) | 01
128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//  Failure:    [30 bit signed int] 11
129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 {
131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal {
132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
133589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochenum ElementsKind {
1343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // The "fast" kind for elements that only contain SMI values. Must be first
1353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // to make it possible to efficiently check maps for this kind.
1363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  FAST_SMI_ONLY_ELEMENTS,
1373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // The "fast" kind for tagged values. Must be second to make it possible to
1393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // efficiently check maps for this and the FAST_SMI_ONLY_ELEMENTS kind
1403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // together at once.
141589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  FAST_ELEMENTS,
142589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
143589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // The "fast" kind for unwrapped, non-tagged double values.
144589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  FAST_DOUBLE_ELEMENTS,
145589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
146589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // The "slow" kind.
147589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  DICTIONARY_ELEMENTS,
148589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  NON_STRICT_ARGUMENTS_ELEMENTS,
149589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // The "fast" kind for external arrays
150589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  EXTERNAL_BYTE_ELEMENTS,
151589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  EXTERNAL_UNSIGNED_BYTE_ELEMENTS,
152589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  EXTERNAL_SHORT_ELEMENTS,
153589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  EXTERNAL_UNSIGNED_SHORT_ELEMENTS,
154589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  EXTERNAL_INT_ELEMENTS,
155589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  EXTERNAL_UNSIGNED_INT_ELEMENTS,
156589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  EXTERNAL_FLOAT_ELEMENTS,
157589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  EXTERNAL_DOUBLE_ELEMENTS,
158589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  EXTERNAL_PIXEL_ELEMENTS,
159589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
160589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // Derived constants from ElementsKind
161589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND = EXTERNAL_BYTE_ELEMENTS,
162589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  LAST_EXTERNAL_ARRAY_ELEMENTS_KIND = EXTERNAL_PIXEL_ELEMENTS,
1633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  FIRST_ELEMENTS_KIND = FAST_SMI_ONLY_ELEMENTS,
164589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  LAST_ELEMENTS_KIND = EXTERNAL_PIXEL_ELEMENTS
165589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch};
166589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
1673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochenum CompareMapMode {
1683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  REQUIRE_EXACT_MAP,
1693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ALLOW_ELEMENT_TRANSITION_MAPS
1703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch};
17185b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
1723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochenum KeyedAccessGrowMode {
1733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  DO_NOT_ALLOW_JSARRAY_GROWTH,
1743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ALLOW_JSARRAY_GROWTH
1753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch};
17685b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
1773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst int kElementsKindCount = LAST_ELEMENTS_KIND - FIRST_ELEMENTS_KIND + 1;
17885b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
1793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid PrintElementsKind(FILE* out, ElementsKind kind);
180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochinline bool IsMoreGeneralElementsKindTransition(ElementsKind from_kind,
1823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                                ElementsKind to_kind);
183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Setter that skips the write barrier if mode is SKIP_WRITE_BARRIER.
185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockenum WriteBarrierMode { SKIP_WRITE_BARRIER, UPDATE_WRITE_BARRIER };
186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// PropertyNormalizationMode is used to specify whether to keep
189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// inobject properties when normalizing properties of a JSObject.
190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockenum PropertyNormalizationMode {
191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  CLEAR_INOBJECT_PROPERTIES,
192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  KEEP_INOBJECT_PROPERTIES
193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1960d5e116f6aee03185f237311a943491bb079a768Kristian Monsen// NormalizedMapSharingMode is used to specify whether a map may be shared
1970d5e116f6aee03185f237311a943491bb079a768Kristian Monsen// by different objects with normalized properties.
1980d5e116f6aee03185f237311a943491bb079a768Kristian Monsenenum NormalizedMapSharingMode {
1990d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  UNIQUE_NORMALIZED_MAP,
2000d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  SHARED_NORMALIZED_MAP
2010d5e116f6aee03185f237311a943491bb079a768Kristian Monsen};
2020d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
2030d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
2043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Indicates whether a get method should implicitly create the object looked up.
2053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochenum CreationFlag {
2063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ALLOW_CREATION,
2073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  OMIT_CREATION
2083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch};
2093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
211791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block// Instance size sentinel for objects of variable size.
2123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst int kVariableSizeSentinel = 0;
213791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block
214791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block
215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// All Maps have a field instance_type containing a InstanceType.
216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// It describes the type of the instances.
217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// As an example, a JavaScript object is a heap object and its map
219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// instance_type is JS_OBJECT_TYPE.
220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The names of the string instance types are intended to systematically
222e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// mirror their encoding in the instance_type field of the map.  The default
223e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// encoding is considered TWO_BYTE.  It is not mentioned in the name.  ASCII
224e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// encoding is mentioned explicitly in the name.  Likewise, the default
225e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// representation is considered sequential.  It is not mentioned in the
2263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// name.  The other representations (e.g. CONS, EXTERNAL) are explicitly
227e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// mentioned.  Finally, the string is either a SYMBOL_TYPE (if it is a
228e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// symbol) or a STRING_TYPE (if it is not a symbol).
229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// NOTE: The following things are some that depend on the string types having
231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// instance_types that are less than those of all other types:
232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// HeapObject::Size, HeapObject::IterateBody, the typeof operator, and
233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Object::IsString.
234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// NOTE: Everything following JS_VALUE_TYPE is considered a
236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// JSObject for GC purposes. The first four entries here have typeof
237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 'object', whereas JS_FUNCTION_TYPE has typeof 'function'.
238d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block#define INSTANCE_TYPE_LIST_ALL(V)                                              \
239d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  V(SYMBOL_TYPE)                                                               \
240d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  V(ASCII_SYMBOL_TYPE)                                                         \
241d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  V(CONS_SYMBOL_TYPE)                                                          \
242d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  V(CONS_ASCII_SYMBOL_TYPE)                                                    \
243d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  V(EXTERNAL_SYMBOL_TYPE)                                                      \
244756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  V(EXTERNAL_SYMBOL_WITH_ASCII_DATA_TYPE)                                      \
245d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  V(EXTERNAL_ASCII_SYMBOL_TYPE)                                                \
2463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  V(SHORT_EXTERNAL_SYMBOL_TYPE)                                                \
2473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  V(SHORT_EXTERNAL_SYMBOL_WITH_ASCII_DATA_TYPE)                                \
2483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  V(SHORT_EXTERNAL_ASCII_SYMBOL_TYPE)                                          \
249d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  V(STRING_TYPE)                                                               \
250d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  V(ASCII_STRING_TYPE)                                                         \
251d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  V(CONS_STRING_TYPE)                                                          \
252d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  V(CONS_ASCII_STRING_TYPE)                                                    \
25369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  V(SLICED_STRING_TYPE)                                                        \
254d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  V(EXTERNAL_STRING_TYPE)                                                      \
255756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  V(EXTERNAL_STRING_WITH_ASCII_DATA_TYPE)                                      \
256d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  V(EXTERNAL_ASCII_STRING_TYPE)                                                \
2573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  V(SHORT_EXTERNAL_STRING_TYPE)                                                \
2583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  V(SHORT_EXTERNAL_STRING_WITH_ASCII_DATA_TYPE)                                \
2593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  V(SHORT_EXTERNAL_ASCII_STRING_TYPE)                                          \
260d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  V(PRIVATE_EXTERNAL_ASCII_STRING_TYPE)                                        \
261d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                                                                               \
262d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  V(MAP_TYPE)                                                                  \
263d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  V(CODE_TYPE)                                                                 \
264d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  V(ODDBALL_TYPE)                                                              \
265756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  V(JS_GLOBAL_PROPERTY_CELL_TYPE)                                              \
266e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke                                                                               \
267e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  V(HEAP_NUMBER_TYPE)                                                          \
268257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  V(FOREIGN_TYPE)                                                              \
269d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  V(BYTE_ARRAY_TYPE)                                                           \
2703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  V(FREE_SPACE_TYPE)                                                           \
271d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  /* Note: the order of these external array */                                \
272d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  /* types is relied upon in */                                                \
273d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  /* Object::IsExternalArray(). */                                             \
274d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  V(EXTERNAL_BYTE_ARRAY_TYPE)                                                  \
275d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  V(EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)                                         \
276d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  V(EXTERNAL_SHORT_ARRAY_TYPE)                                                 \
277d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  V(EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)                                        \
278d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  V(EXTERNAL_INT_ARRAY_TYPE)                                                   \
279d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  V(EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)                                          \
280d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  V(EXTERNAL_FLOAT_ARRAY_TYPE)                                                 \
28144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  V(EXTERNAL_PIXEL_ARRAY_TYPE)                                                 \
282d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  V(FILLER_TYPE)                                                               \
283d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                                                                               \
284d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  V(ACCESSOR_INFO_TYPE)                                                        \
2853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  V(ACCESSOR_PAIR_TYPE)                                                        \
286d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  V(ACCESS_CHECK_INFO_TYPE)                                                    \
287d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  V(INTERCEPTOR_INFO_TYPE)                                                     \
288d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  V(CALL_HANDLER_INFO_TYPE)                                                    \
289d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  V(FUNCTION_TEMPLATE_INFO_TYPE)                                               \
290d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  V(OBJECT_TEMPLATE_INFO_TYPE)                                                 \
291d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  V(SIGNATURE_INFO_TYPE)                                                       \
292d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  V(TYPE_SWITCH_INFO_TYPE)                                                     \
293d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  V(SCRIPT_TYPE)                                                               \
2946ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  V(CODE_CACHE_TYPE)                                                           \
2953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  V(POLYMORPHIC_CODE_CACHE_TYPE)                                               \
2963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  V(TYPE_FEEDBACK_INFO_TYPE)                                                   \
2973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  V(ALIASED_ARGUMENTS_ENTRY_TYPE)                                              \
298d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                                                                               \
299756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  V(FIXED_ARRAY_TYPE)                                                          \
30069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  V(FIXED_DOUBLE_ARRAY_TYPE)                                                   \
301756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  V(SHARED_FUNCTION_INFO_TYPE)                                                 \
302756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick                                                                               \
3031e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  V(JS_MESSAGE_OBJECT_TYPE)                                                    \
3041e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block                                                                               \
305d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  V(JS_VALUE_TYPE)                                                             \
3063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  V(JS_DATE_TYPE)                                                              \
307d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  V(JS_OBJECT_TYPE)                                                            \
308d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  V(JS_CONTEXT_EXTENSION_OBJECT_TYPE)                                          \
309d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  V(JS_GLOBAL_OBJECT_TYPE)                                                     \
310d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  V(JS_BUILTINS_OBJECT_TYPE)                                                   \
311d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  V(JS_GLOBAL_PROXY_TYPE)                                                      \
312d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  V(JS_ARRAY_TYPE)                                                             \
3133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  V(JS_PROXY_TYPE)                                                             \
31469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  V(JS_WEAK_MAP_TYPE)                                                          \
315d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  V(JS_REGEXP_TYPE)                                                            \
316d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                                                                               \
317d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  V(JS_FUNCTION_TYPE)                                                          \
3183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  V(JS_FUNCTION_PROXY_TYPE)                                                    \
319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_DEBUGGER_SUPPORT
321d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block#define INSTANCE_TYPE_LIST_DEBUGGER(V)                                         \
322d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  V(DEBUG_INFO_TYPE)                                                           \
323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  V(BREAK_POINT_INFO_TYPE)
324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#else
325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define INSTANCE_TYPE_LIST_DEBUGGER(V)
326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
328d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block#define INSTANCE_TYPE_LIST(V)                                                  \
329d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  INSTANCE_TYPE_LIST_ALL(V)                                                    \
330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  INSTANCE_TYPE_LIST_DEBUGGER(V)
331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Since string types are not consecutive, this macro is used to
334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// iterate over them.
335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define STRING_TYPE_LIST(V)                                                    \
336d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  V(SYMBOL_TYPE,                                                               \
337791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block    kVariableSizeSentinel,                                                     \
338d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    symbol,                                                                    \
339d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    Symbol)                                                                    \
340d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  V(ASCII_SYMBOL_TYPE,                                                         \
341791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block    kVariableSizeSentinel,                                                     \
342d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    ascii_symbol,                                                              \
343d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    AsciiSymbol)                                                               \
344d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  V(CONS_SYMBOL_TYPE,                                                          \
345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    ConsString::kSize,                                                         \
346d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    cons_symbol,                                                               \
347d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    ConsSymbol)                                                                \
348d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  V(CONS_ASCII_SYMBOL_TYPE,                                                    \
349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    ConsString::kSize,                                                         \
350d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    cons_ascii_symbol,                                                         \
351d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    ConsAsciiSymbol)                                                           \
352d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  V(EXTERNAL_SYMBOL_TYPE,                                                      \
353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    ExternalTwoByteString::kSize,                                              \
354d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    external_symbol,                                                           \
355d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    ExternalSymbol)                                                            \
3569dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  V(EXTERNAL_SYMBOL_WITH_ASCII_DATA_TYPE,                                      \
3579dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen    ExternalTwoByteString::kSize,                                              \
3589dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen    external_symbol_with_ascii_data,                                           \
3599dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen    ExternalSymbolWithAsciiData)                                               \
360d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  V(EXTERNAL_ASCII_SYMBOL_TYPE,                                                \
361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    ExternalAsciiString::kSize,                                                \
362d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    external_ascii_symbol,                                                     \
363d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    ExternalAsciiSymbol)                                                       \
3643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  V(SHORT_EXTERNAL_SYMBOL_TYPE,                                                \
3653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    ExternalTwoByteString::kShortSize,                                         \
3663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    short_external_symbol,                                                     \
3673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    ShortExternalSymbol)                                                       \
3683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  V(SHORT_EXTERNAL_SYMBOL_WITH_ASCII_DATA_TYPE,                                \
3693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    ExternalTwoByteString::kShortSize,                                         \
3703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    short_external_symbol_with_ascii_data,                                     \
3713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    ShortExternalSymbolWithAsciiData)                                          \
3723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  V(SHORT_EXTERNAL_ASCII_SYMBOL_TYPE,                                          \
3733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    ExternalAsciiString::kShortSize,                                           \
3743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    short_external_ascii_symbol,                                               \
3753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    ShortExternalAsciiSymbol)                                                  \
376d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  V(STRING_TYPE,                                                               \
377791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block    kVariableSizeSentinel,                                                     \
378d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    string,                                                                    \
379d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    String)                                                                    \
380d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  V(ASCII_STRING_TYPE,                                                         \
381791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block    kVariableSizeSentinel,                                                     \
382d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    ascii_string,                                                              \
383d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    AsciiString)                                                               \
384d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  V(CONS_STRING_TYPE,                                                          \
385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    ConsString::kSize,                                                         \
386d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    cons_string,                                                               \
387d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    ConsString)                                                                \
388d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  V(CONS_ASCII_STRING_TYPE,                                                    \
389a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    ConsString::kSize,                                                         \
390d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    cons_ascii_string,                                                         \
391d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    ConsAsciiString)                                                           \
39269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  V(SLICED_STRING_TYPE,                                                        \
39369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    SlicedString::kSize,                                                       \
39469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    sliced_string,                                                             \
39569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    SlicedString)                                                              \
39669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  V(SLICED_ASCII_STRING_TYPE,                                                  \
39769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    SlicedString::kSize,                                                       \
39869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    sliced_ascii_string,                                                       \
39969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    SlicedAsciiString)                                                         \
400d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  V(EXTERNAL_STRING_TYPE,                                                      \
401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    ExternalTwoByteString::kSize,                                              \
402d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    external_string,                                                           \
403d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    ExternalString)                                                            \
4049dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  V(EXTERNAL_STRING_WITH_ASCII_DATA_TYPE,                                      \
4059dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen    ExternalTwoByteString::kSize,                                              \
4069dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen    external_string_with_ascii_data,                                           \
4079dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen    ExternalStringWithAsciiData)                                               \
408d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  V(EXTERNAL_ASCII_STRING_TYPE,                                                \
409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    ExternalAsciiString::kSize,                                                \
410d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    external_ascii_string,                                                     \
4113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    ExternalAsciiString)                                                       \
4123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  V(SHORT_EXTERNAL_STRING_TYPE,                                                \
4133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    ExternalTwoByteString::kShortSize,                                         \
4143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    short_external_string,                                                     \
4153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    ShortExternalString)                                                       \
4163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  V(SHORT_EXTERNAL_STRING_WITH_ASCII_DATA_TYPE,                                \
4173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    ExternalTwoByteString::kShortSize,                                         \
4183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    short_external_string_with_ascii_data,                                     \
4193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    ShortExternalStringWithAsciiData)                                          \
4203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  V(SHORT_EXTERNAL_ASCII_STRING_TYPE,                                          \
4213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    ExternalAsciiString::kShortSize,                                           \
4223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    short_external_ascii_string,                                               \
4233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    ShortExternalAsciiString)
424a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
425a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A struct is a simple object a set of object-valued fields.  Including an
426a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// object type in this causes the compiler to generate most of the boilerplate
427a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// code for the class including allocation and garbage collection routines,
428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// casts and predicates.  All you need to define is the class, methods and
429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// object verification routines.  Easy, no?
430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
431a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Note that for subtle reasons related to the ordering or numerical values of
432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// type tags, elements in this list have to be added to the INSTANCE_TYPE_LIST
433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// manually.
434d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block#define STRUCT_LIST_ALL(V)                                                     \
435d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  V(ACCESSOR_INFO, AccessorInfo, accessor_info)                                \
4363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  V(ACCESSOR_PAIR, AccessorPair, accessor_pair)                                \
437d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  V(ACCESS_CHECK_INFO, AccessCheckInfo, access_check_info)                     \
438d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  V(INTERCEPTOR_INFO, InterceptorInfo, interceptor_info)                       \
439d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  V(CALL_HANDLER_INFO, CallHandlerInfo, call_handler_info)                     \
440d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  V(FUNCTION_TEMPLATE_INFO, FunctionTemplateInfo, function_template_info)      \
441d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  V(OBJECT_TEMPLATE_INFO, ObjectTemplateInfo, object_template_info)            \
442d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  V(SIGNATURE_INFO, SignatureInfo, signature_info)                             \
443d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  V(TYPE_SWITCH_INFO, TypeSwitchInfo, type_switch_info)                        \
4446ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  V(SCRIPT, Script, script)                                                    \
4453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  V(CODE_CACHE, CodeCache, code_cache)                                         \
4463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  V(POLYMORPHIC_CODE_CACHE, PolymorphicCodeCache, polymorphic_code_cache)      \
4473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  V(TYPE_FEEDBACK_INFO, TypeFeedbackInfo, type_feedback_info)                  \
4483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  V(ALIASED_ARGUMENTS_ENTRY, AliasedArgumentsEntry, aliased_arguments_entry)
449a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
450a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_DEBUGGER_SUPPORT
451d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block#define STRUCT_LIST_DEBUGGER(V)                                                \
452d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  V(DEBUG_INFO, DebugInfo, debug_info)                                         \
453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  V(BREAK_POINT_INFO, BreakPointInfo, break_point_info)
454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#else
455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define STRUCT_LIST_DEBUGGER(V)
456a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
458d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block#define STRUCT_LIST(V)                                                         \
459d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  STRUCT_LIST_ALL(V)                                                           \
460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  STRUCT_LIST_DEBUGGER(V)
461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// We use the full 8 bits of the instance_type field to encode heap object
463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// instance types.  The high-order bit (bit 7) is set if the object is not a
464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// string, and cleared if it is a string.
465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst uint32_t kIsNotStringMask = 0x80;
466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst uint32_t kStringTag = 0x0;
467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst uint32_t kNotStringTag = 0x80;
468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
469e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// Bit 6 indicates that the object is a symbol (if set) or not (if cleared).
470e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// There are not enough types that the non-string types (with bit 7 set) can
471e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// have bit 6 set too.
472e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkeconst uint32_t kIsSymbolMask = 0x40;
473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst uint32_t kNotSymbolTag = 0x0;
474e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkeconst uint32_t kSymbolTag = 0x40;
475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// If bit 7 is clear then bit 2 indicates whether the string consists of
477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// two-byte characters or one-byte characters.
478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst uint32_t kStringEncodingMask = 0x4;
479a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst uint32_t kTwoByteStringTag = 0x0;
480a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst uint32_t kAsciiStringTag = 0x4;
481a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
482a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// If bit 7 is clear, the low-order 2 bits indicate the representation
483a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// of the string.
484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst uint32_t kStringRepresentationMask = 0x03;
485a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockenum StringRepresentationTag {
486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  kSeqStringTag = 0x0,
487a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  kConsStringTag = 0x1,
48869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  kExternalStringTag = 0x2,
48969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  kSlicedStringTag = 0x3
490a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
49169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochconst uint32_t kIsIndirectStringMask = 0x1;
49269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochconst uint32_t kIsIndirectStringTag = 0x1;
49369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen MurdochSTATIC_ASSERT((kSeqStringTag & kIsIndirectStringMask) == 0);
49469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen MurdochSTATIC_ASSERT((kExternalStringTag & kIsIndirectStringMask) == 0);
49569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen MurdochSTATIC_ASSERT(
49669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    (kConsStringTag & kIsIndirectStringMask) == kIsIndirectStringTag);
49769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen MurdochSTATIC_ASSERT(
49869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    (kSlicedStringTag & kIsIndirectStringMask) == kIsIndirectStringTag);
49969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
50069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// Use this mask to distinguish between cons and slice only after making
50169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// sure that the string is one of the two (an indirect string).
50269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochconst uint32_t kSlicedNotConsMask = kSlicedStringTag & ~kConsStringTag;
50369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen MurdochSTATIC_ASSERT(IS_POWER_OF_TWO(kSlicedNotConsMask) && kSlicedNotConsMask != 0);
504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5059dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen// If bit 7 is clear, then bit 3 indicates whether this two-byte
5063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// string actually contains ASCII data.
5079dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsenconst uint32_t kAsciiDataHintMask = 0x08;
5089dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsenconst uint32_t kAsciiDataHintTag = 0x08;
5099dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
5103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// If bit 7 is clear and string representation indicates an external string,
5113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// then bit 4 indicates whether the data pointer is cached.
5123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst uint32_t kShortExternalStringMask = 0x10;
5133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst uint32_t kShortExternalStringTag = 0x10;
5143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A ConsString with an empty string as the right side is a candidate
517a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// for being shortcut by the garbage collector unless it is a
518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// symbol. It's not common to have non-flat symbols, so we do not
519a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// shortcut them thereby avoiding turning symbols into strings. See
520a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// heap.cc and mark-compact.cc.
521a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst uint32_t kShortcutTypeMask =
522a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    kIsNotStringMask |
523a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    kIsSymbolMask |
524a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    kStringRepresentationMask;
525a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst uint32_t kShortcutTypeTag = kConsStringTag;
526a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
527a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
528a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockenum InstanceType {
529e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // String types.
5309dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  SYMBOL_TYPE = kTwoByteStringTag | kSymbolTag | kSeqStringTag,
531d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  ASCII_SYMBOL_TYPE = kAsciiStringTag | kSymbolTag | kSeqStringTag,
5329dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  CONS_SYMBOL_TYPE = kTwoByteStringTag | kSymbolTag | kConsStringTag,
533d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  CONS_ASCII_SYMBOL_TYPE = kAsciiStringTag | kSymbolTag | kConsStringTag,
5343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  SHORT_EXTERNAL_SYMBOL_TYPE = kTwoByteStringTag | kSymbolTag |
5353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                               kExternalStringTag | kShortExternalStringTag,
5363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  SHORT_EXTERNAL_SYMBOL_WITH_ASCII_DATA_TYPE =
5373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      kTwoByteStringTag | kSymbolTag | kExternalStringTag |
5383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      kAsciiDataHintTag | kShortExternalStringTag,
5393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  SHORT_EXTERNAL_ASCII_SYMBOL_TYPE = kAsciiStringTag | kExternalStringTag |
5403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                     kSymbolTag | kShortExternalStringTag,
5419dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  EXTERNAL_SYMBOL_TYPE = kTwoByteStringTag | kSymbolTag | kExternalStringTag,
5429dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  EXTERNAL_SYMBOL_WITH_ASCII_DATA_TYPE =
5439dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen      kTwoByteStringTag | kSymbolTag | kExternalStringTag | kAsciiDataHintTag,
544d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  EXTERNAL_ASCII_SYMBOL_TYPE =
545d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      kAsciiStringTag | kSymbolTag | kExternalStringTag,
5469dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  STRING_TYPE = kTwoByteStringTag | kSeqStringTag,
547d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  ASCII_STRING_TYPE = kAsciiStringTag | kSeqStringTag,
5489dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  CONS_STRING_TYPE = kTwoByteStringTag | kConsStringTag,
549d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  CONS_ASCII_STRING_TYPE = kAsciiStringTag | kConsStringTag,
55069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  SLICED_STRING_TYPE = kTwoByteStringTag | kSlicedStringTag,
55169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  SLICED_ASCII_STRING_TYPE = kAsciiStringTag | kSlicedStringTag,
5523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  SHORT_EXTERNAL_STRING_TYPE =
5533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      kTwoByteStringTag | kExternalStringTag | kShortExternalStringTag,
5543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  SHORT_EXTERNAL_STRING_WITH_ASCII_DATA_TYPE =
5553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      kTwoByteStringTag | kExternalStringTag |
5563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      kAsciiDataHintTag | kShortExternalStringTag,
5573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  SHORT_EXTERNAL_ASCII_STRING_TYPE =
5583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      kAsciiStringTag | kExternalStringTag | kShortExternalStringTag,
5599dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  EXTERNAL_STRING_TYPE = kTwoByteStringTag | kExternalStringTag,
5609dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  EXTERNAL_STRING_WITH_ASCII_DATA_TYPE =
5619dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen      kTwoByteStringTag | kExternalStringTag | kAsciiDataHintTag,
5621e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // LAST_STRING_TYPE
563d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  EXTERNAL_ASCII_STRING_TYPE = kAsciiStringTag | kExternalStringTag,
564d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  PRIVATE_EXTERNAL_ASCII_STRING_TYPE = EXTERNAL_ASCII_STRING_TYPE,
565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
566e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Objects allocated in their own spaces (never in new space).
567e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  MAP_TYPE = kNotStringTag,  // FIRST_NONSTRING_TYPE
568a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  CODE_TYPE,
569a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ODDBALL_TYPE,
570a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  JS_GLOBAL_PROPERTY_CELL_TYPE,
571e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
572e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // "Data", objects that cannot contain non-map-word pointers to heap
573e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // objects.
574e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  HEAP_NUMBER_TYPE,
575257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  FOREIGN_TYPE,
576a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  BYTE_ARRAY_TYPE,
5773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  FREE_SPACE_TYPE,
578e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  EXTERNAL_BYTE_ARRAY_TYPE,  // FIRST_EXTERNAL_ARRAY_TYPE
5793ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE,
5803ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  EXTERNAL_SHORT_ARRAY_TYPE,
5813ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE,
5823ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  EXTERNAL_INT_ARRAY_TYPE,
5833ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  EXTERNAL_UNSIGNED_INT_ARRAY_TYPE,
58444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  EXTERNAL_FLOAT_ARRAY_TYPE,
585257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  EXTERNAL_DOUBLE_ARRAY_TYPE,
58644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  EXTERNAL_PIXEL_ARRAY_TYPE,  // LAST_EXTERNAL_ARRAY_TYPE
5873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  FIXED_DOUBLE_ARRAY_TYPE,
588e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  FILLER_TYPE,  // LAST_DATA_TYPE
589a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
590e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Structs.
591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ACCESSOR_INFO_TYPE,
5923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ACCESSOR_PAIR_TYPE,
593a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ACCESS_CHECK_INFO_TYPE,
594a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  INTERCEPTOR_INFO_TYPE,
595a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  CALL_HANDLER_INFO_TYPE,
596a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  FUNCTION_TEMPLATE_INFO_TYPE,
597a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  OBJECT_TEMPLATE_INFO_TYPE,
598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  SIGNATURE_INFO_TYPE,
599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  TYPE_SWITCH_INFO_TYPE,
600e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  SCRIPT_TYPE,
6016ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CODE_CACHE_TYPE,
6023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  POLYMORPHIC_CODE_CACHE_TYPE,
6033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  TYPE_FEEDBACK_INFO_TYPE,
6043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ALIASED_ARGUMENTS_ENTRY_TYPE,
6059dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  // The following two instance types are only used when ENABLE_DEBUGGER_SUPPORT
6069dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  // is defined. However as include/v8.h contain some of the instance type
6079dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  // constants always having them avoids them getting different numbers
6089dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  // depending on whether ENABLE_DEBUGGER_SUPPORT is defined or not.
609a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DEBUG_INFO_TYPE,
610a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  BREAK_POINT_INFO_TYPE,
611a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
612e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  FIXED_ARRAY_TYPE,
613e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  SHARED_FUNCTION_INFO_TYPE,
614e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
6151e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  JS_MESSAGE_OBJECT_TYPE,
6161e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
6173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // All the following types are subtypes of JSReceiver, which corresponds to
6183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // objects in the JS sense. The first and the last type in this range are
6193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // the two forms of function. This organization enables using the same
6203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // compares for checking the JS_RECEIVER/SPEC_OBJECT range and the
6213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // NONCALLABLE_JS_OBJECT range.
6223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  JS_FUNCTION_PROXY_TYPE,  // FIRST_JS_RECEIVER_TYPE, FIRST_JS_PROXY_TYPE
6233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  JS_PROXY_TYPE,  // LAST_JS_PROXY_TYPE
6243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
6253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  JS_VALUE_TYPE,  // FIRST_JS_OBJECT_TYPE
6263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  JS_DATE_TYPE,
627a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  JS_OBJECT_TYPE,
628a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  JS_CONTEXT_EXTENSION_OBJECT_TYPE,
629a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  JS_GLOBAL_OBJECT_TYPE,
630a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  JS_BUILTINS_OBJECT_TYPE,
631a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  JS_GLOBAL_PROXY_TYPE,
632a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  JS_ARRAY_TYPE,
6333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  JS_SET_TYPE,
6343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  JS_MAP_TYPE,
63569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  JS_WEAK_MAP_TYPE,
6361e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
6373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  JS_REGEXP_TYPE,
638a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  JS_FUNCTION_TYPE,  // LAST_JS_OBJECT_TYPE, LAST_JS_RECEIVER_TYPE
640a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
641a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Pseudo-types
642a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  FIRST_TYPE = 0x0,
6433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  LAST_TYPE = JS_FUNCTION_TYPE,
644e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  INVALID_TYPE = FIRST_TYPE - 1,
645e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  FIRST_NONSTRING_TYPE = MAP_TYPE,
646e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Boundaries for testing for an external array.
647e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  FIRST_EXTERNAL_ARRAY_TYPE = EXTERNAL_BYTE_ARRAY_TYPE,
64844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  LAST_EXTERNAL_ARRAY_TYPE = EXTERNAL_PIXEL_ARRAY_TYPE,
649e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Boundary for promotion to old data space/old pointer space.
650e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  LAST_DATA_TYPE = FILLER_TYPE,
6513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Boundary for objects represented as JSReceiver (i.e. JSObject or JSProxy).
6523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Note that there is no range for JSObject or JSProxy, since their subtypes
6533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // are not continuous in this enum! The enum ranges instead reflect the
6543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // external class names, where proxies are treated as either ordinary objects,
6553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // or functions.
6563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  FIRST_JS_RECEIVER_TYPE = JS_FUNCTION_PROXY_TYPE,
6573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  LAST_JS_RECEIVER_TYPE = LAST_TYPE,
6583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Boundaries for testing the types represented as JSObject
6593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  FIRST_JS_OBJECT_TYPE = JS_VALUE_TYPE,
6603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  LAST_JS_OBJECT_TYPE = LAST_TYPE,
6613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Boundaries for testing the types represented as JSProxy
6623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  FIRST_JS_PROXY_TYPE = JS_FUNCTION_PROXY_TYPE,
6633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  LAST_JS_PROXY_TYPE = JS_PROXY_TYPE,
6643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Boundaries for testing whether the type is a JavaScript object.
6653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  FIRST_SPEC_OBJECT_TYPE = FIRST_JS_RECEIVER_TYPE,
6663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  LAST_SPEC_OBJECT_TYPE = LAST_JS_RECEIVER_TYPE,
6673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Boundaries for testing the types for which typeof is "object".
6683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  FIRST_NONCALLABLE_SPEC_OBJECT_TYPE = JS_PROXY_TYPE,
6693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  LAST_NONCALLABLE_SPEC_OBJECT_TYPE = JS_REGEXP_TYPE,
6703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Note that the types for which typeof is "function" are not continuous.
6713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Define this so that we can put assertions on discrete checks.
6723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  NUM_OF_CALLABLE_SPEC_OBJECT_TYPES = 2
673a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
674a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst int kExternalArrayTypeCount =
6763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    LAST_EXTERNAL_ARRAY_TYPE - FIRST_EXTERNAL_ARRAY_TYPE + 1;
677a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6789dcf7e2f83591d471e88bf7d230651900b8e424bKristian MonsenSTATIC_CHECK(JS_OBJECT_TYPE == Internals::kJSObjectType);
6799dcf7e2f83591d471e88bf7d230651900b8e424bKristian MonsenSTATIC_CHECK(FIRST_NONSTRING_TYPE == Internals::kFirstNonstringType);
680257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochSTATIC_CHECK(FOREIGN_TYPE == Internals::kForeignType);
6819dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
6829dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
683a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockenum CompareResult {
684a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  LESS      = -1,
685a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  EQUAL     =  0,
686a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  GREATER   =  1,
687a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
688a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  NOT_EQUAL = GREATER
689a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
690a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
691a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
692a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define DECL_BOOLEAN_ACCESSORS(name)   \
693a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline bool name();                  \
694a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void set_##name(bool value);  \
695a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
696a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
697a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define DECL_ACCESSORS(name, type)                                      \
698a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline type* name();                                                  \
699a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void set_##name(type* value,                                   \
700a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                         WriteBarrierMode mode = UPDATE_WRITE_BARRIER); \
701a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
702a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
70369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochclass DictionaryElementsAccessor;
70469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochclass ElementsAccessor;
70569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochclass FixedArrayBase;
706a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass ObjectVisitor;
70769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochclass StringStream;
7083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochclass Failure;
709a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
710a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstruct ValueInfo : public Malloced {
711a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ValueInfo() : type(FIRST_TYPE), ptr(NULL), str(NULL), number(0) { }
712a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  InstanceType type;
713a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* ptr;
714a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  const char* str;
715a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  double number;
716a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
717a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
718a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
719a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A template-ized version of the IsXXX functions.
720a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocktemplate <class C> static inline bool Is(Object* obj);
721a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
722b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
7235913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reckclass MaybeObject BASE_EMBEDDED {
7245913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck public:
7255913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  inline bool IsFailure();
7265913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  inline bool IsRetryAfterGC();
7275913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  inline bool IsOutOfMemory();
7285913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  inline bool IsException();
7295913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  INLINE(bool IsTheHole());
7305913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  inline bool ToObject(Object** obj) {
7315913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    if (IsFailure()) return false;
7325913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    *obj = reinterpret_cast<Object*>(this);
7335913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    return true;
7345913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  }
735053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block  inline Failure* ToFailureUnchecked() {
736053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block    ASSERT(IsFailure());
737053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block    return reinterpret_cast<Failure*>(this);
738053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block  }
7395913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  inline Object* ToObjectUnchecked() {
7405913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    ASSERT(!IsFailure());
7415913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    return reinterpret_cast<Object*>(this);
7425913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  }
7435913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  inline Object* ToObjectChecked() {
7445913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    CHECK(!IsFailure());
7455913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    return reinterpret_cast<Object*>(this);
7465913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  }
7475913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck
748053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block  template<typename T>
749053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block  inline bool To(T** obj) {
750053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block    if (IsFailure()) return false;
751053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block    *obj = T::cast(reinterpret_cast<Object*>(this));
752053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block    return true;
753053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block  }
754053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block
755b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef OBJECT_PRINT
7565913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  // Prints this object with details.
757b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  inline void Print() {
758b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    Print(stdout);
7593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
760b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  inline void PrintLn() {
761b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    PrintLn(stdout);
762b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
763b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void Print(FILE* out);
764b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void PrintLn(FILE* out);
765b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif
766b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef DEBUG
7675913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  // Verifies the object.
7685913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  void Verify();
7695913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck#endif
7705913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck};
771a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
772b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
773b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch#define OBJECT_TYPE_LIST(V)                    \
774b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  V(Smi)                                       \
775b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  V(HeapObject)                                \
776b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  V(Number)                                    \
777b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
778b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch#define HEAP_OBJECT_TYPE_LIST(V)               \
779b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  V(HeapNumber)                                \
780b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  V(String)                                    \
781b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  V(Symbol)                                    \
782b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  V(SeqString)                                 \
783b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  V(ExternalString)                            \
784b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  V(ConsString)                                \
78569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  V(SlicedString)                              \
786b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  V(ExternalTwoByteString)                     \
787b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  V(ExternalAsciiString)                       \
788b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  V(SeqTwoByteString)                          \
789b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  V(SeqAsciiString)                            \
790b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch                                               \
791b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  V(ExternalArray)                             \
792b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  V(ExternalByteArray)                         \
793b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  V(ExternalUnsignedByteArray)                 \
794b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  V(ExternalShortArray)                        \
795b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  V(ExternalUnsignedShortArray)                \
796b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  V(ExternalIntArray)                          \
797b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  V(ExternalUnsignedIntArray)                  \
798b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  V(ExternalFloatArray)                        \
799257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  V(ExternalDoubleArray)                       \
80044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  V(ExternalPixelArray)                        \
801b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  V(ByteArray)                                 \
8023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  V(FreeSpace)                                 \
8033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  V(JSReceiver)                                \
804b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  V(JSObject)                                  \
805b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  V(JSContextExtensionObject)                  \
806b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  V(Map)                                       \
807b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  V(DescriptorArray)                           \
808b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  V(DeoptimizationInputData)                   \
809b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  V(DeoptimizationOutputData)                  \
8103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  V(TypeFeedbackCells)                         \
811b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  V(FixedArray)                                \
8123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  V(FixedDoubleArray)                          \
813b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  V(Context)                                   \
814b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  V(GlobalContext)                             \
8153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  V(ScopeInfo)                                 \
816b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  V(JSFunction)                                \
817b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  V(Code)                                      \
818b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  V(Oddball)                                   \
819b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  V(SharedFunctionInfo)                        \
820b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  V(JSValue)                                   \
8213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  V(JSDate)                                    \
8221e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  V(JSMessageObject)                           \
823b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  V(StringWrapper)                             \
824257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  V(Foreign)                                   \
825b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  V(Boolean)                                   \
826b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  V(JSArray)                                   \
827257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  V(JSProxy)                                   \
8283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  V(JSFunctionProxy)                           \
8293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  V(JSSet)                                     \
8303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  V(JSMap)                                     \
83169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  V(JSWeakMap)                                 \
832b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  V(JSRegExp)                                  \
833b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  V(HashTable)                                 \
834b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  V(Dictionary)                                \
835b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  V(SymbolTable)                               \
836b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  V(JSFunctionResultCache)                     \
837b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  V(NormalizedMapCache)                        \
838b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  V(CompilationCacheTable)                     \
839b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  V(CodeCacheHashTable)                        \
8403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  V(PolymorphicCodeCacheHashTable)             \
841b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  V(MapCache)                                  \
842b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  V(Primitive)                                 \
843b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  V(GlobalObject)                              \
844b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  V(JSGlobalObject)                            \
845b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  V(JSBuiltinsObject)                          \
846b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  V(JSGlobalProxy)                             \
847b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  V(UndetectableObject)                        \
848b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  V(AccessCheckNeeded)                         \
849b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  V(JSGlobalPropertyCell)                      \
850b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
8513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
8523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochclass JSReceiver;
8533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
854a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Object is the abstract superclass for all classes in the
855a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// object hierarchy.
856a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Object does not use any virtual functions to avoid the
857a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// allocation of the C++ vtable.
858a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Since Smi and Failure are subclasses of Object no
859a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// data members can be present in Object.
8605913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reckclass Object : public MaybeObject {
861a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
862a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Type testing.
8633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool IsObject() { return true; }
8643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
865b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch#define IS_TYPE_FUNCTION_DECL(type_)  inline bool Is##type_();
866b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  OBJECT_TYPE_LIST(IS_TYPE_FUNCTION_DECL)
867b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  HEAP_OBJECT_TYPE_LIST(IS_TYPE_FUNCTION_DECL)
868b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch#undef IS_TYPE_FUNCTION_DECL
869a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline bool IsFixedArrayBase();
8713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
872a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Returns true if this object is an instance of the specified
873a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // function template.
874a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline bool IsInstanceOf(FunctionTemplateInfo* type);
875a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
876a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline bool IsStruct();
877a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define DECLARE_STRUCT_PREDICATE(NAME, Name, name) inline bool Is##Name();
878a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  STRUCT_LIST(DECLARE_STRUCT_PREDICATE)
879a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#undef DECLARE_STRUCT_PREDICATE
880a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
88169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  INLINE(bool IsSpecObject());
8823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  INLINE(bool IsSpecFunction());
88369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
884a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Oddball testing.
885a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  INLINE(bool IsUndefined());
886a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  INLINE(bool IsNull());
88744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  INLINE(bool IsTheHole());  // Shadows MaybeObject's implementation.
888a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  INLINE(bool IsTrue());
889a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  INLINE(bool IsFalse());
890086aeeaae12517475c22695a200be45495516549Ben Murdoch  inline bool IsArgumentsMarker();
8913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline bool NonFailureIsHeapObject();
8923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
8933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Filler objects (fillers and free space objects).
8943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline bool IsFiller();
895a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
896a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Extract the number.
897a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline double Number();
8983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline bool IsNaN();
899a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
9003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Returns true if the object is of the correct type to be used as a
9013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // implementation of a JSObject's elements.
9023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  inline bool HasValidElements();
9033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
904a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline bool HasSpecificClassOf(String* name);
905a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
9065913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* ToObject();             // ECMA-262 9.9.
9075913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  Object* ToBoolean();                                 // ECMA-262 9.2.
908a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
909a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Convert to a JSObject if needed.
910a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // global_context is used when creating wrapper object.
9115913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* ToObject(Context* global_context);
912a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
913a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Converts this to a Smi if possible.
914a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Failure is returned otherwise.
9155913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT inline MaybeObject* ToSmi();
916a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
917a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Lookup(String* name, LookupResult* result);
918a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
919a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Property access.
9205913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT inline MaybeObject* GetProperty(String* key);
9215913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT inline MaybeObject* GetProperty(
9225913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      String* key,
9235913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      PropertyAttributes* attributes);
9245913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* GetPropertyWithReceiver(
9255913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      Object* receiver,
9265913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      String* key,
9275913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      PropertyAttributes* attributes);
9283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
9293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static Handle<Object> GetProperty(Handle<Object> object,
9303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                    Handle<Object> receiver,
9313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                    LookupResult* result,
9323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                    Handle<String> key,
9333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                    PropertyAttributes* attributes);
9343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
9355913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* GetProperty(Object* receiver,
9365913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck                                           LookupResult* result,
9375913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck                                           String* key,
9385913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck                                           PropertyAttributes* attributes);
9393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
9405913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* GetPropertyWithDefinedGetter(Object* receiver,
9413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                                            JSReceiver* getter);
9425913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck
9433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static Handle<Object> GetElement(Handle<Object> object, uint32_t index);
9443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT inline MaybeObject* GetElement(uint32_t index);
9455913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  // For use when we know that no exception can be thrown.
9465913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  inline Object* GetElementNoExceptionThrown(uint32_t index);
9473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT MaybeObject* GetElementWithReceiver(Object* receiver,
9483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                                      uint32_t index);
949a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
950a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Return the object's prototype (might be Heap::null_value()).
951a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* GetPrototype();
952a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
9533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Returns the permanent hash code associated with this object depending on
9543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // the actual object type.  Might return a failure in case no hash was
9553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // created yet or GC was caused by creation.
9563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT MaybeObject* GetHash(CreationFlag flag);
9573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
9583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Checks whether this object has the same value as the given one.  This
9593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // function is implemented according to ES5, section 9.12 and can be used
9603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // to implement the Harmony "egal" function.
9613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool SameValue(Object* other);
9623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
9637f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // Tries to convert an object to an array index.  Returns true and sets
9647f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // the output parameter if it succeeds.
9657f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  inline bool ToArrayIndex(uint32_t* index);
9667f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
967a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Returns true if this is a JSValue containing a string and the index is
968a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // < the length of the string.  Used to implement [] on strings.
969a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline bool IsStringObjectWithCharacterAt(uint32_t index);
970a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
971a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG
972a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Verify a pointer is a valid object pointer.
973a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static void VerifyPointer(Object* p);
974a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
975a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
976a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Prints this object without details.
977b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  inline void ShortPrint() {
978b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    ShortPrint(stdout);
979b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
980b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void ShortPrint(FILE* out);
981a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
982a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Prints this object without details to a message accumulator.
983a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void ShortPrint(StringStream* accumulator);
984a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
985a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Casting: This cast is only needed to satisfy macros in objects-inl.h.
986a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static Object* cast(Object* value) { return value; }
987a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
988a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Layout description.
989a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kHeaderSize = 0;  // Object does not take up any space.
990a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
991a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
992a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DISALLOW_IMPLICIT_CONSTRUCTORS(Object);
993a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
994a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
995a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
996a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Smi represents integer Numbers that can be stored in 31 bits.
997a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Smis are immediate which means they are NOT allocated in the heap.
998a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The this pointer has the following format: [31 bit signed int] 0
9993ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// For long smis it has the following format:
10003ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block//     [32 bit signed int] [31 bits zero padding] 0
10013ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// Smi stands for small integer.
1002a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass Smi: public Object {
1003a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
1004a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Returns the integer value.
1005a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline int value();
1006a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1007a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Convert a value to a Smi object.
1008a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline Smi* FromInt(int value);
1009a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1010a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline Smi* FromIntptr(intptr_t value);
1011a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1012a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Returns whether value can be represented in a Smi.
1013a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline bool IsValid(intptr_t value);
1014a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1015a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Casting.
1016a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline Smi* cast(Object* object);
1017a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1018a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Dispatched behavior.
1019b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  inline void SmiPrint() {
1020b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    SmiPrint(stdout);
1021b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
1022b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void SmiPrint(FILE* out);
1023a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void SmiPrint(StringStream* accumulator);
1024a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG
1025a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void SmiVerify();
1026a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
1027a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
10283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kMinValue =
10293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      (static_cast<unsigned int>(-1)) << (kSmiValueSize - 1);
10303ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  static const int kMaxValue = -(kMinValue + 1);
1031a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1032a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
1033a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DISALLOW_IMPLICIT_CONSTRUCTORS(Smi);
1034a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
1035a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1036a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1037a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Failure is used for reporting out of memory situations and
1038a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// propagating exceptions through the runtime system.  Failure objects
1039a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// are transient and cannot occur as part of the object graph.
1040a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
1041a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Failures are a single word, encoded as follows:
1042a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// +-------------------------+---+--+--+
1043f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch// |.........unused..........|sss|tt|11|
1044a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// +-------------------------+---+--+--+
10453ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block//                          7 6 4 32 10
10463ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block//
1047a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
1048a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The low two bits, 0-1, are the failure tag, 11.  The next two bits,
1049a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 2-3, are a failure type tag 'tt' with possible values:
1050a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//   00 RETRY_AFTER_GC
1051a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//   01 EXCEPTION
1052a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//   10 INTERNAL_ERROR
1053a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//   11 OUT_OF_MEMORY_EXCEPTION
1054a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
1055a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The next three bits, 4-6, are an allocation space tag 'sss'.  The
1056a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// allocation space tag is 000 for all failure types except
1057a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// RETRY_AFTER_GC.  For RETRY_AFTER_GC, the possible values are the
1058a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// allocation spaces (the encoding is found in globals.h).
1059a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1060a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Failure type tag info.
1061a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst int kFailureTypeTagSize = 2;
1062a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst int kFailureTypeTagMask = (1 << kFailureTypeTagSize) - 1;
1063a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
10645913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reckclass Failure: public MaybeObject {
1065a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
1066a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // RuntimeStubs assumes EXCEPTION = 1 in the compiler-generated code.
1067a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  enum Type {
1068a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    RETRY_AFTER_GC = 0,
1069a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    EXCEPTION = 1,       // Returning this marker tells the real exception
107044f0eee88ff00398ff7f715fab053374d808c90dSteve Block                         // is in Isolate::pending_exception.
1071a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    INTERNAL_ERROR = 2,
1072a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    OUT_OF_MEMORY_EXCEPTION = 3
1073a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  };
1074a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1075a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline Type type() const;
1076a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1077a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Returns the space that needs to be collected for RetryAfterGC failures.
1078a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline AllocationSpace allocation_space() const;
1079a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1080a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline bool IsInternalError() const;
1081a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline bool IsOutOfMemoryException() const;
1082a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1083f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  static inline Failure* RetryAfterGC(AllocationSpace space);
1084f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  static inline Failure* RetryAfterGC();  // NEW_SPACE
1085a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline Failure* Exception();
1086a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline Failure* InternalError();
1087a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline Failure* OutOfMemoryException();
1088a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Casting.
10895913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  static inline Failure* cast(MaybeObject* object);
1090a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1091a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Dispatched behavior.
1092b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  inline void FailurePrint() {
1093b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    FailurePrint(stdout);
1094b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
1095b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void FailurePrint(FILE* out);
1096a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void FailurePrint(StringStream* accumulator);
1097a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG
1098a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void FailureVerify();
1099a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
1100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
11023ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  inline intptr_t value() const;
11033ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  static inline Failure* Construct(Type type, intptr_t value = 0);
1104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DISALLOW_IMPLICIT_CONSTRUCTORS(Failure);
1106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
1107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Heap objects typically have a map pointer in their first word.  However,
11103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// during GC other data (e.g. mark bits, forwarding addresses) is sometimes
1111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// encoded in the first word.  The class MapWord is an abstraction of the
1112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// value in a heap object's first word.
1113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass MapWord BASE_EMBEDDED {
1114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
1115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Normal state: the map word contains a map pointer.
1116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Create a map word from a map pointer.
1118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline MapWord FromMap(Map* map);
1119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // View this map word as a map pointer.
1121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline Map* ToMap();
1122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Scavenge collection: the map word of live objects in the from space
1125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // contains a forwarding address (a heap object pointer in the to space).
1126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // True if this map word is a forwarding address for a scavenge
1128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // collection.  Only valid during a scavenge collection (specifically,
11293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // when all map words are heap object pointers, i.e. not during a full GC).
1130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline bool IsForwardingAddress();
1131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Create a map word from a forwarding address.
1133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline MapWord FromForwardingAddress(HeapObject* object);
1134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // View this map word as a forwarding address.
1136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline HeapObject* ToForwardingAddress();
1137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
11383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static inline MapWord FromRawValue(uintptr_t value) {
11393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return MapWord(value);
11403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
114185b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
11423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline uintptr_t ToRawValue() {
11433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return value_;
11443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
1145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
1147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // HeapObject calls the private constructor and directly reads the value.
1148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  friend class HeapObject;
1149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  explicit MapWord(uintptr_t value) : value_(value) {}
1151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  uintptr_t value_;
1153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
1154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// HeapObject is the superclass for all classes describing heap allocated
1157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// objects.
1158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass HeapObject: public Object {
1159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
1160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // [map]: Contains a map which contains the object's reflective
1161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // information.
1162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline Map* map();
1163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void set_map(Map* value);
11643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // The no-write-barrier version.  This is OK if the object is white and in
11653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // new space, or if the value is an immortal immutable object, like the maps
11663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // of primitive (non-JS) objects like strings, heap numbers etc.
11673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline void set_map_no_write_barrier(Map* value);
1168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // During garbage collection, the map word of a heap object does not
1170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // necessarily contain a map pointer.
1171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline MapWord map_word();
1172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void set_map_word(MapWord map_word);
1173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
117444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // The Heap the object was allocated in. Used also to access Isolate.
117544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  inline Heap* GetHeap();
11763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
117744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Convenience method to get current isolate. This method can be
117844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // accessed only when its result is the same as
117944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Isolate::Current(), it ASSERTs this. See also comment for GetHeap.
118044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  inline Isolate* GetIsolate();
118144f0eee88ff00398ff7f715fab053374d808c90dSteve Block
1182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Converts an address to a HeapObject pointer.
1183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline HeapObject* FromAddress(Address address);
1184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Returns the address of this HeapObject.
1186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline Address address();
1187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Iterates over pointers contained in the object (including the Map)
1189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Iterate(ObjectVisitor* v);
1190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Iterates over all pointers contained in the object except the
1192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // first map pointer.  The object type is given in the first
1193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // parameter. This function does not access the map pointer in the
1194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // object, and so is safe to call while the map pointer is modified.
1195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void IterateBody(InstanceType type, int object_size, ObjectVisitor* v);
1196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Returns the heap object's size in bytes
1198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline int Size();
1199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Given a heap object's map pointer, returns the heap size in bytes
1201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Useful when the map pointer field is used for other purposes.
1202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // GC internal.
1203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline int SizeFromMap(Map* map);
1204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Returns the field at offset in obj, as a read/write Object* reference.
1206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Does no checking, and is safe to use during GC, while maps are invalid.
12077f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // Does not invoke write barrier, so should only be assigned to
1208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // during marking GC.
1209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline Object** RawField(HeapObject* obj, int offset);
1210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Casting.
1212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline HeapObject* cast(Object* obj);
1213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
12144515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  // Return the write barrier mode for this. Callers of this function
12154515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  // must be able to present a reference to an AssertNoAllocation
12164515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  // object as a sign that they are not going to use this function
12174515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  // from code that allocates and thus invalidates the returned write
12184515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  // barrier mode.
12194515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  inline WriteBarrierMode GetWriteBarrierMode(const AssertNoAllocation&);
1220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Dispatched behavior.
1222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void HeapObjectShortPrint(StringStream* accumulator);
1223b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef OBJECT_PRINT
1224b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  inline void HeapObjectPrint() {
1225b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    HeapObjectPrint(stdout);
1226b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
1227b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void HeapObjectPrint(FILE* out);
12283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void PrintHeader(FILE* out, const char* id);
1229b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif
12303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG
1232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void HeapObjectVerify();
1233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void VerifyObjectField(int offset);
12347f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  inline void VerifySmiField(int offset);
123585b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
1236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Verify a pointer is a valid HeapObject pointer that points to object
1237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // areas in the heap.
1238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static void VerifyHeapPointer(Object* p);
1239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
1240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Layout description.
1242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // First field in a heap object is map.
1243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kMapOffset = Object::kHeaderSize;
1244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kHeaderSize = kMapOffset + kPointerSize;
1245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  STATIC_CHECK(kMapOffset == Internals::kHeapObjectMapOffset);
1247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block protected:
1249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // helpers for calling an ObjectVisitor to iterate over pointers in the
1250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // half-open range [start, end) specified as integer offsets
1251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void IteratePointers(ObjectVisitor* v, int start, int end);
1252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // as above, for the single element at "offset"
1253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void IteratePointer(ObjectVisitor* v, int offset);
1254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
1256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DISALLOW_IMPLICIT_CONSTRUCTORS(HeapObject);
1257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
1258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1260756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick#define SLOT_ADDR(obj, offset) \
1261756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  reinterpret_cast<Object**>((obj)->address() + offset)
1262756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
1263756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick// This class describes a body of an object of a fixed size
1264756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick// in which all pointer fields are located in the [start_offset, end_offset)
1265756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick// interval.
1266756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merricktemplate<int start_offset, int end_offset, int size>
1267756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrickclass FixedBodyDescriptor {
1268756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick public:
1269756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  static const int kStartOffset = start_offset;
1270756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  static const int kEndOffset = end_offset;
1271756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  static const int kSize = size;
1272756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
1273756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  static inline void IterateBody(HeapObject* obj, ObjectVisitor* v);
1274756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
1275756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  template<typename StaticVisitor>
1276756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  static inline void IterateBody(HeapObject* obj) {
1277756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick    StaticVisitor::VisitPointers(SLOT_ADDR(obj, start_offset),
1278756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick                                 SLOT_ADDR(obj, end_offset));
1279756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  }
1280756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick};
1281756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
1282756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
1283756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick// This class describes a body of an object of a variable size
1284756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick// in which all pointer fields are located in the [start_offset, object_size)
1285756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick// interval.
1286756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merricktemplate<int start_offset>
1287756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrickclass FlexibleBodyDescriptor {
1288756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick public:
1289756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  static const int kStartOffset = start_offset;
1290756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
1291756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  static inline void IterateBody(HeapObject* obj,
1292756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick                                 int object_size,
1293756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick                                 ObjectVisitor* v);
1294756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
1295756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  template<typename StaticVisitor>
1296756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  static inline void IterateBody(HeapObject* obj, int object_size) {
1297756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick    StaticVisitor::VisitPointers(SLOT_ADDR(obj, start_offset),
1298756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick                                 SLOT_ADDR(obj, object_size));
1299756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  }
1300756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick};
1301756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
1302756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick#undef SLOT_ADDR
1303756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
1304756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
1305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The HeapNumber class describes heap allocated numbers that cannot be
1306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// represented in a Smi (small integer)
1307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass HeapNumber: public HeapObject {
1308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
1309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // [value]: number value.
1310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline double value();
1311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void set_value(double value);
1312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Casting.
1314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline HeapNumber* cast(Object* obj);
1315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Dispatched behavior.
1317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* HeapNumberToBoolean();
1318b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  inline void HeapNumberPrint() {
1319b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    HeapNumberPrint(stdout);
1320b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
1321b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void HeapNumberPrint(FILE* out);
1322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void HeapNumberPrint(StringStream* accumulator);
1323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG
1324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void HeapNumberVerify();
1325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
1326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
13276ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  inline int get_exponent();
13286ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  inline int get_sign();
13296ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
1330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Layout description.
1331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kValueOffset = HeapObject::kHeaderSize;
1332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // IEEE doubles are two 32 bit words.  The first is just mantissa, the second
1333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // is a mixture of sign, exponent and mantissa.  Our current platforms are all
1334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // little endian apart from non-EABI arm which is little endian with big
1335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // endian floating point word ordering!
1336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kMantissaOffset = kValueOffset;
1337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kExponentOffset = kValueOffset + 4;
13388b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
1339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kSize = kValueOffset + kDoubleSize;
1340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const uint32_t kSignMask = 0x80000000u;
1341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const uint32_t kExponentMask = 0x7ff00000u;
1342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const uint32_t kMantissaMask = 0xfffffu;
13436ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static const int kMantissaBits = 52;
13449dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  static const int kExponentBits = 11;
1345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kExponentBias = 1023;
1346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kExponentShift = 20;
1347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kMantissaBitsInTopWord = 20;
1348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kNonMantissaBitsInTopWord = 12;
1349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
1351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DISALLOW_IMPLICIT_CONSTRUCTORS(HeapNumber);
1352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
1353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
13553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochenum EnsureElementsMode {
13563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  DONT_ALLOW_DOUBLE_ELEMENTS,
13573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ALLOW_COPIED_DOUBLE_ELEMENTS,
13583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ALLOW_CONVERTED_DOUBLE_ELEMENTS
13593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch};
13603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
13613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
13623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Indicates whether a property should be set or (re)defined.  Setting of a
13633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// property causes attributes to remain unchanged, writability to be checked
13643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// and callbacks to be called.  Defining of a property causes attributes to
13653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// be updated and callbacks to be overridden.
13663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochenum SetPropertyMode {
13673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  SET_PROPERTY,
13683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  DEFINE_PROPERTY
13693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch};
13703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
13713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
13723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Indicator for one component of an AccessorPair.
13733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochenum AccessorComponent {
13743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ACCESSOR_GETTER,
13753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ACCESSOR_SETTER
13763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch};
13773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
13783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
13793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// JSReceiver includes types on which properties can be defined, i.e.,
13803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// JSObject and JSProxy.
13813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochclass JSReceiver: public HeapObject {
1382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
1383e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  enum DeleteMode {
1384e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    NORMAL_DELETION,
1385e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    STRICT_DELETION,
1386e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    FORCE_DELETION
1387e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  };
1388e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
13893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Casting.
13903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  static inline JSReceiver* cast(Object* obj);
13913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
13923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static Handle<Object> SetProperty(Handle<JSReceiver> object,
13933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                    Handle<String> key,
13943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                    Handle<Object> value,
13953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                    PropertyAttributes attributes,
13963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                    StrictModeFlag strict_mode);
13973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Can cause GC.
13983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  MUST_USE_RESULT MaybeObject* SetProperty(String* key,
13993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                           Object* value,
14003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                           PropertyAttributes attributes,
14013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                           StrictModeFlag strict_mode);
14023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  MUST_USE_RESULT MaybeObject* SetProperty(LookupResult* result,
14033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                           String* key,
14043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                           Object* value,
14053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                           PropertyAttributes attributes,
14063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                           StrictModeFlag strict_mode);
14073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT MaybeObject* SetPropertyWithDefinedSetter(JSReceiver* setter,
14083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                                            Object* value);
14093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
14103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  MUST_USE_RESULT MaybeObject* DeleteProperty(String* name, DeleteMode mode);
14113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT MaybeObject* DeleteElement(uint32_t index, DeleteMode mode);
14123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
14133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Set the index'th array element.
14143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Can cause GC, or return failure if GC is required.
14153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT MaybeObject* SetElement(uint32_t index,
14163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                          Object* value,
14173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                          PropertyAttributes attributes,
14183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                          StrictModeFlag strict_mode,
14193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                          bool check_prototype);
14203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
14213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Tests for the fast common case for property enumeration.
14223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool IsSimpleEnum();
14233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
14243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Returns the class name ([[Class]] property in the specification).
14253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  String* class_name();
14263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
14273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Returns the constructor name (the name (possibly, inferred name) of the
14283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // function that was used to instantiate the object).
14293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  String* constructor_name();
14303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
14313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  inline PropertyAttributes GetPropertyAttribute(String* name);
14323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  PropertyAttributes GetPropertyAttributeWithReceiver(JSReceiver* receiver,
14333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                                      String* name);
14343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  PropertyAttributes GetLocalPropertyAttribute(String* name);
14353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
14363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Can cause a GC.
14373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  inline bool HasProperty(String* name);
14383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  inline bool HasLocalProperty(String* name);
14393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline bool HasElement(uint32_t index);
14403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
14413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Return the object's prototype (might be Heap::null_value()).
14423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  inline Object* GetPrototype();
14433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
14443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Set the object's prototype (only JSReceiver and null are allowed).
14453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  MUST_USE_RESULT MaybeObject* SetPrototype(Object* value,
14463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                            bool skip_hidden_prototypes);
14473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
14483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Retrieves a permanent object identity hash code. The undefined value might
14493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // be returned in case no hash was created yet and OMIT_CREATION was used.
14503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline MUST_USE_RESULT MaybeObject* GetIdentityHash(CreationFlag flag);
14513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
14523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Lookup a property.  If found, the result is valid and has
14533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // detailed information.
14543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  void LocalLookup(String* name, LookupResult* result);
14553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  void Lookup(String* name, LookupResult* result);
14563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
14573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch protected:
14583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Smi* GenerateIdentityHash();
14593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
14603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch private:
14613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  PropertyAttributes GetPropertyAttribute(JSReceiver* receiver,
14623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                          LookupResult* result,
14633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                          String* name,
14643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                          bool continue_search);
14653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
14663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  DISALLOW_IMPLICIT_CONSTRUCTORS(JSReceiver);
14673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch};
14683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
14693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// The JSObject describes real heap allocated JavaScript objects with
14703fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// properties.
14713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// Note that the map of JSObject changes during execution to enable inline
14723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// caching.
14733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochclass JSObject: public JSReceiver {
14743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch public:
1475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // [properties]: Backing storage for properties.
14767f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // properties is a FixedArray in the fast case and a Dictionary in the
1477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // slow case.
1478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(properties, FixedArray)  // Get and set fast properties.
1479a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void initialize_properties();
1480a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline bool HasFastProperties();
1481a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline StringDictionary* property_dictionary();  // Gets slow properties.
1482a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1483a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // [elements]: The elements (properties with names that are integers).
1484756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  //
1485756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  // Elements can be in two general modes: fast and slow. Each mode
1486756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  // corrensponds to a set of object representations of elements that
1487756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  // have something in common.
1488756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  //
1489756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  // In the fast mode elements is a FixedArray and so each element can
1490756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  // be quickly accessed. This fact is used in the generated code. The
14913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // elements array can have one of three maps in this mode:
14923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // fixed_array_map, non_strict_arguments_elements_map or
14933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // fixed_cow_array_map (for copy-on-write arrays). In the latter case
14943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // the elements array may be shared by a few objects and so before
14953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // writing to any element the array must be copied. Use
14963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // EnsureWritableFastElements in this case.
1497756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  //
14983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // In the slow mode the elements is either a NumberDictionary, an
14993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // ExternalArray, or a FixedArray parameter map for a (non-strict)
15003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // arguments object.
150169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  DECL_ACCESSORS(elements, FixedArrayBase)
1502a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void initialize_elements();
15035913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT inline MaybeObject* ResetElements();
1504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline ElementsKind GetElementsKind();
150569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  inline ElementsAccessor* GetElementsAccessor();
15063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline bool HasFastSmiOnlyElements();
1507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline bool HasFastElements();
15083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Returns if an object has either FAST_ELEMENT or FAST_SMI_ONLY_ELEMENT
15093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // elements.  TODO(danno): Rename HasFastTypeElements to HasFastElements() and
15103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // HasFastElements to HasFastObjectElements.
15113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline bool HasFastTypeElements();
15123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  inline bool HasFastDoubleElements();
15133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline bool HasNonStrictArgumentsElements();
1514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline bool HasDictionaryElements();
151544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  inline bool HasExternalPixelElements();
15163ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  inline bool HasExternalArrayElements();
15173ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  inline bool HasExternalByteElements();
15183ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  inline bool HasExternalUnsignedByteElements();
15193ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  inline bool HasExternalShortElements();
15203ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  inline bool HasExternalUnsignedShortElements();
15213ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  inline bool HasExternalIntElements();
15223ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  inline bool HasExternalUnsignedIntElements();
15233ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  inline bool HasExternalFloatElements();
1524257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  inline bool HasExternalDoubleElements();
15253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  bool HasFastArgumentsElements();
15263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  bool HasDictionaryArgumentsElements();
1527c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch  inline SeededNumberDictionary* element_dictionary();  // Gets slow elements.
1528c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch
15293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline void set_map_and_elements(
15303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Map* map,
15313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      FixedArrayBase* value,
15323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
15333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
15343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Requires: HasFastElements().
15355913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT inline MaybeObject* EnsureWritableFastElements();
1536a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1537a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Collects elements starting at index 0.
1538a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Undefined values are placed after non-undefined values.
1539a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Returns the number of non-undefined values.
15405913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* PrepareElementsForSort(uint32_t limit);
1541a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // As PrepareElementsForSort, but only on objects where elements is
1542a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // a dictionary, and it will stay a dictionary.
15435913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* PrepareSlowElementsForSort(uint32_t limit);
15445913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck
15453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT MaybeObject* GetPropertyWithCallback(Object* receiver,
15463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                                       Object* structure,
15473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                                       String* name);
15483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
15493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Can cause GC.
15503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  MUST_USE_RESULT MaybeObject* SetPropertyForResult(LookupResult* result,
15515913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck                                           String* key,
15525913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck                                           Object* value,
1553e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch                                           PropertyAttributes attributes,
1554e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch                                           StrictModeFlag strict_mode);
15555913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* SetPropertyWithFailedAccessCheck(
15565913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      LookupResult* result,
15575913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      String* name,
1558086aeeaae12517475c22695a200be45495516549Ben Murdoch      Object* value,
15593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      bool check_prototype,
15603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      StrictModeFlag strict_mode);
15613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  MUST_USE_RESULT MaybeObject* SetPropertyWithCallback(
15623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      Object* structure,
15633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      String* name,
15643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      Object* value,
15653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      JSObject* holder,
15663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      StrictModeFlag strict_mode);
15675913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* SetPropertyWithInterceptor(
15685913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      String* name,
15695913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      Object* value,
1570e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      PropertyAttributes attributes,
1571e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      StrictModeFlag strict_mode);
15725913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* SetPropertyPostInterceptor(
15735913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      String* name,
15745913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      Object* value,
1575e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      PropertyAttributes attributes,
1576e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      StrictModeFlag strict_mode);
15773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
15783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static Handle<Object> SetLocalPropertyIgnoreAttributes(
15793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Handle<JSObject> object,
15803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Handle<String> key,
15813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Handle<Object> value,
15823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      PropertyAttributes attributes);
15833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
15843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Can cause GC.
1585086aeeaae12517475c22695a200be45495516549Ben Murdoch  MUST_USE_RESULT MaybeObject* SetLocalPropertyIgnoreAttributes(
15865913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      String* key,
15875913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      Object* value,
15885913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      PropertyAttributes attributes);
1589a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1590a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Retrieve a value in a normalized object given a lookup result.
1591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Handles the special representation of JS global objects.
1592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* GetNormalizedProperty(LookupResult* result);
1593a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1594a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Sets the property value in a normalized object given a lookup result.
1595a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Handles the special representation of JS global objects.
1596a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* SetNormalizedProperty(LookupResult* result, Object* value);
1597a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Sets the property value in a normalized object given (key, value, details).
1599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Handles the special representation of JS global objects.
16003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static Handle<Object> SetNormalizedProperty(Handle<JSObject> object,
16013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                              Handle<String> key,
16023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                              Handle<Object> value,
16033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                              PropertyDetails details);
16043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
16055913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* SetNormalizedProperty(String* name,
16065913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck                                                     Object* value,
16075913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck                                                     PropertyDetails details);
1608a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1609a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Deletes the named property in a normalized object.
16105913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* DeleteNormalizedProperty(String* name,
16115913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck                                                        DeleteMode mode);
1612a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1613a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Retrieve interceptors.
1614a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  InterceptorInfo* GetNamedInterceptor();
1615a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  InterceptorInfo* GetIndexedInterceptor();
1616a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
16173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Used from JSReceiver.
16183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  PropertyAttributes GetPropertyAttributePostInterceptor(JSObject* receiver,
16193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                                         String* name,
16203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                                         bool continue_search);
16213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  PropertyAttributes GetPropertyAttributeWithInterceptor(JSObject* receiver,
16223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                                         String* name,
16233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                                         bool continue_search);
16243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  PropertyAttributes GetPropertyAttributeWithFailedAccessCheck(
16253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      Object* receiver,
16263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      LookupResult* result,
16273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      String* name,
16283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      bool continue_search);
1629a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
16303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static void DefineAccessor(Handle<JSObject> object,
16313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                             Handle<String> name,
16323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                             Handle<Object> getter,
16333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                             Handle<Object> setter,
16343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                             PropertyAttributes attributes);
16355913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* DefineAccessor(String* name,
16363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                              Object* getter,
16373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                              Object* setter,
16385913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck                                              PropertyAttributes attributes);
16393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Object* LookupAccessor(String* name, AccessorComponent component);
1640a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
16415913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* DefineAccessor(AccessorInfo* info);
1642f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
1643a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Used from Object::GetProperty().
16443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT MaybeObject* GetPropertyWithFailedAccessCheck(
16455913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      Object* receiver,
16465913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      LookupResult* result,
16475913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      String* name,
16485913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      PropertyAttributes* attributes);
16493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT MaybeObject* GetPropertyWithInterceptor(
16505d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch      JSReceiver* receiver,
16515d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch      String* name,
16525d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch      PropertyAttributes* attributes);
16533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT MaybeObject* GetPropertyPostInterceptor(
16543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      JSReceiver* receiver,
16553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      String* name,
16563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      PropertyAttributes* attributes);
16573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT MaybeObject* GetLocalPropertyPostInterceptor(
16583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      JSReceiver* receiver,
16595913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      String* name,
16605913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      PropertyAttributes* attributes);
1661a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1662a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Returns true if this is an instance of an api function and has
1663a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // been modified since it was created.  May give false positives.
1664a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool IsDirty();
1665a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1666d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // If the receiver is a JSGlobalProxy this method will return its prototype,
1667d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // otherwise the result is the receiver itself.
1668d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  inline Object* BypassGlobalProxy();
1669d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
1670d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // Accessors for hidden properties object.
1671d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  //
1672d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // Hidden properties are not local properties of the object itself.
16733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Instead they are stored in an auxiliary structure kept as a local
1674d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // property with a special name Heap::hidden_symbol(). But if the
1675d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // receiver is a JSGlobalProxy then the auxiliary object is a property
16763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // of its prototype, and if it's a detached proxy, then you can't have
16773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // hidden properties.
16783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
16793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Sets a hidden property on this object. Returns this object if successful,
16803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // undefined if called on a detached proxy.
16813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static Handle<Object> SetHiddenProperty(Handle<JSObject> obj,
16823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                          Handle<String> key,
16833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                          Handle<Object> value);
16843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Returns a failure if a GC is required.
16853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT MaybeObject* SetHiddenProperty(String* key, Object* value);
16863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Gets the value of a hidden property with the given key. Returns undefined
16873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // if the property doesn't exist (or if called on a detached proxy),
16883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // otherwise returns the value set for the key.
16893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Object* GetHiddenProperty(String* key);
16903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Deletes a hidden property. Deleting a non-existing property is
16913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // considered successful.
16923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void DeleteHiddenProperty(String* key);
16933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Returns true if the object has a property with the hidden symbol as name.
16943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool HasHiddenProperties();
16953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
16963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static int GetIdentityHash(Handle<JSObject> obj);
16973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT MaybeObject* GetIdentityHash(CreationFlag flag);
16983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT MaybeObject* SetIdentityHash(Object* hash, CreationFlag flag);
16993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
17003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static Handle<Object> DeleteProperty(Handle<JSObject> obj,
17013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                       Handle<String> name);
170285b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch  MUST_USE_RESULT MaybeObject* DeleteProperty(String* name, DeleteMode mode);
17033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
17043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static Handle<Object> DeleteElement(Handle<JSObject> obj, uint32_t index);
17055913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* DeleteElement(uint32_t index, DeleteMode mode);
1706a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
17073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline void ValidateSmiOnlyElements();
17083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
17093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Makes sure that this object can contain HeapObject as elements.
17103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT inline MaybeObject* EnsureCanContainHeapObjectElements();
17113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
17123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Makes sure that this object can contain the specified elements.
17133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT inline MaybeObject* EnsureCanContainElements(
17143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Object** elements,
17153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      uint32_t count,
17163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      EnsureElementsMode mode);
17173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT inline MaybeObject* EnsureCanContainElements(
17183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      FixedArrayBase* elements,
17193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      EnsureElementsMode mode);
17203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT MaybeObject* EnsureCanContainElements(
17213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Arguments* arguments,
17223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      uint32_t first_arg,
17233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      uint32_t arg_count,
17243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      EnsureElementsMode mode);
1725a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1726a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Do we want to keep the elements in fast case when increasing the
1727a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // capacity?
1728a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool ShouldConvertToSlowElements(int new_capacity);
1729a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Returns true if the backing storage for the slow-case elements of
1730a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // this object takes up nearly as much space as a fast-case backing
1731a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // storage would.  In that case the JSObject should have fast
1732a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // elements.
1733a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool ShouldConvertToFastElements();
17343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Returns true if the elements of JSObject contains only values that can be
17353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // represented in a FixedDoubleArray and has at least one value that can only
17363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // be represented as a double and not a Smi.
17373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool ShouldConvertToFastDoubleElements(bool* has_smi_only_elements);
1738402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
1739a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Tells whether the index'th element is present.
17403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  bool HasElementWithReceiver(JSReceiver* receiver, uint32_t index);
17410d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
1742e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // Computes the new capacity when expanding the elements of a JSObject.
1743e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  static int NewElementsCapacity(int old_capacity) {
1744e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    // (old_capacity + 50%) + 16
1745e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    return old_capacity + (old_capacity >> 1) + 16;
1746e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  }
1747e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
17480d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // Tells whether the index'th element is present and how it is stored.
17490d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  enum LocalElementType {
17500d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    // There is no element with given index.
17510d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    UNDEFINED_ELEMENT,
17520d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
17530d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    // Element with given index is handled by interceptor.
17540d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    INTERCEPTED_ELEMENT,
17550d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
17560d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    // Element with given index is character in string.
17570d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    STRING_CHARACTER_ELEMENT,
17580d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
17590d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    // Element with given index is stored in fast backing store.
17600d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    FAST_ELEMENT,
17610d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
17620d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    // Element with given index is stored in slow backing store.
17630d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    DICTIONARY_ELEMENT
17640d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  };
17650d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
17660d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  LocalElementType HasLocalElement(uint32_t index);
1767a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
17683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  bool HasElementWithInterceptor(JSReceiver* receiver, uint32_t index);
1769a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
17709fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  MUST_USE_RESULT MaybeObject* SetFastElement(uint32_t index,
17719fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block                                              Object* value,
1772e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch                                              StrictModeFlag strict_mode,
17733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                              bool check_prototype);
17743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
17753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT MaybeObject* SetDictionaryElement(
17763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      uint32_t index,
17773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Object* value,
17783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      PropertyAttributes attributes,
17793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      StrictModeFlag strict_mode,
17803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      bool check_prototype,
17813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      SetPropertyMode set_mode = SET_PROPERTY);
17823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
17833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  MUST_USE_RESULT MaybeObject* SetFastDoubleElement(
17843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      uint32_t index,
17853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      Object* value,
17863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      StrictModeFlag strict_mode,
17873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      bool check_prototype = true);
1788a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
17893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static Handle<Object> SetOwnElement(Handle<JSObject> object,
17903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                      uint32_t index,
17913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                      Handle<Object> value,
17923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                      StrictModeFlag strict_mode);
17933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
17943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Empty handle is returned if the element cannot be set to the given value.
17953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static MUST_USE_RESULT Handle<Object> SetElement(
17963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Handle<JSObject> object,
17973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      uint32_t index,
17983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Handle<Object> value,
17993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      PropertyAttributes attr,
18003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      StrictModeFlag strict_mode,
18013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      SetPropertyMode set_mode = SET_PROPERTY);
18023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1803a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // A Failure object is returned if GC is needed.
18043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT MaybeObject* SetElement(
18053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      uint32_t index,
18063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Object* value,
18073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      PropertyAttributes attributes,
18083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      StrictModeFlag strict_mode,
18093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      bool check_prototype = true,
18103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      SetPropertyMode set_mode = SET_PROPERTY);
1811a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1812a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Returns the index'th element.
1813a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // The undefined object if index is out of bounds.
18143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT MaybeObject* GetElementWithInterceptor(Object* receiver,
18153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                                         uint32_t index);
18163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
18173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  enum SetFastElementsCapacityMode {
18183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    kAllowSmiOnlyElements,
18193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    kForceSmiOnlyElements,
18203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    kDontAllowSmiOnlyElements
18213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  };
1822592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch
18233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Replace the elements' backing store with fast elements of the given
18243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // capacity.  Update the length for JSArrays.  Returns the new backing
18253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // store.
18263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT MaybeObject* SetFastElementsCapacityAndLength(
18273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      int capacity,
18283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      int length,
18293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      SetFastElementsCapacityMode set_capacity_mode);
18303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  MUST_USE_RESULT MaybeObject* SetFastDoubleElementsCapacityAndLength(
18313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      int capacity,
18323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      int length);
1833a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1834a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Lookup interceptors are used for handling properties controlled by host
1835a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // objects.
1836a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline bool HasNamedInterceptor();
1837a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline bool HasIndexedInterceptor();
1838a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1839a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Support functions for v8 api (needed for correct interceptor behavior).
1840a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool HasRealNamedProperty(String* key);
1841a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool HasRealElementProperty(uint32_t index);
1842a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool HasRealNamedCallbackProperty(String* key);
1843a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1844a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Get the header size for a JSObject.  Used to compute the index of
1845a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // internal fields as well as the number of internal fields.
1846a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline int GetHeaderSize();
1847a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1848a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline int GetInternalFieldCount();
184944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  inline int GetInternalFieldOffset(int index);
1850a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline Object* GetInternalField(int index);
1851a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void SetInternalField(int index, Object* value);
18523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline void SetInternalField(int index, Smi* value);
1853a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1854a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // The following lookup functions skip interceptors.
1855a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void LocalLookupRealNamedProperty(String* name, LookupResult* result);
1856a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void LookupRealNamedProperty(String* name, LookupResult* result);
1857a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void LookupRealNamedPropertyInPrototypes(String* name, LookupResult* result);
1858a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void LookupCallbackSetterInPrototypes(String* name, LookupResult* result);
18591e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  MUST_USE_RESULT MaybeObject* SetElementWithCallbackSetterInPrototypes(
18603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      uint32_t index, Object* value, bool* found, StrictModeFlag strict_mode);
1861a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void LookupCallback(String* name, LookupResult* result);
1862a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1863a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Returns the number of properties on this object filtering out properties
1864a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // with the specified attributes (ignoring interceptors).
18653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int NumberOfLocalProperties(PropertyAttributes filter = NONE);
1866a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Fill in details for properties into storage starting at the specified
1867a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // index.
1868a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void GetLocalPropertyNames(FixedArray* storage, int index);
1869a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1870a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Returns the number of properties on this object filtering out properties
1871a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // with the specified attributes (ignoring interceptors).
1872a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int NumberOfLocalElements(PropertyAttributes filter);
1873a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Returns the number of enumerable elements (ignoring interceptors).
1874a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int NumberOfEnumElements();
1875a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Returns the number of elements on this object filtering out elements
1876a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // with the specified attributes (ignoring interceptors).
1877a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int GetLocalElementKeys(FixedArray* storage, PropertyAttributes filter);
1878a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Count and fill in the enumerable elements into storage.
1879a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // (storage->length() == NumberOfEnumElements()).
1880a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // If storage is NULL, will count the elements without adding
1881a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // them to any storage.
1882a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Returns the number of enumerable elements.
1883a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int GetEnumElementKeys(FixedArray* storage);
1884a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1885a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Add a property to a fast-case object using a map transition to
1886a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // new_map.
18875913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* AddFastPropertyUsingMap(Map* new_map,
18885913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck                                                       String* name,
18895913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck                                                       Object* value);
1890a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1891a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Add a constant function property to a fast-case object.
1892a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // This leaves a CONSTANT_TRANSITION in the old map, and
1893a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // if it is called on a second object with this map, a
1894a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // normal property is added instead, with a map transition.
1895a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // This avoids the creation of many maps with the same constant
1896a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // function, all orphaned.
18975913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* AddConstantFunctionProperty(
18985913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      String* name,
18995913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      JSFunction* function,
19005913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      PropertyAttributes attributes);
1901a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
19025913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* ReplaceSlowProperty(
19035913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      String* name,
19045913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      Object* value,
19055913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      PropertyAttributes attributes);
1906a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
19073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Returns a new map with all transitions dropped from the object's current
19083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // map and the ElementsKind set.
19093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static Handle<Map> GetElementsTransitionMap(Handle<JSObject> object,
19103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                              ElementsKind to_kind);
19113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline MUST_USE_RESULT MaybeObject* GetElementsTransitionMap(
19123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Isolate* isolate,
19133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      ElementsKind elements_kind);
19143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT MaybeObject* GetElementsTransitionMapSlow(
19153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      ElementsKind elements_kind);
19163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
19173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static Handle<Object> TransitionElementsKind(Handle<JSObject> object,
19183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                               ElementsKind to_kind);
19193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
19203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT MaybeObject* TransitionElementsKind(ElementsKind to_kind);
19213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1922a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Converts a descriptor of any other type to a real field,
1923a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // backed by the properties array.  Descriptors of visible
1924a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // types, such as CONSTANT_FUNCTION, keep their enumeration order.
1925a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Converts the descriptor on the original object's map to a
1926a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // map transition, and the the new field is on the object's new map.
19275913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* ConvertDescriptorToFieldAndMapTransition(
1928a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      String* name,
1929a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      Object* new_value,
1930a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      PropertyAttributes attributes);
1931a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1932a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Converts a descriptor of any other type to a real field,
1933a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // backed by the properties array.  Descriptors of visible
1934a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // types, such as CONSTANT_FUNCTION, keep their enumeration order.
19355913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* ConvertDescriptorToField(
19365913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      String* name,
19375913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      Object* new_value,
19385913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      PropertyAttributes attributes);
1939a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1940a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Add a property to a fast-case object.
19415913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* AddFastProperty(String* name,
19425913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck                                               Object* value,
19435913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck                                               PropertyAttributes attributes);
1944a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1945a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Add a property to a slow-case object.
19465913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* AddSlowProperty(String* name,
19475913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck                                               Object* value,
19485913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck                                               PropertyAttributes attributes);
1949a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1950a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Add a property to an object.
19515913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* AddProperty(String* name,
19525913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck                                           Object* value,
195344f0eee88ff00398ff7f715fab053374d808c90dSteve Block                                           PropertyAttributes attributes,
195444f0eee88ff00398ff7f715fab053374d808c90dSteve Block                                           StrictModeFlag strict_mode);
1955a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1956a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Convert the object to use the canonical dictionary
1957a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // representation. If the object is expected to have additional properties
1958a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // added this number can be indicated to have the backing store allocated to
1959a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // an initial capacity for holding these properties.
19603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static void NormalizeProperties(Handle<JSObject> object,
19613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                  PropertyNormalizationMode mode,
19623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                  int expected_additional_properties);
19633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
19645913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* NormalizeProperties(
19655913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      PropertyNormalizationMode mode,
19665913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      int expected_additional_properties);
19673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
19683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Convert and update the elements backing store to be a
19693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // SeededNumberDictionary dictionary.  Returns the backing after conversion.
19703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static Handle<SeededNumberDictionary> NormalizeElements(
19713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Handle<JSObject> object);
19723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
19735913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* NormalizeElements();
1974a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
19753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static void UpdateMapCodeCache(Handle<JSObject> object,
19763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                 Handle<String> name,
19773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                 Handle<Code> code);
19783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
19795913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* UpdateMapCodeCache(String* name, Code* code);
198080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
1981a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Transform slow named properties to fast variants.
1982a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Returns failure if allocation failed.
19833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static void TransformToFastProperties(Handle<JSObject> object,
19843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                        int unused_property_fields);
19853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
19865913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* TransformToFastProperties(
19875913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      int unused_property_fields);
1988a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1989a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Access fast-case object properties at index.
1990a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline Object* FastPropertyAt(int index);
1991a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline Object* FastPropertyAtPut(int index, Object* value);
1992a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1993a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Access to in object properties.
199444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  inline int GetInObjectPropertyOffset(int index);
1995a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline Object* InObjectPropertyAt(int index);
1996a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline Object* InObjectPropertyAtPut(int index,
1997a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                       Object* value,
1998a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                       WriteBarrierMode mode
1999a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                       = UPDATE_WRITE_BARRIER);
2000a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
20013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Initializes the body after properties slot, properties slot is
20023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // initialized by set_properties.  Fill the pre-allocated fields with
20033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // pre_allocated_value and the rest with filler_value.
20043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Note: this call does not update write barrier, the caller is responsible
20053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // to ensure that |filler_value| can be collected without WB here.
20063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline void InitializeBody(Map* map,
20073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                             Object* pre_allocated_value,
20083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                             Object* filler_value);
2009a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2010a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Check whether this object references another object
2011a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool ReferencesObject(Object* obj);
2012a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2013a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Casting.
2014a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline JSObject* cast(Object* obj);
2015a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
20168defd9ff6930b4e24729971a61cf7469daf119beSteve Block  // Disalow further properties to be added to the object.
20173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static Handle<Object> PreventExtensions(Handle<JSObject> object);
20185913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* PreventExtensions();
20198defd9ff6930b4e24729971a61cf7469daf119beSteve Block
20208defd9ff6930b4e24729971a61cf7469daf119beSteve Block
2021a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Dispatched behavior.
2022a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void JSObjectShortPrint(StringStream* accumulator);
2023b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef OBJECT_PRINT
2024b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  inline void JSObjectPrint() {
2025b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    JSObjectPrint(stdout);
2026b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
2027b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void JSObjectPrint(FILE* out);
2028b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif
2029a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG
2030a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void JSObjectVerify();
2031b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif
2032b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef OBJECT_PRINT
2033b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  inline void PrintProperties() {
2034b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    PrintProperties(stdout);
2035b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
2036b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void PrintProperties(FILE* out);
2037b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2038b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  inline void PrintElements() {
2039b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    PrintElements(stdout);
2040b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
2041b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void PrintElements(FILE* out);
2042b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif
2043a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
20443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void PrintElementsTransition(
20453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      FILE* file, ElementsKind from_kind, FixedArrayBase* from_elements,
20463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      ElementsKind to_kind, FixedArrayBase* to_elements);
20473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2048b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef DEBUG
2049a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Structure for collecting spill information about JSObjects.
2050a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  class SpillInformation {
2051a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block   public:
2052a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    void Clear();
2053a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    void Print();
2054a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    int number_of_objects_;
2055a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    int number_of_objects_with_fast_properties_;
2056a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    int number_of_objects_with_fast_elements_;
2057a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    int number_of_fast_used_fields_;
2058a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    int number_of_fast_unused_fields_;
2059a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    int number_of_slow_used_properties_;
2060a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    int number_of_slow_unused_properties_;
2061a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    int number_of_fast_used_elements_;
2062a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    int number_of_fast_unused_elements_;
2063a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    int number_of_slow_used_elements_;
2064a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    int number_of_slow_unused_elements_;
2065a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  };
2066a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2067a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void IncrementSpillStatistics(SpillInformation* info);
2068a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
2069a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* SlowReverseLookup(Object* value);
2070a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
20718defd9ff6930b4e24729971a61cf7469daf119beSteve Block  // Maximal number of fast properties for the JSObject. Used to
20728defd9ff6930b4e24729971a61cf7469daf119beSteve Block  // restrict the number of map transitions to avoid an explosion in
20738defd9ff6930b4e24729971a61cf7469daf119beSteve Block  // the number of maps for objects used as dictionaries.
20748defd9ff6930b4e24729971a61cf7469daf119beSteve Block  inline int MaxFastProperties();
20758defd9ff6930b4e24729971a61cf7469daf119beSteve Block
2076e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Maximal number of elements (numbered 0 .. kMaxElementCount - 1).
2077e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Also maximal value of JSArray's length property.
2078e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  static const uint32_t kMaxElementCount = 0xffffffffu;
2079e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
208069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  // Constants for heuristics controlling conversion of fast elements
208169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  // to slow elements.
208269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
208369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  // Maximal gap that can be introduced by adding an element beyond
208469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  // the current elements length.
2085a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const uint32_t kMaxGap = 1024;
208669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
208769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  // Maximal length of fast elements array that won't be checked for
208869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  // being dense enough on expansion.
208969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  static const int kMaxUncheckedFastElementsLength = 5000;
209069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
209169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  // Same as above but for old arrays. This limit is more strict. We
209269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  // don't want to be wasteful with long lived objects.
209369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  static const int kMaxUncheckedOldFastElementsLength = 500;
209469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
2095a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kInitialMaxFastElementArray = 100000;
2096b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static const int kMaxFastProperties = 12;
2097a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kMaxInstanceSize = 255 * kPointerSize;
2098a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // When extending the backing storage for property values, we increase
2099a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // its size by more than the 1 entry necessary, so sequentially adding fields
2100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // to the same object requires fewer allocations and copies.
2101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kFieldsAdded = 3;
2102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Layout description.
2104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kPropertiesOffset = HeapObject::kHeaderSize;
2105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kElementsOffset = kPropertiesOffset + kPointerSize;
2106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kHeaderSize = kElementsOffset + kPointerSize;
2107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  STATIC_CHECK(kHeaderSize == Internals::kJSObjectHeaderSize);
2109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2110756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  class BodyDescriptor : public FlexibleBodyDescriptor<kPropertiesOffset> {
2111756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick   public:
2112756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick    static inline int SizeOf(Map* map, HeapObject* object);
2113756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  };
2114756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
2115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
211669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  friend class DictionaryElementsAccessor;
211769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
21185913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* GetElementWithCallback(Object* receiver,
21195913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck                                                      Object* structure,
21205913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck                                                      uint32_t index,
21215913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck                                                      Object* holder);
21223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT MaybeObject* SetElementWithCallback(
21233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Object* structure,
21243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      uint32_t index,
21253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Object* value,
21263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      JSObject* holder,
21273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      StrictModeFlag strict_mode);
2128e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  MUST_USE_RESULT MaybeObject* SetElementWithInterceptor(
2129e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      uint32_t index,
2130e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      Object* value,
21313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      PropertyAttributes attributes,
2132e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      StrictModeFlag strict_mode,
21333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      bool check_prototype,
21343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      SetPropertyMode set_mode);
21359fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  MUST_USE_RESULT MaybeObject* SetElementWithoutInterceptor(
21369fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block      uint32_t index,
21379fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block      Object* value,
21383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      PropertyAttributes attributes,
2139e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      StrictModeFlag strict_mode,
21403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      bool check_prototype,
21413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      SetPropertyMode set_mode);
21423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
21433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Searches the prototype chain for a callback setter and sets the property
21443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // with the setter if it finds one. The '*found' flag indicates whether
21453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // a setter was found or not.
21463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // This function can cause GC and can return a failure result with
21473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // '*found==true'.
21483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT MaybeObject* SetPropertyWithCallbackSetterInPrototypes(
21493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      String* name,
21503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Object* value,
21513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      PropertyAttributes attributes,
21523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      bool* found,
21533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      StrictModeFlag strict_mode);
2154592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch
21555913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* DeletePropertyPostInterceptor(String* name,
21565913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck                                                             DeleteMode mode);
21575913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* DeletePropertyWithInterceptor(String* name);
21585913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck
21595913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* DeleteElementWithInterceptor(uint32_t index);
2160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
21613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  MUST_USE_RESULT MaybeObject* DeleteFastElement(uint32_t index);
21623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  MUST_USE_RESULT MaybeObject* DeleteDictionaryElement(uint32_t index,
21633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                                       DeleteMode mode);
21643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
21653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  bool ReferencesObjectFromElements(FixedArray* elements,
21663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                    ElementsKind kind,
21673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                    Object* object);
2168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Returns true if most of the elements backing storage is used.
2170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool HasDenseElements();
2171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
217269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  // Gets the current elements capacity and the number of used elements.
217369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  void GetElementsCapacityAndUsage(int* capacity, int* used);
217469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
2175f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  bool CanSetCallback(String* name);
21765913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* SetElementCallback(
21775913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      uint32_t index,
21785913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      Object* structure,
21795913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      PropertyAttributes attributes);
21805913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* SetPropertyCallback(
21815913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      String* name,
21825913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      Object* structure,
21835913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      PropertyAttributes attributes);
21843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT MaybeObject* DefineElementAccessor(
21853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      uint32_t index,
21863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Object* getter,
21873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Object* setter,
21883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      PropertyAttributes attributes);
21893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT MaybeObject* DefinePropertyAccessor(
21905913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      String* name,
21913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Object* getter,
21923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Object* setter,
21935913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      PropertyAttributes attributes);
219485b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch  void LookupInDescriptor(String* name, LookupResult* result);
2195592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch
21963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Returns the hidden properties backing store object, currently
21973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // a StringDictionary, stored on this object.
21983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // If no hidden properties object has been put on this object,
21993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // return undefined, unless create_if_absent is true, in which case
22003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // a new dictionary is created, added to this object, and returned.
22013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT MaybeObject* GetHiddenPropertiesDictionary(
22023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      bool create_if_absent);
22033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Updates the existing hidden properties dictionary.
22043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT MaybeObject* SetHiddenPropertiesDictionary(
22053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      StringDictionary* dictionary);
22063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DISALLOW_IMPLICIT_CONSTRUCTORS(JSObject);
2208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
2209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
22113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// Common superclass for FixedArrays that allow implementations to share
22123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// common accessors and some code paths.
22133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochclass FixedArrayBase: public HeapObject {
2214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
2215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // [length]: length of the array.
2216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline int length();
2217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void set_length(int value);
2218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
22193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  inline static FixedArrayBase* cast(Object* object);
22203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
22213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Layout description.
22223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Length is smi tagged when it is stored.
22233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  static const int kLengthOffset = HeapObject::kHeaderSize;
22243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  static const int kHeaderSize = kLengthOffset + kPointerSize;
22253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch};
22263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
22273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
222869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochclass FixedDoubleArray;
222969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
22303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// FixedArray describes fixed-sized arrays with element type Object*.
22313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochclass FixedArray: public FixedArrayBase {
22323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch public:
2233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Setter and getter for elements.
2234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline Object* get(int index);
2235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Setter that uses write barrier.
2236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void set(int index, Object* value);
223769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  inline bool is_the_hole(int index);
2238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Setter that doesn't need write barrier).
2240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void set(int index, Smi* value);
2241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Setter with explicit barrier mode.
2242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void set(int index, Object* value, WriteBarrierMode mode);
2243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Setters for frequently used oddballs located in old space.
2245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void set_undefined(int index);
224644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // TODO(isolates): duplicate.
224744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  inline void set_undefined(Heap* heap, int index);
2248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void set_null(int index);
224944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // TODO(isolates): duplicate.
225044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  inline void set_null(Heap* heap, int index);
2251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void set_the_hole(int index);
2252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2253756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  // Setters with less debug checks for the GC to use.
2254756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  inline void set_unchecked(int index, Smi* value);
225544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  inline void set_null_unchecked(Heap* heap, int index);
225644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  inline void set_unchecked(Heap* heap, int index, Object* value,
225744f0eee88ff00398ff7f715fab053374d808c90dSteve Block                            WriteBarrierMode mode);
2258756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
22596ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Gives access to raw memory which stores the array's data.
22606ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  inline Object** data_start();
22616ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
22623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline Object** GetFirstElementAddress();
22633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline bool ContainsOnlySmisOrHoles();
22643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Copy operations.
22665913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT inline MaybeObject* Copy();
22675913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* CopySize(int new_length);
2268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Add the elements of a JSArray to this FixedArray.
22705913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* AddKeysFromJSArray(JSArray* array);
2271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Compute the union of this and other.
22735913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* UnionOfKeys(FixedArray* other);
2274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Copy a sub array from the receiver to dest.
2276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void CopyTo(int pos, FixedArray* dest, int dest_pos, int len);
2277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Garbage collection support.
2279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static int SizeFor(int length) { return kHeaderSize + length * kPointerSize; }
2280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Code Generation support.
2282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static int OffsetOfElementAt(int index) { return SizeFor(index); }
2283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Casting.
2285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline FixedArray* cast(Object* obj);
2286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2287e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Maximal allowed size, in bytes, of a single FixedArray.
2288e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Prevents overflowing size computations, as well as extreme memory
2289e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // consumption.
2290692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch  static const int kMaxSize = 128 * MB * kPointerSize;
2291e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Maximally allowed length of a FixedArray.
2292e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  static const int kMaxLength = (kMaxSize - kHeaderSize) / kPointerSize;
2293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Dispatched behavior.
2295b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef OBJECT_PRINT
2296b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  inline void FixedArrayPrint() {
2297b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    FixedArrayPrint(stdout);
2298b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
2299b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void FixedArrayPrint(FILE* out);
2300b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif
2301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG
2302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void FixedArrayVerify();
2303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Checks if two FixedArrays have identical contents.
2304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool IsEqualTo(FixedArray* other);
2305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
2306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Swap two elements in a pair of arrays.  If this array and the
2308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // numbers array are the same object, the elements are only swapped
2309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // once.
2310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void SwapPairs(FixedArray* numbers, int i, int j);
2311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Sort prefix of this array and the numbers array as pairs wrt. the
2313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // numbers.  If the numbers array and the this array are the same
2314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // object, the prefix of this array is sorted.
2315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void SortPairs(FixedArray* numbers, uint32_t len);
2316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2317756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  class BodyDescriptor : public FlexibleBodyDescriptor<kHeaderSize> {
2318756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick   public:
2319756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick    static inline int SizeOf(Map* map, HeapObject* object) {
2320756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick      return SizeFor(reinterpret_cast<FixedArray*>(object)->length());
2321756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick    }
2322756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  };
2323756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
2324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block protected:
23254515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  // Set operation on FixedArray without using write barriers. Can
23264515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  // only be used for storing old space objects or smis.
23273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static inline void NoWriteBarrierSet(FixedArray* array,
23283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                       int index,
23293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                       Object* value);
23303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
23313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Set operation on FixedArray without incremental write barrier. Can
23323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // only be used if the object is guaranteed to be white (whiteness witness
23333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // is present).
23343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static inline void NoIncrementalWriteBarrierSet(FixedArray* array,
23353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                                  int index,
23363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                                  Object* value);
2337c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch
2338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
2339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DISALLOW_IMPLICIT_CONSTRUCTORS(FixedArray);
2340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
2341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
23433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// FixedDoubleArray describes fixed-sized arrays with element type double.
23443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochclass FixedDoubleArray: public FixedArrayBase {
23453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch public:
23463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Setter and getter for elements.
234769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  inline double get_scalar(int index);
23483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline int64_t get_representation(int index);
23493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT inline MaybeObject* get(int index);
23503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  inline void set(int index, double value);
23513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  inline void set_the_hole(int index);
23523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
23533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Checking for the hole.
23543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  inline bool is_the_hole(int index);
23553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
23563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Copy operations
23573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT inline MaybeObject* Copy();
23583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
23593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Garbage collection support.
23603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  inline static int SizeFor(int length) {
23613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    return kHeaderSize + length * kDoubleSize;
23623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
23633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
23643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Code Generation support.
23653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  static int OffsetOfElementAt(int index) { return SizeFor(index); }
23663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
23673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  inline static bool is_the_hole_nan(double value);
23683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  inline static double hole_nan_as_double();
23693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  inline static double canonical_not_the_hole_nan_as_double();
23703fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
23713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Casting.
23723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  static inline FixedDoubleArray* cast(Object* obj);
23733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
23743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Maximal allowed size, in bytes, of a single FixedDoubleArray.
23753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Prevents overflowing size computations, as well as extreme memory
23763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // consumption.
23773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  static const int kMaxSize = 512 * MB;
23783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Maximally allowed length of a FixedArray.
23793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  static const int kMaxLength = (kMaxSize - kHeaderSize) / kDoubleSize;
23803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
23813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Dispatched behavior.
23823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#ifdef OBJECT_PRINT
23833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  inline void FixedDoubleArrayPrint() {
23843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    FixedDoubleArrayPrint(stdout);
23853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
23863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  void FixedDoubleArrayPrint(FILE* out);
23873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif
23883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
23893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#ifdef DEBUG
23903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  void FixedDoubleArrayVerify();
23913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif
23923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
23933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch private:
23943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  DISALLOW_IMPLICIT_CONSTRUCTORS(FixedDoubleArray);
23953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch};
23963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
23973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
23983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochclass IncrementalMarking;
23993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
24003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// DescriptorArrays are fixed arrays used to hold instance descriptors.
2402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The format of the these objects is:
2403257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// TODO(1399): It should be possible to make room for bit_field3 in the map
2404257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch//             without overloading the instance descriptors field in the map
2405257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch//             (and storing it in the DescriptorArray when the map has one).
2406257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch//   [0]: storage for bit_field3 for Map owning this object (Smi)
2407257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch//   [1]: point to a fixed array with (value, detail) pairs.
2408257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch//   [2]: next enumeration index (Smi), or pointer to small fixed array:
2409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//          [0]: next enumeration index (Smi)
2410a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//          [1]: pointer to fixed array with enum cache
2411257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch//   [3]: first key
2412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//   [length() - 1]: last key
2413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
2414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass DescriptorArray: public FixedArray {
2415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
2416257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Returns true for both shared empty_descriptor_array and for smis, which the
2417257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // map uses to encode additional bit fields when the descriptor array is not
2418257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // yet used.
2419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline bool IsEmpty();
2420e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
2421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Returns the number of descriptors in the array.
2422a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int number_of_descriptors() {
242344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    ASSERT(length() > kFirstIndex || IsEmpty());
242444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    int len = length();
242544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    return len <= kFirstIndex ? 0 : len - kFirstIndex;
2426a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2427a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int NextEnumerationIndex() {
2429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (IsEmpty()) return PropertyDetails::kInitialIndex;
2430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Object* obj = get(kEnumerationIndexIndex);
2431a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (obj->IsSmi()) {
2432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      return Smi::cast(obj)->value();
2433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    } else {
2434a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      Object* index = FixedArray::cast(obj)->get(kEnumCacheBridgeEnumIndex);
2435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      return Smi::cast(index)->value();
2436a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
2437a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2438a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Set next enumeration index and flush any enum cache.
2440a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void SetNextEnumerationIndex(int value) {
2441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (!IsEmpty()) {
24423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      set(kEnumerationIndexIndex, Smi::FromInt(value));
2443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
2444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool HasEnumCache() {
2446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return !IsEmpty() && !get(kEnumerationIndexIndex)->IsSmi();
2447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2449a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* GetEnumCache() {
2450a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    ASSERT(HasEnumCache());
2451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    FixedArray* bridge = FixedArray::cast(get(kEnumerationIndexIndex));
2452a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return bridge->get(kEnumCacheBridgeCacheIndex);
2453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2455257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // TODO(1399): It should be possible to make room for bit_field3 in the map
2456257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  //             without overloading the instance descriptors field in the map
2457257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  //             (and storing it in the DescriptorArray when the map has one).
2458257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  inline int bit_field3_storage();
2459257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  inline void set_bit_field3_storage(int value);
2460257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
2461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Initialize or change the enum cache,
2462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // using the supplied storage for the small "bridge".
24633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void SetEnumCache(FixedArray* bridge_storage,
24643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                    FixedArray* new_cache,
24653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                    Object* new_index_cache);
2466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Accessors for fetching instance descriptor at descriptor number.
2468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline String* GetKey(int descriptor_number);
2469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline Object* GetValue(int descriptor_number);
2470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline Smi* GetDetails(int descriptor_number);
2471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline PropertyType GetType(int descriptor_number);
2472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline int GetFieldIndex(int descriptor_number);
2473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline JSFunction* GetConstantFunction(int descriptor_number);
2474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline Object* GetCallbacksObject(int descriptor_number);
2475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline AccessorDescriptor* GetCallbacks(int descriptor_number);
2476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline bool IsProperty(int descriptor_number);
24773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline bool IsTransitionOnly(int descriptor_number);
2478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline bool IsNullDescriptor(int descriptor_number);
2479a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline bool IsDontEnum(int descriptor_number);
2480a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
24813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  class WhitenessWitness {
24823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch   public:
24833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    inline explicit WhitenessWitness(DescriptorArray* array);
24843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    inline ~WhitenessWitness();
24853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
24863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch   private:
24873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    IncrementalMarking* marking_;
24883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  };
24893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2490a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Accessor for complete descriptor.
2491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void Get(int descriptor_number, Descriptor* desc);
24923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline void Set(int descriptor_number,
24933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                  Descriptor* desc,
24943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                  const WhitenessWitness&);
24953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
24963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Transfer a complete descriptor from the src descriptor array to the dst
24973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // one, dropping map transitions in CALLBACKS.
24983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static void CopyFrom(Handle<DescriptorArray> dst,
24993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                       int dst_index,
25003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                       Handle<DescriptorArray> src,
25013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                       int src_index,
25023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                       const WhitenessWitness& witness);
25033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
25043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Transfer a complete descriptor from the src descriptor array to this
25053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // descriptor array, dropping map transitions in CALLBACKS.
25063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT MaybeObject* CopyFrom(int dst_index,
25073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                        DescriptorArray* src,
25083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                        int src_index,
25093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                        const WhitenessWitness&);
2510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Copy the descriptor array, insert a new descriptor and optionally
2512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // remove map transitions.  If the descriptor is already present, it is
2513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // replaced.  If a replaced descriptor is a real property (not a transition
2514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // or null), its enumeration index is kept as is.
2515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // If adding a real property, map transitions must be removed.  If adding
2516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // a transition, they must not be removed.  All null descriptors are removed.
25175913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* CopyInsert(Descriptor* descriptor,
25185913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck                                          TransitionFlag transition_flag);
2519a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
25203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Return a copy of the array with all transitions and null descriptors
25213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // removed. Return a Failure object in case of an allocation failure.
25225913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* RemoveTransitions();
2523a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2524a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Sort the instance descriptors by the hash codes of their keys.
25250d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // Does not check for duplicates.
25263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void SortUnchecked(const WhitenessWitness&);
25270d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
25280d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // Sort the instance descriptors by the hash codes of their keys.
25290d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // Checks the result for duplicates.
25303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void Sort(const WhitenessWitness&);
2531a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2532a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Search the instance descriptors for given name.
2533a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline int Search(String* name);
2534a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2535756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  // As the above, but uses DescriptorLookupCache and updates it when
2536756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  // necessary.
2537756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  inline int SearchWithCache(String* name);
2538756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
2539a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Tells whether the name is present int the array.
2540a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool Contains(String* name) { return kNotFound != Search(name); }
2541a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2542a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Perform a binary search in the instance descriptors represented
2543a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // by this fixed array.  low and high are descriptor indices.  If there
2544a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // are three instance descriptors in this array it should be called
2545a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // with low=0 and high=2.
2546a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int BinarySearch(String* name, int low, int high);
2547a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2548a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Perform a linear search in the instance descriptors represented
2549a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // by this fixed array.  len is the number of descriptor indices that are
2550a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // valid.  Does not require the descriptors to be sorted.
2551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int LinearSearch(String* name, int len);
2552a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2553a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Allocates a DescriptorArray, but returns the singleton
2554a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // empty descriptor array object if number_of_descriptors is 0.
25555913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT static MaybeObject* Allocate(int number_of_descriptors);
2556a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2557a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Casting.
2558a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline DescriptorArray* cast(Object* obj);
2559a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2560a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Constant for denoting key was not found.
2561a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kNotFound = -1;
2562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2563257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  static const int kBitField3StorageIndex = 0;
2564257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  static const int kContentArrayIndex = 1;
2565257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  static const int kEnumerationIndexIndex = 2;
2566257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  static const int kFirstIndex = 3;
2567a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2568a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // The length of the "bridge" to the enum cache.
25693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kEnumCacheBridgeLength = 3;
2570a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kEnumCacheBridgeEnumIndex = 0;
2571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kEnumCacheBridgeCacheIndex = 1;
25723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kEnumCacheBridgeIndicesCacheIndex = 2;
2573a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2574a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Layout description.
2575257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  static const int kBitField3StorageOffset = FixedArray::kHeaderSize;
2576257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  static const int kContentArrayOffset = kBitField3StorageOffset + kPointerSize;
2577a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kEnumerationIndexOffset = kContentArrayOffset + kPointerSize;
2578a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kFirstOffset = kEnumerationIndexOffset + kPointerSize;
2579a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2580a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Layout description for the bridge array.
2581a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kEnumCacheBridgeEnumOffset = FixedArray::kHeaderSize;
2582a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kEnumCacheBridgeCacheOffset =
2583a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    kEnumCacheBridgeEnumOffset + kPointerSize;
2584a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2585b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef OBJECT_PRINT
2586a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Print all the descriptors.
2587b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  inline void PrintDescriptors() {
2588b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    PrintDescriptors(stdout);
2589b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
2590b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void PrintDescriptors(FILE* out);
2591b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif
2592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2593b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef DEBUG
2594a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Is the descriptor array sorted and without duplicates?
2595a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool IsSortedNoDuplicates();
2596a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2597a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Are two DescriptorArrays equal?
2598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool IsEqualTo(DescriptorArray* other);
2599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
2600a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2601a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // The maximum number of descriptors we want in a descriptor array (should
2602a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // fit in a page).
2603a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kMaxNumberOfDescriptors = 1024 + 512;
2604a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2605a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
26063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // An entry in a DescriptorArray, represented as an (array, index) pair.
26073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  class Entry {
26083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch   public:
26093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    inline explicit Entry(DescriptorArray* descs, int index) :
26103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        descs_(descs), index_(index) { }
26113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
26123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    inline PropertyType type() { return descs_->GetType(index_); }
26133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    inline Object* GetCallbackObject() { return descs_->GetValue(index_); }
26143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
26153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch   private:
26163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    DescriptorArray* descs_;
26173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    int index_;
26183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  };
26193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2620a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Conversion from descriptor number to array indices.
2621a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static int ToKeyIndex(int descriptor_number) {
2622a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return descriptor_number+kFirstIndex;
2623a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2624e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
2625e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  static int ToDetailsIndex(int descriptor_number) {
2626e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    return (descriptor_number << 1) + 1;
2627e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  }
2628e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
2629a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static int ToValueIndex(int descriptor_number) {
2630a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return descriptor_number << 1;
2631a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2632a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2633a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool is_null_descriptor(int descriptor_number) {
2634a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return PropertyDetails(GetDetails(descriptor_number)).type() ==
2635a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        NULL_DESCRIPTOR;
2636a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2637a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Swap operation on FixedArray without using write barriers.
26383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static inline void NoIncrementalWriteBarrierSwap(
26393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      FixedArray* array, int first, int second);
2640a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2641a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Swap descriptor first and second.
26423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline void NoIncrementalWriteBarrierSwapDescriptors(
26433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      int first, int second);
2644a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2645a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  FixedArray* GetContentArray() {
2646a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return FixedArray::cast(get(kContentArrayIndex));
2647a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2648a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DISALLOW_IMPLICIT_CONSTRUCTORS(DescriptorArray);
2649a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
2650a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2651a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2652a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// HashTable is a subclass of FixedArray that implements a hash table
2653a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// that uses open addressing and quadratic probing.
2654a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
2655a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// In order for the quadratic probing to work, elements that have not
2656a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// yet been used and elements that have been deleted are
2657a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// distinguished.  Probing continues when deleted elements are
2658a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// encountered and stops when unused elements are encountered.
2659a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
2660a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// - Elements with key == undefined have not been used yet.
26613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// - Elements with key == the_hole have been deleted.
2662a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
2663a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The hash table class is parameterized with a Shape and a Key.
2664a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Shape must be a class with the following interface:
2665a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//   class ExampleShape {
2666a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//    public:
2667a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//      // Tells whether key matches other.
2668a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     static bool IsMatch(Key key, Object* other);
2669a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     // Returns the hash value for key.
2670a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     static uint32_t Hash(Key key);
2671a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     // Returns the hash value for object.
2672a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     static uint32_t HashForObject(Key key, Object* object);
2673a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     // Convert key to an object.
2674a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     static inline Object* AsObject(Key key);
2675a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     // The prefix size indicates number of elements in the beginning
2676a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     // of the backing storage.
2677a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     static const int kPrefixSize = ..;
2678a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     // The Element size indicates number of elements per entry.
2679a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     static const int kEntrySize = ..;
2680a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//   };
26813ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// The prefix size indicates an amount of memory in the
2682a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// beginning of the backing storage that can be used for non-element
2683a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// information by subclasses.
2684a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2685c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdochtemplate<typename Key>
2686c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdochclass BaseShape {
2687c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch public:
2688c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch  static const bool UsesSeed = false;
2689c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch  static uint32_t Hash(Key key) { return 0; }
2690c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch  static uint32_t SeededHash(Key key, uint32_t seed) {
2691c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch    ASSERT(UsesSeed);
2692c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch    return Hash(key);
2693c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch  }
2694c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch  static uint32_t HashForObject(Key key, Object* object) { return 0; }
2695c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch  static uint32_t SeededHashForObject(Key key, uint32_t seed, Object* object) {
26963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    ASSERT(UsesSeed);
2697c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch    return HashForObject(key, object);
2698c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch  }
2699c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch};
2700c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch
2701a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocktemplate<typename Shape, typename Key>
2702a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass HashTable: public FixedArray {
2703a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
2704c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch  // Wrapper methods
2705c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch  inline uint32_t Hash(Key key) {
2706c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch    if (Shape::UsesSeed) {
27073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      return Shape::SeededHash(key,
27083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          GetHeap()->HashSeed());
2709c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch    } else {
2710c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch      return Shape::Hash(key);
2711c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch    }
2712c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch  }
2713c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch
2714c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch  inline uint32_t HashForObject(Key key, Object* object) {
2715c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch    if (Shape::UsesSeed) {
27163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      return Shape::SeededHashForObject(key,
27173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          GetHeap()->HashSeed(), object);
2718c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch    } else {
2719c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch      return Shape::HashForObject(key, object);
2720c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch    }
2721c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch  }
2722c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch
27233ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // Returns the number of elements in the hash table.
2724a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int NumberOfElements() {
2725a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return Smi::cast(get(kNumberOfElementsIndex))->value();
2726a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2727a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2728e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Returns the number of deleted elements in the hash table.
2729e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  int NumberOfDeletedElements() {
2730e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    return Smi::cast(get(kNumberOfDeletedElementsIndex))->value();
2731e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  }
2732e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
27333ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // Returns the capacity of the hash table.
2734a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int Capacity() {
2735a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return Smi::cast(get(kCapacityIndex))->value();
2736a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2737a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2738a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ElementAdded should be called whenever an element is added to a
27393ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // hash table.
2740a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void ElementAdded() { SetNumberOfElements(NumberOfElements() + 1); }
2741a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2742a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ElementRemoved should be called whenever an element is removed from
27433ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // a hash table.
2744e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  void ElementRemoved() {
2745e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    SetNumberOfElements(NumberOfElements() - 1);
2746e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    SetNumberOfDeletedElements(NumberOfDeletedElements() + 1);
2747e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  }
2748e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  void ElementsRemoved(int n) {
2749e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    SetNumberOfElements(NumberOfElements() - n);
2750e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    SetNumberOfDeletedElements(NumberOfDeletedElements() + n);
2751e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  }
2752a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
27533ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // Returns a new HashTable object. Might return Failure.
27545913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT static MaybeObject* Allocate(
275580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen      int at_least_space_for,
275680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen      PretenureFlag pretenure = NOT_TENURED);
2757a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
275869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  // Computes the required capacity for a table holding the given
275969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  // number of elements. May be more than HashTable::kMaxCapacity.
276069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  static int ComputeCapacity(int at_least_space_for);
276169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
2762a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Returns the key at entry.
2763a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* KeyAt(int entry) { return get(EntryToIndex(entry)); }
2764a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
27653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Tells whether k is a real key.  The hole and undefined are not allowed
2766a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // as keys and can be used to indicate missing or deleted elements.
2767a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool IsKey(Object* k) {
27683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return !k->IsTheHole() && !k->IsUndefined();
2769a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2770a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2771a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Garbage collection support.
2772a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void IteratePrefix(ObjectVisitor* visitor);
2773a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void IterateElements(ObjectVisitor* visitor);
2774a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2775a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Casting.
2776a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline HashTable* cast(Object* obj);
2777a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2778a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Compute the probe offset (quadratic probing).
2779a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  INLINE(static uint32_t GetProbeOffset(uint32_t n)) {
2780a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return (n + n * n) >> 1;
2781a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2782a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2783a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kNumberOfElementsIndex = 0;
2784e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  static const int kNumberOfDeletedElementsIndex = 1;
2785e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  static const int kCapacityIndex = 2;
2786e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  static const int kPrefixStartIndex = 3;
2787e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  static const int kElementsStartIndex =
2788a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      kPrefixStartIndex + Shape::kPrefixSize;
2789e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  static const int kEntrySize = Shape::kEntrySize;
2790e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  static const int kElementsStartOffset =
2791a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      kHeaderSize + kElementsStartIndex * kPointerSize;
27926ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static const int kCapacityOffset =
27936ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      kHeaderSize + kCapacityIndex * kPointerSize;
2794a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2795a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Constant used for denoting a absent entry.
2796a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kNotFound = -1;
2797a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2798e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Maximal capacity of HashTable. Based on maximal length of underlying
2799e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // FixedArray. Staying below kMaxCapacity also ensures that EntryToIndex
2800e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // cannot overflow.
2801e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  static const int kMaxCapacity =
2802e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke      (FixedArray::kMaxLength - kElementsStartOffset) / kEntrySize;
2803e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
28043bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  // Find entry for key otherwise return kNotFound.
280544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  inline int FindEntry(Key key);
280644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  int FindEntry(Isolate* isolate, Key key);
2807a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2808a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block protected:
2809a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Find the entry at which to insert element with the given key that
2810a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // has the given hash value.
2811a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  uint32_t FindInsertionEntry(uint32_t hash);
2812a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2813a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Returns the index for an entry (of the key)
2814a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline int EntryToIndex(int entry) {
2815a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return (entry * kEntrySize) + kElementsStartIndex;
2816a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2817a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
28183ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // Update the number of elements in the hash table.
2819a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void SetNumberOfElements(int nof) {
28203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    set(kNumberOfElementsIndex, Smi::FromInt(nof));
2821a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2822a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2823e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Update the number of deleted elements in the hash table.
2824e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  void SetNumberOfDeletedElements(int nod) {
28253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    set(kNumberOfDeletedElementsIndex, Smi::FromInt(nod));
2826e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  }
2827e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
2828a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Sets the capacity of the hash table.
2829a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void SetCapacity(int capacity) {
2830a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // To scale a computed hash code to fit within the hash table, we
2831a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // use bit-wise AND with a mask, so the capacity must be positive
2832a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // and non-zero.
2833a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    ASSERT(capacity > 0);
2834e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    ASSERT(capacity <= kMaxCapacity);
28353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    set(kCapacityIndex, Smi::FromInt(capacity));
2836a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2837a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2838a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2839a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Returns probe entry.
2840a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static uint32_t GetProbe(uint32_t hash, uint32_t number, uint32_t size) {
2841a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    ASSERT(IsPowerOf2(size));
2842a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return (hash + GetProbeOffset(number)) & (size - 1);
2843a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2844a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2845e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  static uint32_t FirstProbe(uint32_t hash, uint32_t size) {
2846e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    return hash & (size - 1);
2847e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  }
2848e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
2849e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  static uint32_t NextProbe(uint32_t last, uint32_t number, uint32_t size) {
2850e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    return (last + number) & (size - 1);
2851e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  }
2852e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
28533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Rehashes this hash-table into the new table.
28543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  MUST_USE_RESULT MaybeObject* Rehash(HashTable* new_table, Key key);
28553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
28563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Attempt to shrink hash table after removal of key.
28573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  MUST_USE_RESULT MaybeObject* Shrink(Key key);
28583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
2859a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Ensure enough space for n additional elements.
28605913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* EnsureCapacity(int n, Key key);
2861a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
2862a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2863a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2864a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// HashTableKey is an abstract superclass for virtual key behavior.
2865a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass HashTableKey {
2866a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
2867a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Returns whether the other object matches this key.
2868a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  virtual bool IsMatch(Object* other) = 0;
2869a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Returns the hash value for this key.
2870a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  virtual uint32_t Hash() = 0;
2871a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Returns the hash value for object.
2872a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  virtual uint32_t HashForObject(Object* key) = 0;
28733ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // Returns the key object for storing into the hash table.
2874a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // If allocations fails a failure object is returned.
28755913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT virtual MaybeObject* AsObject() = 0;
2876a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Required.
2877a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  virtual ~HashTableKey() {}
2878a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
2879a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2880c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch
2881c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdochclass SymbolTableShape : public BaseShape<HashTableKey*> {
2882a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
288344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  static inline bool IsMatch(HashTableKey* key, Object* value) {
2884a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return key->IsMatch(value);
2885a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
288644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  static inline uint32_t Hash(HashTableKey* key) {
2887a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return key->Hash();
2888a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
288944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  static inline uint32_t HashForObject(HashTableKey* key, Object* object) {
2890a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return key->HashForObject(object);
2891a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
289244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  MUST_USE_RESULT static inline MaybeObject* AsObject(HashTableKey* key) {
2893a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return key->AsObject();
2894a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2895a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2896a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kPrefixSize = 0;
2897a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kEntrySize = 1;
2898a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
2899a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2900257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochclass SeqAsciiString;
2901257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
2902a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SymbolTable.
2903a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
2904a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// No special elements in the prefix and the element size is 1
2905a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// because only the symbol itself (the key) needs to be stored.
2906a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass SymbolTable: public HashTable<SymbolTableShape, HashTableKey*> {
2907a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
2908a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Find symbol in the symbol table.  If it is not there yet, it is
2909a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // added.  The return value is the symbol table which might have
2910a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // been enlarged.  If the return value is not a failure, the symbol
2911a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // pointer *s is set to the symbol found.
29125913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* LookupSymbol(Vector<const char> str, Object** s);
29139fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  MUST_USE_RESULT MaybeObject* LookupAsciiSymbol(Vector<const char> str,
29149fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block                                                 Object** s);
2915257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  MUST_USE_RESULT MaybeObject* LookupSubStringAsciiSymbol(
2916257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      Handle<SeqAsciiString> str,
2917257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      int from,
2918257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      int length,
2919257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      Object** s);
29209fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  MUST_USE_RESULT MaybeObject* LookupTwoByteSymbol(Vector<const uc16> str,
29219fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block                                                   Object** s);
29225913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* LookupString(String* key, Object** s);
2923a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2924a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Looks up a symbol that is equal to the given string and returns
2925a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // true if it is found, assigning the symbol to the given output
2926a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // parameter.
2927a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool LookupSymbolIfExists(String* str, String** symbol);
2928d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  bool LookupTwoCharsSymbolIfExists(uint32_t c1, uint32_t c2, String** symbol);
2929a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2930a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Casting.
2931a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline SymbolTable* cast(Object* obj);
2932a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2933a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
29345913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* LookupKey(HashTableKey* key, Object** s);
2935a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2936a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DISALLOW_IMPLICIT_CONSTRUCTORS(SymbolTable);
2937a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
2938a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2939a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2940c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdochclass MapCacheShape : public BaseShape<HashTableKey*> {
2941a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
294244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  static inline bool IsMatch(HashTableKey* key, Object* value) {
2943a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return key->IsMatch(value);
2944a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
294544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  static inline uint32_t Hash(HashTableKey* key) {
2946a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return key->Hash();
2947a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2948a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
294944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  static inline uint32_t HashForObject(HashTableKey* key, Object* object) {
2950a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return key->HashForObject(object);
2951a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2952a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
295344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  MUST_USE_RESULT static inline MaybeObject* AsObject(HashTableKey* key) {
2954a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return key->AsObject();
2955a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2956a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2957a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kPrefixSize = 0;
2958a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kEntrySize = 2;
2959a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
2960a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2961a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2962a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// MapCache.
2963a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
2964a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Maps keys that are a fixed array of symbols to a map.
2965a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Used for canonicalize maps for object literals.
2966a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass MapCache: public HashTable<MapCacheShape, HashTableKey*> {
2967a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
2968a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Find cached value for a string key, otherwise return null.
2969a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* Lookup(FixedArray* key);
29705913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* Put(FixedArray* key, Map* value);
2971a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline MapCache* cast(Object* obj);
2972a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2973a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
2974a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DISALLOW_IMPLICIT_CONSTRUCTORS(MapCache);
2975a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
2976a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2977a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2978a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocktemplate <typename Shape, typename Key>
2979a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass Dictionary: public HashTable<Shape, Key> {
2980a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
2981a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline Dictionary<Shape, Key>* cast(Object* obj) {
2982a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return reinterpret_cast<Dictionary<Shape, Key>*>(obj);
2983a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2984a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2985a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Returns the value at entry.
2986a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* ValueAt(int entry) {
29873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return this->get(HashTable<Shape, Key>::EntryToIndex(entry) + 1);
2988a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2989a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2990a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Set the value for entry.
29913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void ValueAtPut(int entry, Object* value) {
2992e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    this->set(HashTable<Shape, Key>::EntryToIndex(entry) + 1, value);
2993a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2994a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2995a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Returns the property details for the property at entry.
2996a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  PropertyDetails DetailsAt(int entry) {
2997a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    ASSERT(entry >= 0);  // Not found is -1, which is not caught by get().
2998a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return PropertyDetails(
29996ded16be15dd865a9b21ea304d5273c8be299c87Steve Block        Smi::cast(this->get(HashTable<Shape, Key>::EntryToIndex(entry) + 2)));
3000a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
3001a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3002a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Set the details for entry.
3003a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void DetailsAtPut(int entry, PropertyDetails value) {
30046ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    this->set(HashTable<Shape, Key>::EntryToIndex(entry) + 2, value.AsSmi());
3005a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
3006a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3007a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Sorting support
3008a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void CopyValuesTo(FixedArray* elements);
3009a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3010a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Delete a property from the dictionary.
3011a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* DeleteProperty(int entry, JSObject::DeleteMode mode);
3012a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
30133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Attempt to shrink the dictionary after deletion of key.
30143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  MUST_USE_RESULT MaybeObject* Shrink(Key key);
30153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
3016a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Returns the number of elements in the dictionary filtering out properties
3017a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // with the specified attributes.
3018a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int NumberOfElementsFilterAttributes(PropertyAttributes filter);
3019a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3020a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Returns the number of enumerable elements in the dictionary.
3021a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int NumberOfEnumElements();
3022a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
30233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  enum SortMode { UNSORTED, SORTED };
3024a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Copies keys to preallocated fixed array.
30253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  void CopyKeysTo(FixedArray* storage,
30263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                  PropertyAttributes filter,
30273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                  SortMode sort_mode);
3028a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Fill in details for properties into storage.
30293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  void CopyKeysTo(FixedArray* storage, int index, SortMode sort_mode);
3030a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3031a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Accessors for next enumeration index.
3032a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void SetNextEnumerationIndex(int index) {
30333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    this->set(kNextEnumerationIndexIndex, Smi::FromInt(index));
3034a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
3035a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3036a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int NextEnumerationIndex() {
3037a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return Smi::cast(FixedArray::get(kNextEnumerationIndexIndex))->value();
3038a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
3039a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3040a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Returns a new array for dictionary usage. Might return Failure.
30415913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT static MaybeObject* Allocate(int at_least_space_for);
3042a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3043a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Ensure enough space for n additional elements.
30445913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* EnsureCapacity(int n, Key key);
3045a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3046b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef OBJECT_PRINT
3047b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  inline void Print() {
3048b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    Print(stdout);
3049b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
3050b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void Print(FILE* out);
3051a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
3052a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Returns the key (slow).
3053a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* SlowReverseLookup(Object* value);
3054a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3055a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Sets the entry to (key, value) pair.
3056a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void SetEntry(int entry,
3057a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                       Object* key,
30588b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch                       Object* value);
30598b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  inline void SetEntry(int entry,
30608b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch                       Object* key,
3061a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                       Object* value,
3062a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                       PropertyDetails details);
3063a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
30645913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* Add(Key key,
30655913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck                                   Object* value,
30665913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck                                   PropertyDetails details);
3067a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3068a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block protected:
3069a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Generic at put operation.
30705913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* AtPut(Key key, Object* value);
3071a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3072a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Add entry to dictionary.
30735913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* AddEntry(Key key,
30745913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck                                        Object* value,
30755913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck                                        PropertyDetails details,
30765913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck                                        uint32_t hash);
3077a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3078a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Generate new enumeration indices to avoid enumeration index overflow.
30795913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* GenerateNewEnumerationIndices();
3080a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kMaxNumberKeyIndex =
3081a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      HashTable<Shape, Key>::kPrefixStartIndex;
3082a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kNextEnumerationIndexIndex = kMaxNumberKeyIndex + 1;
3083a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
3084a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3085a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3086c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdochclass StringDictionaryShape : public BaseShape<String*> {
3087a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
3088a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline bool IsMatch(String* key, Object* other);
3089a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline uint32_t Hash(String* key);
3090a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline uint32_t HashForObject(String* key, Object* object);
30915913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT static inline MaybeObject* AsObject(String* key);
3092a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kPrefixSize = 2;
3093a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kEntrySize = 3;
3094a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const bool kIsEnumerable = true;
3095a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
3096a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3097a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3098a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass StringDictionary: public Dictionary<StringDictionaryShape, String*> {
3099a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
3100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline StringDictionary* cast(Object* obj) {
3101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    ASSERT(obj->IsDictionary());
3102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return reinterpret_cast<StringDictionary*>(obj);
3103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
3104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Copies enumerable keys to preallocated fixed array.
3106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void CopyEnumKeysTo(FixedArray* storage, FixedArray* sort_array);
3107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // For transforming properties of a JSObject.
31095913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* TransformPropertiesToFastFor(
31105913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      JSObject* obj,
31115913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      int unused_property_fields);
31123bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch
31133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Find entry for key, otherwise return kNotFound. Optimized version of
31143bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  // HashTable::FindEntry.
31153bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  int FindEntry(String* key);
31163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
31173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool ContainsTransition(int entry);
3118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
3119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3121c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdochclass NumberDictionaryShape : public BaseShape<uint32_t> {
3122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
3123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline bool IsMatch(uint32_t key, Object* other);
31245913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT static inline MaybeObject* AsObject(uint32_t key);
3125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kEntrySize = 3;
3126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const bool kIsEnumerable = false;
3127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
3128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3130c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdochclass SeededNumberDictionaryShape : public NumberDictionaryShape {
3131c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch public:
3132c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch  static const bool UsesSeed = true;
3133c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch  static const int kPrefixSize = 2;
3134c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch
3135c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch  static inline uint32_t SeededHash(uint32_t key, uint32_t seed);
3136c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch  static inline uint32_t SeededHashForObject(uint32_t key,
3137c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch                                             uint32_t seed,
3138c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch                                             Object* object);
3139c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch};
3140c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch
3141c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch
3142c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdochclass UnseededNumberDictionaryShape : public NumberDictionaryShape {
31432b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch public:
3144c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch  static const int kPrefixSize = 0;
3145c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch
3146c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch  static inline uint32_t Hash(uint32_t key);
3147c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch  static inline uint32_t HashForObject(uint32_t key, Object* object);
3148c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch};
3149c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch
3150c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch
3151c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdochclass SeededNumberDictionary
3152c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch    : public Dictionary<SeededNumberDictionaryShape, uint32_t> {
3153c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch public:
3154c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch  static SeededNumberDictionary* cast(Object* obj) {
3155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    ASSERT(obj->IsDictionary());
3156c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch    return reinterpret_cast<SeededNumberDictionary*>(obj);
3157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
3158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Type specific at put (default NONE attributes is used when adding).
31605913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* AtNumberPut(uint32_t key, Object* value);
31615913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* AddNumberEntry(uint32_t key,
31625913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck                                              Object* value,
31635913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck                                              PropertyDetails details);
3164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Set an existing entry or add a new one if needed.
31663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Return the updated dictionary.
31673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT static Handle<SeededNumberDictionary> Set(
31683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Handle<SeededNumberDictionary> dictionary,
31693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      uint32_t index,
31703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Handle<Object> value,
31713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      PropertyDetails details);
31723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
31735913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* Set(uint32_t key,
31745913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck                                   Object* value,
31755913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck                                   PropertyDetails details);
3176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void UpdateMaxNumberKey(uint32_t key);
3178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // If slow elements are required we will never go back to fast-case
3180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // for the elements kept in this dictionary.  We require slow
3181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // elements if an element has been added at an index larger than
3182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // kRequiresSlowElementsLimit or set_requires_slow_elements() has been called
3183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // when defining a getter or setter with a number key.
3184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline bool requires_slow_elements();
3185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void set_requires_slow_elements();
3186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Get the value of the max number key that has been added to this
3188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // dictionary.  max_number_key can only be called if
3189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // requires_slow_elements returns false.
3190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline uint32_t max_number_key();
3191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Bit masks.
3193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kRequiresSlowElementsMask = 1;
3194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kRequiresSlowElementsTagSize = 1;
3195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const uint32_t kRequiresSlowElementsLimit = (1 << 29) - 1;
3196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
3197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3199c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdochclass UnseededNumberDictionary
3200c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch    : public Dictionary<UnseededNumberDictionaryShape, uint32_t> {
3201c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch public:
3202c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch  static UnseededNumberDictionary* cast(Object* obj) {
3203c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch    ASSERT(obj->IsDictionary());
3204c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch    return reinterpret_cast<UnseededNumberDictionary*>(obj);
3205c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch  }
3206c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch
3207c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch  // Type specific at put (default NONE attributes is used when adding).
3208c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch  MUST_USE_RESULT MaybeObject* AtNumberPut(uint32_t key, Object* value);
3209c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch  MUST_USE_RESULT MaybeObject* AddNumberEntry(uint32_t key, Object* value);
3210c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch
3211c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch  // Set an existing entry or add a new one if needed.
32123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Return the updated dictionary.
32133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT static Handle<UnseededNumberDictionary> Set(
32143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Handle<UnseededNumberDictionary> dictionary,
32153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      uint32_t index,
32163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Handle<Object> value);
32173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3218c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch  MUST_USE_RESULT MaybeObject* Set(uint32_t key, Object* value);
3219c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch};
3220c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch
3221c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch
32223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochtemplate <int entrysize>
3223c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdochclass ObjectHashTableShape : public BaseShape<Object*> {
32242b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch public:
32253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static inline bool IsMatch(Object* key, Object* other);
32263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static inline uint32_t Hash(Object* key);
32273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static inline uint32_t HashForObject(Object* key, Object* object);
32283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT static inline MaybeObject* AsObject(Object* key);
3229592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch  static const int kPrefixSize = 0;
32303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kEntrySize = entrysize;
323169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch};
323269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
323369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
32343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// ObjectHashSet holds keys that are arbitrary objects by using the identity
32353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// hash of the key for hashing purposes.
32363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochclass ObjectHashSet: public HashTable<ObjectHashTableShape<1>, Object*> {
32373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public:
32383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static inline ObjectHashSet* cast(Object* obj) {
32393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    ASSERT(obj->IsHashTable());
32403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return reinterpret_cast<ObjectHashSet*>(obj);
32413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
32423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
32433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Looks up whether the given key is part of this hash set.
32443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool Contains(Object* key);
32453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
32463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Adds the given key to this hash set.
32473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT MaybeObject* Add(Object* key);
32483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
32493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Removes the given key from this hash set.
32503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT MaybeObject* Remove(Object* key);
32513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch};
32523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
32533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
32543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// ObjectHashTable maps keys that are arbitrary objects to object values by
325569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// using the identity hash of the key for hashing purposes.
32563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochclass ObjectHashTable: public HashTable<ObjectHashTableShape<2>, Object*> {
325769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch public:
325869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  static inline ObjectHashTable* cast(Object* obj) {
325969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    ASSERT(obj->IsHashTable());
326069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    return reinterpret_cast<ObjectHashTable*>(obj);
326169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  }
326269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
326369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  // Looks up the value associated with the given key. The undefined value is
326469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  // returned in case the key is not present.
32653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Object* Lookup(Object* key);
326669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
326769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  // Adds (or overwrites) the value associated with the given key. Mapping a
326869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  // key to the undefined value causes removal of the whole entry.
32693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT MaybeObject* Put(Object* key, Object* value);
327069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
327169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch private:
327269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  friend class MarkCompactCollector;
327369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
32743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void AddEntry(int entry, Object* key, Object* value);
32753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void RemoveEntry(int entry);
327669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
327769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  // Returns the index to the value of an entry.
327869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  static inline int EntryToValueIndex(int entry) {
327969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    return EntryToIndex(entry) + 1;
328069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  }
328169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch};
328269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
328369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
32846ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// JSFunctionResultCache caches results of some JSFunction invocation.
32856ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// It is a fixed array with fixed structure:
32866ded16be15dd865a9b21ea304d5273c8be299c87Steve Block//   [0]: factory function
32876ded16be15dd865a9b21ea304d5273c8be299c87Steve Block//   [1]: finger index
32886ded16be15dd865a9b21ea304d5273c8be299c87Steve Block//   [2]: current cache size
32896ded16be15dd865a9b21ea304d5273c8be299c87Steve Block//   [3]: dummy field.
32906ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// The rest of array are key/value pairs.
32916ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockclass JSFunctionResultCache: public FixedArray {
32926ded16be15dd865a9b21ea304d5273c8be299c87Steve Block public:
32936ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static const int kFactoryIndex = 0;
32946ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static const int kFingerIndex = kFactoryIndex + 1;
32956ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static const int kCacheSizeIndex = kFingerIndex + 1;
32966ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static const int kDummyIndex = kCacheSizeIndex + 1;
32976ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static const int kEntriesIndex = kDummyIndex + 1;
32986ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
32996ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static const int kEntrySize = 2;  // key + value
33006ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
330125f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen  static const int kFactoryOffset = kHeaderSize;
330225f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen  static const int kFingerOffset = kFactoryOffset + kPointerSize;
330325f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen  static const int kCacheSizeOffset = kFingerOffset + kPointerSize;
330425f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen
33056ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  inline void MakeZeroSize();
33066ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  inline void Clear();
33076ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
3308b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  inline int size();
3309b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  inline void set_size(int size);
3310b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  inline int finger_index();
3311b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  inline void set_finger_index(int finger_index);
3312b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
33136ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Casting
33146ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static inline JSFunctionResultCache* cast(Object* obj);
33156ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
33166ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#ifdef DEBUG
33176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void JSFunctionResultCacheVerify();
33186ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#endif
33196ded16be15dd865a9b21ea304d5273c8be299c87Steve Block};
33206ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
33216ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
33223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// ScopeInfo represents information about different scopes of a source
33233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// program  and the allocation of the scope's variables. Scope information
33243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// is stored in a compressed form in ScopeInfo objects and is used
33253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// at runtime (stack dumps, deoptimization, etc.).
33263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
33273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// This object provides quick access to scope info details for runtime
33283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// routines.
33293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochclass ScopeInfo : public FixedArray {
33303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public:
33313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static inline ScopeInfo* cast(Object* object);
33323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
33333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Return the type of this scope.
33343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ScopeType Type();
33353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
33363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Does this scope call eval?
33373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool CallsEval();
33383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
33393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Return the language mode of this scope.
33403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  LanguageMode language_mode();
33413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
33423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Does this scope make a non-strict eval call?
33433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool CallsNonStrictEval() {
33443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return CallsEval() && (language_mode() == CLASSIC_MODE);
33453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
33463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
33473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Return the total number of locals allocated on the stack and in the
33483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // context. This includes the parameters that are allocated in the context.
33493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int LocalCount();
33503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
33513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Return the number of stack slots for code. This number consists of two
33523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // parts:
33533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //  1. One stack slot per stack allocated local.
33543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //  2. One stack slot for the function name if it is stack allocated.
33553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int StackSlotCount();
33563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
33573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Return the number of context slots for code if a context is allocated. This
33583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // number consists of three parts:
33593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //  1. Size of fixed header for every context: Context::MIN_CONTEXT_SLOTS
33603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //  2. One context slot per context allocated local.
33613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //  3. One context slot for the function name if it is context allocated.
33623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Parameters allocated in the context count as context allocated locals. If
33633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // no contexts are allocated for this scope ContextLength returns 0.
33643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int ContextLength();
33653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
33663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Is this scope the scope of a named function expression?
33673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool HasFunctionName();
33683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
33693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Return if this has context allocated locals.
33703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool HasHeapAllocatedLocals();
33713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
33723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Return if contexts are allocated for this scope.
33733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool HasContext();
33743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
33753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Return the function_name if present.
33763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  String* FunctionName();
33773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
33783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Return the name of the given parameter.
33793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  String* ParameterName(int var);
33803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
33813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Return the name of the given local.
33823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  String* LocalName(int var);
33833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
33843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Return the name of the given stack local.
33853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  String* StackLocalName(int var);
33863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
33873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Return the name of the given context local.
33883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  String* ContextLocalName(int var);
33893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
33903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Return the mode of the given context local.
33913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  VariableMode ContextLocalMode(int var);
33923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
33933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Return the initialization flag of the given context local.
33943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  InitializationFlag ContextLocalInitFlag(int var);
33953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
33963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Lookup support for serialized scope info. Returns the
33973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // the stack slot index for a given slot name if the slot is
33983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // present; otherwise returns a value < 0. The name must be a symbol
33993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // (canonicalized).
34003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int StackSlotIndex(String* name);
34013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
34023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Lookup support for serialized scope info. Returns the
34033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // context slot index for a given slot name if the slot is present; otherwise
34043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // returns a value < 0. The name must be a symbol (canonicalized).
34053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // If the slot is present and mode != NULL, sets *mode to the corresponding
34063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // mode for that variable.
34073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int ContextSlotIndex(String* name,
34083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                       VariableMode* mode,
34093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                       InitializationFlag* init_flag);
34103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
34113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Lookup support for serialized scope info. Returns the
34123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // parameter index for a given parameter name if the parameter is present;
34133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // otherwise returns a value < 0. The name must be a symbol (canonicalized).
34143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int ParameterIndex(String* name);
34153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
34163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Lookup support for serialized scope info. Returns the
34173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // function context slot index if the function name is present (named
34183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // function expressions, only), otherwise returns a value < 0. The name
34193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // must be a symbol (canonicalized).
34203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int FunctionContextSlotIndex(String* name, VariableMode* mode);
34213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
34223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static Handle<ScopeInfo> Create(Scope* scope);
34233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
34243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Serializes empty scope info.
34253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static ScopeInfo* Empty();
34263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
34273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#ifdef DEBUG
34283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void Print();
34293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif
34303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
34313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // The layout of the static part of a ScopeInfo is as follows. Each entry is
34323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // numeric and occupies one array slot.
34333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // 1. A set of properties of the scope
34343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // 2. The number of parameters. This only applies to function scopes. For
34353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //    non-function scopes this is 0.
34363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // 3. The number of non-parameter variables allocated on the stack.
34373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // 4. The number of non-parameter and parameter variables allocated in the
34383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //    context.
34393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#define FOR_EACH_NUMERIC_FIELD(V)          \
34403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  V(Flags)                                 \
34413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  V(ParameterCount)                        \
34423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  V(StackLocalCount)                       \
34433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  V(ContextLocalCount)
34443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
34453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#define FIELD_ACCESSORS(name)                            \
34463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void Set##name(int value) {                            \
34473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    set(k##name, Smi::FromInt(value));                   \
34483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }                                                      \
34493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int name() {                                           \
34503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (length() > 0) {                                  \
34513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      return Smi::cast(get(k##name))->value();           \
34523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    } else {                                             \
34533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      return 0;                                          \
34543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }                                                    \
34553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
34563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  FOR_EACH_NUMERIC_FIELD(FIELD_ACCESSORS)
34573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#undef FIELD_ACCESSORS
34583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
34593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch private:
34603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  enum {
34613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#define DECL_INDEX(name) k##name,
34623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  FOR_EACH_NUMERIC_FIELD(DECL_INDEX)
34633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#undef DECL_INDEX
34643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#undef FOR_EACH_NUMERIC_FIELD
34653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  kVariablePartIndex
34663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  };
34673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
34683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // The layout of the variable part of a ScopeInfo is as follows:
34693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // 1. ParameterEntries:
34703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //    This part stores the names of the parameters for function scopes. One
34713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //    slot is used per parameter, so in total this part occupies
34723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //    ParameterCount() slots in the array. For other scopes than function
34733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //    scopes ParameterCount() is 0.
34743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // 2. StackLocalEntries:
34753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //    Contains the names of local variables that are allocated on the stack,
34763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //    in increasing order of the stack slot index. One slot is used per stack
34773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //    local, so in total this part occupies StackLocalCount() slots in the
34783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //    array.
34793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // 3. ContextLocalNameEntries:
34803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //    Contains the names of local variables and parameters that are allocated
34813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //    in the context. They are stored in increasing order of the context slot
34823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //    index starting with Context::MIN_CONTEXT_SLOTS. One slot is used per
34833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //    context local, so in total this part occupies ContextLocalCount() slots
34843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //    in the array.
34853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // 4. ContextLocalInfoEntries:
34863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //    Contains the variable modes and initialization flags corresponding to
34873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //    the context locals in ContextLocalNameEntries. One slot is used per
34883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //    context local, so in total this part occupies ContextLocalCount()
34893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //    slots in the array.
34903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // 5. FunctionNameEntryIndex:
34913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //    If the scope belongs to a named function expression this part contains
34923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //    information about the function variable. It always occupies two array
34933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //    slots:  a. The name of the function variable.
34943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //            b. The context or stack slot index for the variable.
34953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int ParameterEntriesIndex();
34963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int StackLocalEntriesIndex();
34973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int ContextLocalNameEntriesIndex();
34983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int ContextLocalInfoEntriesIndex();
34993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int FunctionNameEntryIndex();
35003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
35013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Location of the function variable for named function expressions.
35023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  enum FunctionVariableInfo {
35033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    NONE,     // No function name present.
35043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    STACK,    // Function
35053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    CONTEXT,
35063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    UNUSED
35073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  };
35083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
35093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Properties of scopes.
35103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  class TypeField:             public BitField<ScopeType,            0, 3> {};
35113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  class CallsEvalField:        public BitField<bool,                 3, 1> {};
35123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  class LanguageModeField:     public BitField<LanguageMode,         4, 2> {};
35133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  class FunctionVariableField: public BitField<FunctionVariableInfo, 6, 2> {};
35143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  class FunctionVariableMode:  public BitField<VariableMode,         8, 3> {};
35153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
35163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // BitFields representing the encoded information for context locals in the
35173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // ContextLocalInfoEntries part.
35183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  class ContextLocalMode:      public BitField<VariableMode,         0, 3> {};
35193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  class ContextLocalInitFlag:  public BitField<InitializationFlag,   3, 1> {};
35203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch};
35213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
35223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
352380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// The cache for maps used by normalized (dictionary mode) objects.
352480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// Such maps do not have property descriptors, so a typical program
352580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// needs very limited number of distinct normalized maps.
352680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenclass NormalizedMapCache: public FixedArray {
352780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen public:
352880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  static const int kEntries = 64;
352980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
35305913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* Get(JSObject* object,
35315913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck                                   PropertyNormalizationMode mode);
353280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
353380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  void Clear();
353480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
353580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  // Casting
353680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  static inline NormalizedMapCache* cast(Object* obj);
353780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
353880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen#ifdef DEBUG
353980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  void NormalizedMapCacheVerify();
354080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen#endif
354180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen};
354280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
354380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
35443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// ByteArray represents fixed sized byte arrays.  Used for the relocation info
35453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// that is attached to code objects.
354669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochclass ByteArray: public FixedArrayBase {
3547a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
35483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline int Size() { return RoundUp(length() + kHeaderSize, kPointerSize); }
35493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3550a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Setter and getter.
3551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline byte get(int index);
3552a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void set(int index, byte value);
3553a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3554a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Treat contents as an int array.
3555a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline int get_int(int index);
3556a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3557a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static int SizeFor(int length) {
35587f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    return OBJECT_POINTER_ALIGN(kHeaderSize + length);
3559a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
3560a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // We use byte arrays for free blocks in the heap.  Given a desired size in
3561a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // bytes that is a multiple of the word size and big enough to hold a byte
3562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // array, this function returns the number of elements a byte array should
3563a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // have.
3564a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static int LengthFor(int size_in_bytes) {
3565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    ASSERT(IsAligned(size_in_bytes, kPointerSize));
3566a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    ASSERT(size_in_bytes >= kHeaderSize);
3567a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return size_in_bytes - kHeaderSize;
3568a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
3569a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3570a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Returns data start address.
3571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline Address GetDataStartAddress();
3572a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3573a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Returns a pointer to the ByteArray object for a given data start address.
3574a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline ByteArray* FromDataStartAddress(Address address);
3575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3576a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Casting.
3577a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline ByteArray* cast(Object* obj);
3578a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3579a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Dispatched behavior.
3580756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  inline int ByteArraySize() {
3581756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick    return SizeFor(this->length());
3582756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  }
3583b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef OBJECT_PRINT
3584b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  inline void ByteArrayPrint() {
3585b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    ByteArrayPrint(stdout);
3586b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
3587b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void ByteArrayPrint(FILE* out);
3588b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif
3589a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG
3590a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void ByteArrayVerify();
3591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
3592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
35937f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // Layout description.
35947f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  static const int kAlignedSize = OBJECT_POINTER_ALIGN(kHeaderSize);
3595a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3596e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Maximal memory consumption for a single ByteArray.
3597e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  static const int kMaxSize = 512 * MB;
3598e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Maximal length of a single ByteArray.
3599e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  static const int kMaxLength = kMaxSize - kHeaderSize;
3600e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
3601a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
3602a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DISALLOW_IMPLICIT_CONSTRUCTORS(ByteArray);
3603a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
3604a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3605a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
36063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// FreeSpace represents fixed sized areas of the heap that are not currently in
36073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// use.  Used by the heap and GC.
36083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochclass FreeSpace: public HeapObject {
36093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public:
36103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // [size]: size of the free space including the header.
36113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline int size();
36123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline void set_size(int value);
36133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
36143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline int Size() { return size(); }
36153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
36163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Casting.
36173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static inline FreeSpace* cast(Object* obj);
36183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
36193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#ifdef OBJECT_PRINT
36203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline void FreeSpacePrint() {
36213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    FreeSpacePrint(stdout);
36223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
36233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void FreeSpacePrint(FILE* out);
36243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif
36253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#ifdef DEBUG
36263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void FreeSpaceVerify();
36273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif
36283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
36293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Layout description.
36303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Size is smi tagged when it is stored.
36313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kSizeOffset = HeapObject::kHeaderSize;
36323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kHeaderSize = kSizeOffset + kPointerSize;
36333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
36343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kAlignedSize = OBJECT_POINTER_ALIGN(kHeaderSize);
36353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
36363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch private:
36373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  DISALLOW_IMPLICIT_CONSTRUCTORS(FreeSpace);
36383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch};
36393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
36403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
36413ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// An ExternalArray represents a fixed-size array of primitive values
36423ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// which live outside the JavaScript heap. Its subclasses are used to
36433ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// implement the CanvasArray types being defined in the WebGL
36443ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// specification. As of this writing the first public draft is not yet
36453ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// available, but Khronos members can access the draft at:
36463ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block//   https://cvs.khronos.org/svn/repos/3dweb/trunk/doc/spec/WebGL-spec.html
36473ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block//
36483ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// The semantics of these arrays differ from CanvasPixelArray.
36493ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// Out-of-range values passed to the setter are converted via a C
36503ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// cast, not clamping. Out-of-range indices cause exceptions to be
36513ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// raised rather than being silently ignored.
365269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochclass ExternalArray: public FixedArrayBase {
36533ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block public:
365469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  inline bool is_the_hole(int index) { return false; }
36557f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
36563ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // [external_pointer]: The pointer to the external memory area backing this
36573ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // external array.
36583ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  DECL_ACCESSORS(external_pointer, void)  // Pointer to the data store.
36593ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
36603ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // Casting.
36613ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  static inline ExternalArray* cast(Object* obj);
36623ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
36633ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // Maximal acceptable length for an external array.
36643ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  static const int kMaxLength = 0x3fffffff;
36653ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
36663ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // ExternalArray headers are not quadword aligned.
36677f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  static const int kExternalPointerOffset =
366869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch      POINTER_SIZE_ALIGN(FixedArrayBase::kLengthOffset + kPointerSize);
36693ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  static const int kHeaderSize = kExternalPointerOffset + kPointerSize;
36707f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  static const int kAlignedSize = OBJECT_POINTER_ALIGN(kHeaderSize);
36713ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
36723ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block private:
36733ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalArray);
36743ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block};
36753ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
36763ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
367744f0eee88ff00398ff7f715fab053374d808c90dSteve Block// A ExternalPixelArray represents a fixed-size byte array with special
367844f0eee88ff00398ff7f715fab053374d808c90dSteve Block// semantics used for implementing the CanvasPixelArray object. Please see the
367944f0eee88ff00398ff7f715fab053374d808c90dSteve Block// specification at:
368044f0eee88ff00398ff7f715fab053374d808c90dSteve Block
368144f0eee88ff00398ff7f715fab053374d808c90dSteve Block// http://www.whatwg.org/specs/web-apps/current-work/
368244f0eee88ff00398ff7f715fab053374d808c90dSteve Block//                      multipage/the-canvas-element.html#canvaspixelarray
368344f0eee88ff00398ff7f715fab053374d808c90dSteve Block// In particular, write access clamps the value written to 0 or 255 if the
368444f0eee88ff00398ff7f715fab053374d808c90dSteve Block// value written is outside this range.
368544f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass ExternalPixelArray: public ExternalArray {
368644f0eee88ff00398ff7f715fab053374d808c90dSteve Block public:
368744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  inline uint8_t* external_pixel_pointer();
368844f0eee88ff00398ff7f715fab053374d808c90dSteve Block
368944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Setter and getter.
369069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  inline uint8_t get_scalar(int index);
36913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT inline MaybeObject* get(int index);
369244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  inline void set(int index, uint8_t value);
369344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
369444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // This accessor applies the correct conversion from Smi, HeapNumber and
369544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // undefined and clamps the converted value between 0 and 255.
369644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Object* SetValue(uint32_t index, Object* value);
369744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
369844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Casting.
369944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  static inline ExternalPixelArray* cast(Object* obj);
370044f0eee88ff00398ff7f715fab053374d808c90dSteve Block
370144f0eee88ff00398ff7f715fab053374d808c90dSteve Block#ifdef OBJECT_PRINT
370244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  inline void ExternalPixelArrayPrint() {
370344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    ExternalPixelArrayPrint(stdout);
370444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
370544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void ExternalPixelArrayPrint(FILE* out);
370644f0eee88ff00398ff7f715fab053374d808c90dSteve Block#endif
370744f0eee88ff00398ff7f715fab053374d808c90dSteve Block#ifdef DEBUG
370844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void ExternalPixelArrayVerify();
370944f0eee88ff00398ff7f715fab053374d808c90dSteve Block#endif  // DEBUG
371044f0eee88ff00398ff7f715fab053374d808c90dSteve Block
371144f0eee88ff00398ff7f715fab053374d808c90dSteve Block private:
371244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalPixelArray);
371344f0eee88ff00398ff7f715fab053374d808c90dSteve Block};
371444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
371544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
37163ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockclass ExternalByteArray: public ExternalArray {
37173ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block public:
37183ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // Setter and getter.
371969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  inline int8_t get_scalar(int index);
37203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT inline MaybeObject* get(int index);
37213ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  inline void set(int index, int8_t value);
37223ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
37233ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // This accessor applies the correct conversion from Smi, HeapNumber
37243ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // and undefined.
37253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT MaybeObject* SetValue(uint32_t index, Object* value);
37263ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
37273ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // Casting.
37283ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  static inline ExternalByteArray* cast(Object* obj);
37293ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
3730b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef OBJECT_PRINT
3731b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  inline void ExternalByteArrayPrint() {
3732b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    ExternalByteArrayPrint(stdout);
3733b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
3734b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void ExternalByteArrayPrint(FILE* out);
3735b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif
37363ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block#ifdef DEBUG
37373ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  void ExternalByteArrayVerify();
37383ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block#endif  // DEBUG
37393ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
37403ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block private:
37413ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalByteArray);
37423ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block};
37433ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
37443ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
37453ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockclass ExternalUnsignedByteArray: public ExternalArray {
37463ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block public:
37473ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // Setter and getter.
374869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  inline uint8_t get_scalar(int index);
37493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT inline MaybeObject* get(int index);
37503ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  inline void set(int index, uint8_t value);
37513ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
37523ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // This accessor applies the correct conversion from Smi, HeapNumber
37533ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // and undefined.
37543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT MaybeObject* SetValue(uint32_t index, Object* value);
37553ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
37563ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // Casting.
37573ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  static inline ExternalUnsignedByteArray* cast(Object* obj);
37583ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
3759b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef OBJECT_PRINT
3760b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  inline void ExternalUnsignedByteArrayPrint() {
3761b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    ExternalUnsignedByteArrayPrint(stdout);
3762b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
3763b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void ExternalUnsignedByteArrayPrint(FILE* out);
3764b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif
37653ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block#ifdef DEBUG
37663ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  void ExternalUnsignedByteArrayVerify();
37673ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block#endif  // DEBUG
37683ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
37693ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block private:
37703ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalUnsignedByteArray);
37713ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block};
37723ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
37733ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
37743ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockclass ExternalShortArray: public ExternalArray {
37753ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block public:
37763ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // Setter and getter.
377769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  inline int16_t get_scalar(int index);
37783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT inline MaybeObject* get(int index);
37793ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  inline void set(int index, int16_t value);
37803ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
37813ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // This accessor applies the correct conversion from Smi, HeapNumber
37823ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // and undefined.
37833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT MaybeObject* SetValue(uint32_t index, Object* value);
37843ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
37853ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // Casting.
37863ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  static inline ExternalShortArray* cast(Object* obj);
37873ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
3788b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef OBJECT_PRINT
3789b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  inline void ExternalShortArrayPrint() {
3790b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    ExternalShortArrayPrint(stdout);
3791b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
3792b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void ExternalShortArrayPrint(FILE* out);
3793b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif
37943ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block#ifdef DEBUG
37953ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  void ExternalShortArrayVerify();
37963ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block#endif  // DEBUG
37973ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
37983ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block private:
37993ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalShortArray);
38003ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block};
38013ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
38023ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
38033ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockclass ExternalUnsignedShortArray: public ExternalArray {
38043ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block public:
38053ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // Setter and getter.
380669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  inline uint16_t get_scalar(int index);
38073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT inline MaybeObject* get(int index);
38083ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  inline void set(int index, uint16_t value);
38093ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
38103ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // This accessor applies the correct conversion from Smi, HeapNumber
38113ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // and undefined.
38123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT MaybeObject* SetValue(uint32_t index, Object* value);
38133ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
38143ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // Casting.
38153ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  static inline ExternalUnsignedShortArray* cast(Object* obj);
38163ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
3817b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef OBJECT_PRINT
3818b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  inline void ExternalUnsignedShortArrayPrint() {
3819b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    ExternalUnsignedShortArrayPrint(stdout);
3820b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
3821b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void ExternalUnsignedShortArrayPrint(FILE* out);
3822b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif
38233ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block#ifdef DEBUG
38243ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  void ExternalUnsignedShortArrayVerify();
38253ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block#endif  // DEBUG
38263ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
38273ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block private:
38283ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalUnsignedShortArray);
38293ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block};
38303ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
38313ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
38323ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockclass ExternalIntArray: public ExternalArray {
38333ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block public:
38343ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // Setter and getter.
383569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  inline int32_t get_scalar(int index);
38363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT inline MaybeObject* get(int index);
38373ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  inline void set(int index, int32_t value);
38383ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
38393ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // This accessor applies the correct conversion from Smi, HeapNumber
38403ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // and undefined.
38413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT MaybeObject* SetValue(uint32_t index, Object* value);
38423ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
38433ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // Casting.
38443ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  static inline ExternalIntArray* cast(Object* obj);
38453ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
3846b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef OBJECT_PRINT
3847b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  inline void ExternalIntArrayPrint() {
3848b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    ExternalIntArrayPrint(stdout);
3849b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
3850b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void ExternalIntArrayPrint(FILE* out);
3851b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif
38523ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block#ifdef DEBUG
38533ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  void ExternalIntArrayVerify();
38543ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block#endif  // DEBUG
38553ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
38563ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block private:
38573ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalIntArray);
38583ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block};
38593ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
38603ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
38613ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockclass ExternalUnsignedIntArray: public ExternalArray {
38623ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block public:
38633ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // Setter and getter.
386469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  inline uint32_t get_scalar(int index);
38653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT inline MaybeObject* get(int index);
38663ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  inline void set(int index, uint32_t value);
38673ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
38683ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // This accessor applies the correct conversion from Smi, HeapNumber
38693ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // and undefined.
38703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT MaybeObject* SetValue(uint32_t index, Object* value);
38713ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
38723ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // Casting.
38733ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  static inline ExternalUnsignedIntArray* cast(Object* obj);
38743ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
3875b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef OBJECT_PRINT
3876b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  inline void ExternalUnsignedIntArrayPrint() {
3877b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    ExternalUnsignedIntArrayPrint(stdout);
3878b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
3879b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void ExternalUnsignedIntArrayPrint(FILE* out);
3880b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif
38813ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block#ifdef DEBUG
38823ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  void ExternalUnsignedIntArrayVerify();
38833ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block#endif  // DEBUG
38843ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
38853ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block private:
38863ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalUnsignedIntArray);
38873ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block};
38883ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
38893ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
38903ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockclass ExternalFloatArray: public ExternalArray {
38913ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block public:
38923ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // Setter and getter.
389369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  inline float get_scalar(int index);
38943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT inline MaybeObject* get(int index);
38953ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  inline void set(int index, float value);
38963ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
38973ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // This accessor applies the correct conversion from Smi, HeapNumber
38983ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // and undefined.
38993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT MaybeObject* SetValue(uint32_t index, Object* value);
39003ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
39013ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // Casting.
39023ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  static inline ExternalFloatArray* cast(Object* obj);
39033ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
3904b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef OBJECT_PRINT
3905b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  inline void ExternalFloatArrayPrint() {
3906b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    ExternalFloatArrayPrint(stdout);
3907b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
3908b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void ExternalFloatArrayPrint(FILE* out);
3909b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif
39103ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block#ifdef DEBUG
39113ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  void ExternalFloatArrayVerify();
39123ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block#endif  // DEBUG
39133ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
39143ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block private:
39153ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalFloatArray);
39163ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block};
39173ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
39183ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
3919257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochclass ExternalDoubleArray: public ExternalArray {
3920257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch public:
3921257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Setter and getter.
392269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  inline double get_scalar(int index);
39233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT inline MaybeObject* get(int index);
3924257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  inline void set(int index, double value);
3925257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
3926257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // This accessor applies the correct conversion from Smi, HeapNumber
3927257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // and undefined.
39283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT MaybeObject* SetValue(uint32_t index, Object* value);
3929257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
3930257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Casting.
3931257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  static inline ExternalDoubleArray* cast(Object* obj);
3932257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
3933257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#ifdef OBJECT_PRINT
3934257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  inline void ExternalDoubleArrayPrint() {
3935257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    ExternalDoubleArrayPrint(stdout);
3936257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
3937257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void ExternalDoubleArrayPrint(FILE* out);
3938257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#endif  // OBJECT_PRINT
3939257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#ifdef DEBUG
3940257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void ExternalDoubleArrayVerify();
3941257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#endif  // DEBUG
3942257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
3943257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch private:
3944257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalDoubleArray);
3945257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch};
3946257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
3947257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
3948b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// DeoptimizationInputData is a fixed array used to hold the deoptimization
3949b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// data for code generated by the Hydrogen/Lithium compiler.  It also
3950b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// contains information about functions that were inlined.  If N different
3951b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// functions were inlined then first N elements of the literal array will
3952b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// contain these functions.
3953b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch//
3954b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// It can be empty.
3955b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass DeoptimizationInputData: public FixedArray {
3956b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
3957b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Layout description.  Indices in the array.
3958b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static const int kTranslationByteArrayIndex = 0;
3959b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static const int kInlinedFunctionCountIndex = 1;
3960b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static const int kLiteralArrayIndex = 2;
3961b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static const int kOsrAstIdIndex = 3;
3962b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static const int kOsrPcOffsetIndex = 4;
3963b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static const int kFirstDeoptEntryIndex = 5;
3964b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3965b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Offsets of deopt entry elements relative to the start of the entry.
3966b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static const int kAstIdOffset = 0;
3967b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static const int kTranslationIndexOffset = 1;
3968b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static const int kArgumentsStackHeightOffset = 2;
39692b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch  static const int kPcOffset = 3;
39702b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch  static const int kDeoptEntrySize = 4;
3971b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3972b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Simple element accessors.
3973b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#define DEFINE_ELEMENT_ACCESSORS(name, type)      \
3974b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  type* name() {                                  \
3975b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    return type::cast(get(k##name##Index));       \
3976b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }                                               \
3977b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void Set##name(type* value) {                   \
3978b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    set(k##name##Index, value);                   \
3979b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
3980b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3981b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  DEFINE_ELEMENT_ACCESSORS(TranslationByteArray, ByteArray)
3982b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  DEFINE_ELEMENT_ACCESSORS(InlinedFunctionCount, Smi)
3983b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  DEFINE_ELEMENT_ACCESSORS(LiteralArray, FixedArray)
3984b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  DEFINE_ELEMENT_ACCESSORS(OsrAstId, Smi)
39853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  DEFINE_ELEMENT_ACCESSORS(OsrPcOffset, Smi)
398685b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
3987b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#undef DEFINE_ELEMENT_ACCESSORS
3988b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3989b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Accessors for elements of the ith deoptimization entry.
3990b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#define DEFINE_ENTRY_ACCESSORS(name, type)                       \
3991b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  type* name(int i) {                                            \
3992b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    return type::cast(get(IndexForEntry(i) + k##name##Offset));  \
3993b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }                                                              \
3994b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void Set##name(int i, type* value) {                           \
3995b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    set(IndexForEntry(i) + k##name##Offset, value);              \
3996b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
3997b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3998b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  DEFINE_ENTRY_ACCESSORS(AstId, Smi)
3999b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  DEFINE_ENTRY_ACCESSORS(TranslationIndex, Smi)
4000b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  DEFINE_ENTRY_ACCESSORS(ArgumentsStackHeight, Smi)
40012b4ba1175df6a5a6b9b5cda034189197bf6565ecBen Murdoch  DEFINE_ENTRY_ACCESSORS(Pc, Smi)
4002b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4003b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#undef DEFINE_ENTRY_ACCESSORS
4004b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4005b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int DeoptCount() {
4006b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    return (length() - kFirstDeoptEntryIndex) / kDeoptEntrySize;
4007b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
4008b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4009b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Allocates a DeoptimizationInputData.
4010b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  MUST_USE_RESULT static MaybeObject* Allocate(int deopt_entry_count,
4011b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                               PretenureFlag pretenure);
4012b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4013b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Casting.
4014b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static inline DeoptimizationInputData* cast(Object* obj);
4015b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
40163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#ifdef ENABLE_DISASSEMBLER
4017b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void DeoptimizationInputDataPrint(FILE* out);
4018b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif
4019b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4020b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private:
4021b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static int IndexForEntry(int i) {
4022b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    return kFirstDeoptEntryIndex + (i * kDeoptEntrySize);
4023b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
4024b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4025b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static int LengthFor(int entry_count) {
4026b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    return IndexForEntry(entry_count);
4027b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
4028b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
4029b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4030b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4031b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// DeoptimizationOutputData is a fixed array used to hold the deoptimization
4032b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// data for code generated by the full compiler.
4033b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// The format of the these objects is
4034b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch//   [i * 2]: Ast ID for ith deoptimization.
4035b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch//   [i * 2 + 1]: PC and state of ith deoptimization
4036b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass DeoptimizationOutputData: public FixedArray {
4037b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
4038b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int DeoptPoints() { return length() / 2; }
4039b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Smi* AstId(int index) { return Smi::cast(get(index * 2)); }
4040b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void SetAstId(int index, Smi* id) { set(index * 2, id); }
4041b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Smi* PcAndState(int index) { return Smi::cast(get(1 + index * 2)); }
4042b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void SetPcAndState(int index, Smi* offset) { set(1 + index * 2, offset); }
4043b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4044b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static int LengthOfFixedArray(int deopt_points) {
4045b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    return deopt_points * 2;
4046b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
4047b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4048b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Allocates a DeoptimizationOutputData.
4049b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  MUST_USE_RESULT static MaybeObject* Allocate(int number_of_deopt_points,
4050b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                               PretenureFlag pretenure);
4051b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4052b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Casting.
4053b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static inline DeoptimizationOutputData* cast(Object* obj);
4054b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
40553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#if defined(OBJECT_PRINT) || defined(ENABLE_DISASSEMBLER)
4056b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void DeoptimizationOutputDataPrint(FILE* out);
4057b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif
4058b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
4059b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4060b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
40613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Forward declaration.
40623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochclass JSGlobalPropertyCell;
40633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
40643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// TypeFeedbackCells is a fixed array used to hold the association between
40653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// cache cells and AST ids for code generated by the full compiler.
40663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// The format of the these objects is
40673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch//   [i * 2]: Global property cell of ith cache cell.
40683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch//   [i * 2 + 1]: Ast ID for ith cache cell.
40693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochclass TypeFeedbackCells: public FixedArray {
40703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public:
40713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int CellCount() { return length() / 2; }
40723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static int LengthOfFixedArray(int cell_count) { return cell_count * 2; }
40733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
40743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Accessors for AST ids associated with cache values.
40753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline Smi* AstId(int index);
40763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline void SetAstId(int index, Smi* id);
40773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
40783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Accessors for global property cells holding the cache values.
40793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline JSGlobalPropertyCell* Cell(int index);
40803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline void SetCell(int index, JSGlobalPropertyCell* cell);
40813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
40823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // The object that indicates an uninitialized cache.
40833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static inline Handle<Object> UninitializedSentinel(Isolate* isolate);
40843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
40853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // The object that indicates a megamorphic state.
40863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static inline Handle<Object> MegamorphicSentinel(Isolate* isolate);
40873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
40883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // A raw version of the uninitialized sentinel that's safe to read during
40893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // garbage collection (e.g., for patching the cache).
40903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static inline Object* RawUninitializedSentinel(Heap* heap);
40913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
40923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Casting.
40933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static inline TypeFeedbackCells* cast(Object* obj);
40943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
40953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kForInFastCaseMarker = 0;
40963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kForInSlowCaseMarker = 1;
40973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch};
409885b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
4099b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
41003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Forward declaration.
41013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochclass SafepointEntry;
41023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochclass TypeFeedbackInfo;
41033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Code describes objects with on-the-fly generated machine code.
4105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass Code: public HeapObject {
4106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
4107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Opaque data type for encapsulating code flags like kind, inline
4108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // cache state, and arguments count.
4109756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  // FLAGS_MIN_VALUE and FLAGS_MAX_VALUE are specified to ensure that
4110756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  // enumeration type has correct value range (see Issue 830 for more details).
4111756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  enum Flags {
4112756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick    FLAGS_MIN_VALUE = kMinInt,
4113756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick    FLAGS_MAX_VALUE = kMaxInt
4114756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  };
4115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  enum Kind {
4117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    FUNCTION,
4118b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    OPTIMIZED_FUNCTION,
4119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    STUB,
4120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    BUILTIN,
4121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    LOAD_IC,
4122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    KEYED_LOAD_IC,
4123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    CALL_IC,
41247f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    KEYED_CALL_IC,
4125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    STORE_IC,
4126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    KEYED_STORE_IC,
4127257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    UNARY_OP_IC,
4128257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    BINARY_OP_IC,
4129b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    COMPARE_IC,
413069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    TO_BOOLEAN_IC,
41316ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    // No more than 16 kinds. The value currently encoded in four bits in
4132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Flags.
4133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Pseudo-kinds.
4135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    REGEXP = BUILTIN,
4136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    FIRST_IC_KIND = LOAD_IC,
413769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    LAST_IC_KIND = TO_BOOLEAN_IC
4138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  };
4139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  enum {
414150ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen    NUMBER_OF_KINDS = LAST_IC_KIND + 1
4142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  };
4143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4144b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  typedef int ExtraICState;
4145b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
4146b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  static const ExtraICState kNoExtraICState = 0;
4147b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
4148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_DISASSEMBLER
4149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Printing
4150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const char* Kind2String(Kind kind);
4151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const char* ICState2String(InlineCacheState state);
4152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const char* PropertyType2String(PropertyType type);
41531e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  static void PrintExtraICState(FILE* out, Kind kind, ExtraICState extra);
4154b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  inline void Disassemble(const char* name) {
4155b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    Disassemble(name, stdout);
4156b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
4157b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void Disassemble(const char* name, FILE* out);
4158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif  // ENABLE_DISASSEMBLER
4159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // [instruction_size]: Size of the native instructions
4161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline int instruction_size();
4162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void set_instruction_size(int value);
4163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4164ac95265630a4e0c317a7a7201d17a57df7d9bcceLeon Clarke  // [relocation_info]: Code relocation information
4165ac95265630a4e0c317a7a7201d17a57df7d9bcceLeon Clarke  DECL_ACCESSORS(relocation_info, ByteArray)
4166b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void InvalidateRelocation();
4167ac95265630a4e0c317a7a7201d17a57df7d9bcceLeon Clarke
41683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // [handler_table]: Fixed array containing offsets of exception handlers.
41693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  DECL_ACCESSORS(handler_table, FixedArray)
41703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4171b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // [deoptimization_data]: Array containing data for deopt.
4172b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  DECL_ACCESSORS(deoptimization_data, FixedArray)
4173b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
41743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // [type_feedback_info]: Struct containing type feedback information.
41753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Will contain either a TypeFeedbackInfo object, or undefined.
41763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  DECL_ACCESSORS(type_feedback_info, Object)
41773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
41783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // [gc_metadata]: Field used to hold GC related metadata. The contents of this
4179257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // field does not have to be traced during garbage collection since
4180257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // it is only used by the garbage collector itself.
41813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  DECL_ACCESSORS(gc_metadata, Object)
41823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
41833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // [ic_age]: Inline caching age: the value of the Heap::global_ic_age
41843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // at the moment when this object was created.
41853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline void set_ic_age(int count);
41863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline int ic_age();
41875d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch
4188b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Unchecked accessors to be used during GC.
4189ac95265630a4e0c317a7a7201d17a57df7d9bcceLeon Clarke  inline ByteArray* unchecked_relocation_info();
4190b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  inline FixedArray* unchecked_deoptimization_data();
4191ac95265630a4e0c317a7a7201d17a57df7d9bcceLeon Clarke
4192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline int relocation_size();
4193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // [flags]: Various code flags.
4195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline Flags flags();
4196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void set_flags(Flags flags);
4197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // [flags]: Access to specific code flags.
4199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline Kind kind();
4200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline InlineCacheState ic_state();  // Only valid for IC stubs.
4201b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  inline ExtraICState extra_ic_state();  // Only valid for IC stubs.
4202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline PropertyType type();  // Only valid for monomorphic IC stubs.
4203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline int arguments_count();  // Only valid for call IC stubs.
4204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Testers for IC stub kinds.
4206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline bool is_inline_cache_stub();
4207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline bool is_load_stub() { return kind() == LOAD_IC; }
4208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline bool is_keyed_load_stub() { return kind() == KEYED_LOAD_IC; }
4209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline bool is_store_stub() { return kind() == STORE_IC; }
4210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline bool is_keyed_store_stub() { return kind() == KEYED_STORE_IC; }
4211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline bool is_call_stub() { return kind() == CALL_IC; }
42127f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  inline bool is_keyed_call_stub() { return kind() == KEYED_CALL_IC; }
421369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  inline bool is_unary_op_stub() { return kind() == UNARY_OP_IC; }
421469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  inline bool is_binary_op_stub() { return kind() == BINARY_OP_IC; }
4215257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  inline bool is_compare_ic_stub() { return kind() == COMPARE_IC; }
421669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  inline bool is_to_boolean_ic_stub() { return kind() == TO_BOOLEAN_IC; }
4217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
42186ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // [major_key]: For kind STUB or BINARY_OP_IC, the major key.
421980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  inline int major_key();
4220b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  inline void set_major_key(int value);
4221b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
42223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // For stubs, tells whether they should always exist, so that they can be
42233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // called from other stubs.
42243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline bool is_pregenerated();
42253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline void set_is_pregenerated(bool value);
42263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4227b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // [optimizable]: For FUNCTION kind, tells if it is optimizable.
4228b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  inline bool optimizable();
4229b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  inline void set_optimizable(bool value);
4230b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4231b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // [has_deoptimization_support]: For FUNCTION kind, tells if it has
4232b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // deoptimization support.
4233b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  inline bool has_deoptimization_support();
4234b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  inline void set_has_deoptimization_support(bool value);
4235b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4236589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // [has_debug_break_slots]: For FUNCTION kind, tells if it has
4237589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // been compiled with debug break slots.
4238589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  inline bool has_debug_break_slots();
4239589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  inline void set_has_debug_break_slots(bool value);
4240589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
42413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // [compiled_with_optimizing]: For FUNCTION kind, tells if it has
42423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // been compiled with IsOptimizing set to true.
42433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline bool is_compiled_optimizable();
42443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline void set_compiled_optimizable(bool value);
42453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
42463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // [has_self_optimization_header]: For FUNCTION kind, tells if it has
42473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // a self-optimization header.
42483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline bool has_self_optimization_header();
42493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline void set_self_optimization_header(bool value);
42503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4251b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // [allow_osr_at_loop_nesting_level]: For FUNCTION kind, tells for
4252b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // how long the function has been marked for OSR and therefore which
4253b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // level of loop nesting we are willing to do on-stack replacement
4254b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // for.
4255b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  inline void set_allow_osr_at_loop_nesting_level(int level);
4256b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  inline int allow_osr_at_loop_nesting_level();
4257b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
42588f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch  // [profiler_ticks]: For FUNCTION kind, tells for how many profiler ticks
42598f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch  // the code object was seen on the stack with no IC patching going on.
42608f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch  inline int profiler_ticks();
42618f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch  inline void set_profiler_ticks(int ticks);
42628f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch
4263b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // [stack_slots]: For kind OPTIMIZED_FUNCTION, the number of stack slots
4264b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // reserved in the code prologue.
4265b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  inline unsigned stack_slots();
4266b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  inline void set_stack_slots(unsigned slots);
4267b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4268b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // [safepoint_table_start]: For kind OPTIMIZED_CODE, the offset in
4269b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // the instruction stream where the safepoint table starts.
42701e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  inline unsigned safepoint_table_offset();
42711e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  inline void set_safepoint_table_offset(unsigned offset);
4272b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4273b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // [stack_check_table_start]: For kind FUNCTION, the offset in the
4274b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // instruction stream where the stack check table starts.
42751e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  inline unsigned stack_check_table_offset();
42761e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  inline void set_stack_check_table_offset(unsigned offset);
4277b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4278b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // [check type]: For kind CALL_IC, tells how to check if the
4279b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // receiver is valid for the given call.
4280b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  inline CheckType check_type();
4281b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  inline void set_check_type(CheckType value);
4282b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
428369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  // [type-recording unary op type]: For kind UNARY_OP_IC.
4284257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  inline byte unary_op_type();
4285257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  inline void set_unary_op_type(byte value);
4286257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
428769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  // [type-recording binary op type]: For kind BINARY_OP_IC.
4288257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  inline byte binary_op_type();
4289257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  inline void set_binary_op_type(byte value);
4290257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  inline byte binary_op_result_type();
4291257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  inline void set_binary_op_result_type(byte value);
4292b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
429369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  // [compare state]: For kind COMPARE_IC, tells what state the stub is in.
4294b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  inline byte compare_state();
4295b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  inline void set_compare_state(byte value);
4296b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
429769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  // [to_boolean_foo]: For kind TO_BOOLEAN_IC tells what state the stub is in.
429869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  inline byte to_boolean_state();
429969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  inline void set_to_boolean_state(byte value);
430069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
43013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // [has_function_cache]: For kind STUB tells whether there is a function
43023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // cache is passed to the stub.
43033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline bool has_function_cache();
43043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline void set_has_function_cache(bool flag);
43053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4306b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  // Get the safepoint entry for the given pc.
4307b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  SafepointEntry GetSafepointEntry(Address pc);
4308b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4309b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Mark this code object as not having a stack check table.  Assumes kind
4310b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // is FUNCTION.
4311b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void SetNoStackCheckTable();
4312b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4313b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Find the first map in an IC stub.
4314b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Map* FindFirstMap();
4315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
43163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  class ExtraICStateStrictMode: public BitField<StrictModeFlag, 0, 1> {};
43173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  class ExtraICStateKeyedAccessGrowMode:
43183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      public BitField<KeyedAccessGrowMode, 1, 1> {};  // NOLINT
43193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
43203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kExtraICStateGrowModeShift = 1;
43213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
43223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static inline StrictModeFlag GetStrictMode(ExtraICState extra_ic_state) {
43233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return ExtraICStateStrictMode::decode(extra_ic_state);
43243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
43253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
43263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static inline KeyedAccessGrowMode GetKeyedAccessGrowMode(
43273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      ExtraICState extra_ic_state) {
43283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return ExtraICStateKeyedAccessGrowMode::decode(extra_ic_state);
43293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
43303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
43313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static inline ExtraICState ComputeExtraICState(
43323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      KeyedAccessGrowMode grow_mode,
43333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      StrictModeFlag strict_mode) {
43343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return ExtraICStateKeyedAccessGrowMode::encode(grow_mode) |
43353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        ExtraICStateStrictMode::encode(strict_mode);
43363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
43373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Flags operations.
4339b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  static inline Flags ComputeFlags(
4340b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch      Kind kind,
4341b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch      InlineCacheState ic_state = UNINITIALIZED,
4342b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch      ExtraICState extra_ic_state = kNoExtraICState,
4343b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch      PropertyType type = NORMAL,
4344b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch      int argc = -1,
4345b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch      InlineCacheHolderFlag holder = OWN_MAP);
4346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline Flags ComputeMonomorphicFlags(
4348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      Kind kind,
4349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      PropertyType type,
4350b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch      ExtraICState extra_ic_state = kNoExtraICState,
43518defd9ff6930b4e24729971a61cf7469daf119beSteve Block      InlineCacheHolderFlag holder = OWN_MAP,
4352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      int argc = -1);
4353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline InlineCacheState ExtractICStateFromFlags(Flags flags);
4355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline PropertyType ExtractTypeFromFlags(Flags flags);
4356589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  static inline Kind ExtractKindFromFlags(Flags flags);
43578defd9ff6930b4e24729971a61cf7469daf119beSteve Block  static inline InlineCacheHolderFlag ExtractCacheHolderFromFlags(Flags flags);
4358589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  static inline ExtraICState ExtractExtraICStateFromFlags(Flags flags);
4359589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  static inline int ExtractArgumentsCountFromFlags(Flags flags);
4360589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
4361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline Flags RemoveTypeFromFlags(Flags flags);
4362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Convert a target address into a code object.
4364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline Code* GetCodeFromTargetAddress(Address address);
4365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4366791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block  // Convert an entry address into an object.
4367791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block  static inline Object* GetObjectFromEntryAddress(Address location_of_address);
4368791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block
4369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Returns the address of the first instruction.
4370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline byte* instruction_start();
4371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4372ac95265630a4e0c317a7a7201d17a57df7d9bcceLeon Clarke  // Returns the address right after the last instruction.
4373ac95265630a4e0c317a7a7201d17a57df7d9bcceLeon Clarke  inline byte* instruction_end();
4374ac95265630a4e0c317a7a7201d17a57df7d9bcceLeon Clarke
4375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Returns the size of the instructions, padding, and relocation information.
4376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline int body_size();
4377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Returns the address of the first relocation info (read backwards!).
4379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline byte* relocation_start();
4380a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Code entry point.
4382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline byte* entry();
4383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Returns true if pc is inside this object's instructions.
4385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline bool contains(byte* pc);
4386a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4387a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Relocate the code by delta bytes. Called to signal that this code
4388a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // object has been moved by delta bytes.
4389d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  void Relocate(intptr_t delta);
4390a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4391a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Migrate code described by desc.
4392a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void CopyFrom(const CodeDesc& desc);
4393a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
43943bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  // Returns the object size for a given body (used for allocation).
43953bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  static int SizeFor(int body_size) {
4396a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    ASSERT_SIZE_TAG_ALIGNED(body_size);
43973bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch    return RoundUp(kHeaderSize + body_size, kCodeAlignment);
4398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
4399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Calculate the size of the code object to report for log events. This takes
4401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // the layout of the code object into account.
4402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int ExecutableSize() {
4403a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Check that the assumptions about the layout of the code object holds.
4404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    ASSERT_EQ(static_cast<int>(instruction_start() - address()),
4405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block              Code::kHeaderSize);
4406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return instruction_size() + Code::kHeaderSize;
4407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
4408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Locating source position.
4410a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int SourcePosition(Address pc);
4411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int SourceStatementPosition(Address pc);
4412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Casting.
4414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline Code* cast(Object* obj);
4415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Dispatched behavior.
44173bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  int CodeSize() { return SizeFor(body_size()); }
4418756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  inline void CodeIterateBody(ObjectVisitor* v);
4419756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
4420756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  template<typename StaticVisitor>
442144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  inline void CodeIterateBody(Heap* heap);
4422b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef OBJECT_PRINT
4423b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  inline void CodePrint() {
4424b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    CodePrint(stdout);
4425b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
4426b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void CodePrint(FILE* out);
4427b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif
4428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG
4429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void CodeVerify();
4430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
44318f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch  void ClearInlineCaches();
4432b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4433b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Max loop nesting marker used to postpose OSR. We don't take loop
4434b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // nesting that is deeper than 5 levels into account.
4435b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static const int kMaxLoopNestingMarker = 6;
4436b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4437a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Layout description.
4438a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kInstructionSizeOffset = HeapObject::kHeaderSize;
4439ac95265630a4e0c317a7a7201d17a57df7d9bcceLeon Clarke  static const int kRelocationInfoOffset = kInstructionSizeOffset + kIntSize;
44403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kHandlerTableOffset = kRelocationInfoOffset + kPointerSize;
4441b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static const int kDeoptimizationDataOffset =
44423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      kHandlerTableOffset + kPointerSize;
44433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kTypeFeedbackInfoOffset =
44445d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch      kDeoptimizationDataOffset + kPointerSize;
44453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kGCMetadataOffset = kTypeFeedbackInfoOffset + kPointerSize;
44463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kICAgeOffset =
44473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      kGCMetadataOffset + kPointerSize;
44483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kFlagsOffset = kICAgeOffset + kIntSize;
4449257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  static const int kKindSpecificFlagsOffset = kFlagsOffset + kIntSize;
4450b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static const int kKindSpecificFlagsSize = 2 * kIntSize;
4451b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4452b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static const int kHeaderPaddingStart = kKindSpecificFlagsOffset +
4453b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      kKindSpecificFlagsSize;
4454b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Add padding to align the instruction start following right after
4456a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // the Code object header.
4457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kHeaderSize =
4458b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      (kHeaderPaddingStart + kCodeAlignmentMask) & ~kCodeAlignmentMask;
4459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Byte offsets within kKindSpecificFlagsOffset.
4461b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static const int kStubMajorKeyOffset = kKindSpecificFlagsOffset;
4462b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static const int kOptimizableOffset = kKindSpecificFlagsOffset;
4463b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static const int kStackSlotsOffset = kKindSpecificFlagsOffset;
4464b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static const int kCheckTypeOffset = kKindSpecificFlagsOffset;
4465b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4466257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  static const int kUnaryOpTypeOffset = kStubMajorKeyOffset + 1;
4467b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static const int kBinaryOpTypeOffset = kStubMajorKeyOffset + 1;
446869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  static const int kCompareStateOffset = kStubMajorKeyOffset + 1;
446969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  static const int kToBooleanTypeOffset = kStubMajorKeyOffset + 1;
44703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kHasFunctionCacheOffset = kStubMajorKeyOffset + 1;
4471589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
4472589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  static const int kFullCodeFlags = kOptimizableOffset + 1;
4473589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  class FullCodeFlagsHasDeoptimizationSupportField:
4474589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      public BitField<bool, 0, 1> {};  // NOLINT
4475589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  class FullCodeFlagsHasDebugBreakSlotsField: public BitField<bool, 1, 1> {};
44763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  class FullCodeFlagsIsCompiledOptimizable: public BitField<bool, 2, 1> {};
44773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  class FullCodeFlagsHasSelfOptimizationHeader: public BitField<bool, 3, 1> {};
4478b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4479b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static const int kBinaryOpReturnTypeOffset = kBinaryOpTypeOffset + 1;
4480589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
4481589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  static const int kAllowOSRAtLoopNestingLevelOffset = kFullCodeFlags + 1;
44828f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch  static const int kProfilerTicksOffset = kAllowOSRAtLoopNestingLevelOffset + 1;
4483b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
44841e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  static const int kSafepointTableOffsetOffset = kStackSlotsOffset + kIntSize;
44851e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  static const int kStackCheckTableOffsetOffset = kStackSlotsOffset + kIntSize;
4486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4487589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // Flags layout.  BitField<type, shift, size>.
4488589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  class ICStateField: public BitField<InlineCacheState, 0, 3> {};
4489589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  class TypeField: public BitField<PropertyType, 3, 4> {};
44903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  class CacheHolderField: public BitField<InlineCacheHolderFlag, 7, 1> {};
44913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  class KindField: public BitField<Kind, 8, 4> {};
4492589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  class ExtraICStateField: public BitField<ExtraICState, 12, 2> {};
44933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  class IsPregeneratedField: public BitField<bool, 14, 1> {};
4494589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
4495589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // Signed field cannot be encoded using the BitField class.
44963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kArgumentsCountShift = 15;
4497589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  static const int kArgumentsCountMask = ~((1 << kArgumentsCountShift) - 1);
4498a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
44993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // This constant should be encodable in an ARM instruction.
4500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kFlagsNotUsedInLookup =
4501589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      TypeField::kMask | CacheHolderField::kMask;
4502a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4503a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
4504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DISALLOW_IMPLICIT_CONSTRUCTORS(Code);
4505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
4506a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// All heap objects have a Map that describes their structure.
4509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//  A Map contains information about:
4510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//  - Size information about the object
4511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//  - How to iterate over an object (for garbage collection)
4512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass Map: public HeapObject {
4513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
4514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Instance size.
4515791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block  // Size in bytes or kVariableSizeSentinel if instances do not have
4516791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block  // a fixed size.
4517a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline int instance_size();
4518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void set_instance_size(int value);
4519a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4520a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Count of properties allocated in the object.
4521a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline int inobject_properties();
4522a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void set_inobject_properties(int value);
4523a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4524a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Count of property fields pre-allocated in the object when first allocated.
4525a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline int pre_allocated_property_fields();
4526a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void set_pre_allocated_property_fields(int value);
4527a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4528a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Instance type.
4529a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline InstanceType instance_type();
4530a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void set_instance_type(InstanceType value);
4531a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4532a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Tells how many unused property fields are available in the
4533a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // instance (only used for JSObject in fast mode).
4534a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline int unused_property_fields();
4535a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void set_unused_property_fields(int value);
4536a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4537a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Bit field.
4538a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline byte bit_field();
4539a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void set_bit_field(byte value);
4540a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4541a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Bit field 2.
4542a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline byte bit_field2();
4543a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void set_bit_field2(byte value);
4544a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4545257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Bit field 3.
4546257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // TODO(1399): It should be possible to make room for bit_field3 in the map
4547257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // without overloading the instance descriptors field (and storing it in the
4548257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // DescriptorArray when the map has one).
4549257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  inline int bit_field3();
4550257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  inline void set_bit_field3(int value);
4551257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
4552a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Tells whether the object in the prototype property will be used
4553a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // for instances created from this function.  If the prototype
4554a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // property is set to a value that is not a JSObject, the prototype
4555a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // property will not be used to create instances of the function.
4556a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // See ECMA-262, 13.2.2.
4557a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void set_non_instance_prototype(bool value);
4558a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline bool has_non_instance_prototype();
4559a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
45606ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Tells whether function has special prototype property. If not, prototype
45616ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // property will not be created when accessed (will return undefined),
45626ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // and construction from this function will not be allowed.
45636ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  inline void set_function_with_prototype(bool value);
45646ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  inline bool function_with_prototype();
45656ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
4566a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Tells whether the instance with this map should be ignored by the
4567a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // __proto__ accessor.
4568a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void set_is_hidden_prototype() {
4569a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    set_bit_field(bit_field() | (1 << kIsHiddenPrototype));
4570a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
4571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4572a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline bool is_hidden_prototype() {
4573a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return ((1 << kIsHiddenPrototype) & bit_field()) != 0;
4574a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
4575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4576a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Records and queries whether the instance has a named interceptor.
4577a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void set_has_named_interceptor() {
4578a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    set_bit_field(bit_field() | (1 << kHasNamedInterceptor));
4579a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
4580a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4581a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline bool has_named_interceptor() {
4582a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return ((1 << kHasNamedInterceptor) & bit_field()) != 0;
4583a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
4584a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4585a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Records and queries whether the instance has an indexed interceptor.
4586a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void set_has_indexed_interceptor() {
4587a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    set_bit_field(bit_field() | (1 << kHasIndexedInterceptor));
4588a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
4589a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4590a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline bool has_indexed_interceptor() {
4591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return ((1 << kHasIndexedInterceptor) & bit_field()) != 0;
4592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
4593a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4594a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Tells whether the instance is undetectable.
4595a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // An undetectable object is a special class of JSObject: 'typeof' operator
4596a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // returns undefined, ToBoolean returns false. Otherwise it behaves like
4597a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // a normal JS object.  It is useful for implementing undetectable
4598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // document.all in Firefox & Safari.
4599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // See https://bugzilla.mozilla.org/show_bug.cgi?id=248549.
4600a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void set_is_undetectable() {
4601a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    set_bit_field(bit_field() | (1 << kIsUndetectable));
4602a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
4603a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4604a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline bool is_undetectable() {
4605a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return ((1 << kIsUndetectable) & bit_field()) != 0;
4606a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
4607a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4608a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Tells whether the instance has a call-as-function handler.
4609a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void set_has_instance_call_handler() {
4610a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    set_bit_field(bit_field() | (1 << kHasInstanceCallHandler));
4611a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
4612a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4613a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline bool has_instance_call_handler() {
4614a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return ((1 << kHasInstanceCallHandler) & bit_field()) != 0;
4615a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
4616a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
46178defd9ff6930b4e24729971a61cf7469daf119beSteve Block  inline void set_is_extensible(bool value);
46188defd9ff6930b4e24729971a61cf7469daf119beSteve Block  inline bool is_extensible();
46198defd9ff6930b4e24729971a61cf7469daf119beSteve Block
4620589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  inline void set_elements_kind(ElementsKind elements_kind) {
4621589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    ASSERT(elements_kind < kElementsKindCount);
4622589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    ASSERT(kElementsKindCount <= (1 << kElementsKindBitCount));
46233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    set_bit_field2((bit_field2() & ~kElementsKindMask) |
46243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch        (elements_kind << kElementsKindShift));
46253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    ASSERT(this->elements_kind() == elements_kind);
4626e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  }
4627e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
4628589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  inline ElementsKind elements_kind() {
4629589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    return static_cast<ElementsKind>(
46303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch        (bit_field2() & kElementsKindMask) >> kElementsKindShift);
46313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
46323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
46333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Tells whether the instance has fast elements that are only Smis.
46343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline bool has_fast_smi_only_elements() {
46353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return elements_kind() == FAST_SMI_ONLY_ELEMENTS;
46363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
46373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
46383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Tells whether the instance has fast elements.
4639756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  inline bool has_fast_elements() {
4640589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    return elements_kind() == FAST_ELEMENTS;
4641e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  }
4642e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
46433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  inline bool has_fast_double_elements() {
4644589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    return elements_kind() == FAST_DOUBLE_ELEMENTS;
46451e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
46461e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
46473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline bool has_non_strict_arguments_elements() {
46483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return elements_kind() == NON_STRICT_ARGUMENTS_ELEMENTS;
46493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
46503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
465144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  inline bool has_external_array_elements() {
4652589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    ElementsKind kind(elements_kind());
4653589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    return kind >= FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND &&
4654589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        kind <= LAST_EXTERNAL_ARRAY_ELEMENTS_KIND;
46553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
46563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
46573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  inline bool has_dictionary_elements() {
4658589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    return elements_kind() == DICTIONARY_ELEMENTS;
46591e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
46601e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
46613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline bool has_slow_elements_kind() {
46623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return elements_kind() == DICTIONARY_ELEMENTS
46633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        || elements_kind() == NON_STRICT_ARGUMENTS_ELEMENTS;
46643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
46653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
46663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static bool IsValidElementsTransition(ElementsKind from_kind,
46673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                        ElementsKind to_kind);
46683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
46690d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // Tells whether the map is attached to SharedFunctionInfo
46700d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // (for inobject slack tracking).
46710d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  inline void set_attached_to_shared_function_info(bool value);
46720d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
46730d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  inline bool attached_to_shared_function_info();
46740d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
46750d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // Tells whether the map is shared between objects that may have different
46760d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // behavior. If true, the map should never be modified, instead a clone
46770d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // should be created and modified.
46780d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  inline void set_is_shared(bool value);
46790d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
46800d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  inline bool is_shared();
46810d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
4682a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Tells whether the instance needs security checks when accessing its
4683a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // properties.
4684a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void set_is_access_check_needed(bool access_check_needed);
4685a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline bool is_access_check_needed();
4686a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4687a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // [prototype]: implicit prototype object.
4688a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(prototype, Object)
4689a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4690a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // [constructor]: points back to the function responsible for this map.
4691a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(constructor, Object)
4692a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
46930d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  inline JSFunction* unchecked_constructor();
46940d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
4695257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Should only be called by the code that initializes map to set initial valid
4696257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // value of the instance descriptor member.
4697257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  inline void init_instance_descriptors();
4698257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
4699a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // [instance descriptors]: describes the object.
4700a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(instance_descriptors, DescriptorArray)
4701a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4702257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Sets the instance descriptor array for the map to be an empty descriptor
4703257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // array.
4704257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  inline void clear_instance_descriptors();
4705257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
4706a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // [stub cache]: contains stubs compiled for this map.
47076ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  DECL_ACCESSORS(code_cache, Object)
4708a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4709053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block  // [prototype transitions]: cache of prototype transitions.
4710053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block  // Prototype transition is a transition that happens
4711053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block  // when we change object's prototype to a new one.
4712053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block  // Cache format:
4713053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block  //    0: finger - index of the first free cell in the cache
4714053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block  //    1 + 2 * i: prototype
4715053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block  //    2 + 2 * i: target map
4716053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block  DECL_ACCESSORS(prototype_transitions, FixedArray)
47173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4718053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block  inline FixedArray* unchecked_prototype_transitions();
4719053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block
47203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  static const int kProtoTransitionHeaderSize = 1;
47213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  static const int kProtoTransitionNumberOfEntriesOffset = 0;
47223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  static const int kProtoTransitionElementsPerEntry = 2;
47233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  static const int kProtoTransitionPrototypeOffset = 0;
47243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  static const int kProtoTransitionMapOffset = 1;
47253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
47263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  inline int NumberOfProtoTransitions() {
47273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    FixedArray* cache = prototype_transitions();
47283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    if (cache->length() == 0) return 0;
47293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    return
47303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch        Smi::cast(cache->get(kProtoTransitionNumberOfEntriesOffset))->value();
47313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
47323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
47333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  inline void SetNumberOfProtoTransitions(int value) {
47343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    FixedArray* cache = prototype_transitions();
47353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    ASSERT(cache->length() != 0);
47363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    cache->set_unchecked(kProtoTransitionNumberOfEntriesOffset,
47373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                         Smi::FromInt(value));
47383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
47393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
4740b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Lookup in the map's instance descriptors and fill out the result
4741b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // with the given holder if the name is found. The holder may be
4742b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // NULL when this function is used from the compiler.
4743b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void LookupInDescriptors(JSObject* holder,
4744b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                           String* name,
4745b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                           LookupResult* result);
4746b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
47475913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* CopyDropDescriptors();
474880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
47495913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* CopyNormalized(PropertyNormalizationMode mode,
47505913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck                                              NormalizedMapSharingMode sharing);
4751a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4752a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Returns a copy of the map, with all transitions dropped from the
4753a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // instance descriptors.
47545913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* CopyDropTransitions();
4755a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4756a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Returns the property index for name (only valid for FAST MODE).
4757a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int PropertyIndexFor(String* name);
4758a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4759a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Returns the next free property index (only valid for FAST MODE).
4760a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int NextFreePropertyIndex();
4761a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
47623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Returns the number of properties described in instance_descriptors
47633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // filtering out properties with the specified attributes.
47643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int NumberOfDescribedProperties(PropertyAttributes filter = NONE);
4765a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4766a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Casting.
4767a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline Map* cast(Object* obj);
4768a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4769a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Locate an accessor in the instance descriptor.
4770a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  AccessorDescriptor* FindAccessor(String* name);
4771a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4772a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Code cache operations.
4773a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4774a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Clears the code cache.
477544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  inline void ClearCodeCache(Heap* heap);
4776a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4777a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Update code cache.
47783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static void UpdateCodeCache(Handle<Map> map,
47793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                              Handle<String> name,
47803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                              Handle<Code> code);
47815913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* UpdateCodeCache(String* name, Code* code);
4782a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4783a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Returns the found code or undefined if absent.
4784a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* FindInCodeCache(String* name, Code::Flags flags);
4785a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4786a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Returns the non-negative index of the code object if it is in the
4787a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // cache and -1 otherwise.
47886ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  int IndexInCodeCache(Object* name, Code* code);
4789a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4790a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Removes a code object from the code cache at the given index.
47916ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void RemoveFromCodeCache(String* name, Code* code, int index);
4792a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4793a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // For every transition in this map, makes the transition's
4794a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // target's prototype pointer point back to this map.
4795a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // This is undone in MarkCompactCollector::ClearNonLiveTransitions().
4796a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void CreateBackPointers();
4797a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
47983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void CreateOneBackPointer(Object* transition_target);
47993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4800a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Set all map transitions from this map to dead maps to null.
4801a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Also, restore the original prototype on the targets of these
4802a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // transitions, so that we do not process this map again while
4803a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // following back pointers.
480444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void ClearNonLiveTransitions(Heap* heap, Object* real_prototype);
4805a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
48063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Restore a possible back pointer in the prototype field of object.
48073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Return true in that case and false otherwise. Set *keep_entry to
48083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // true when a live map transition has been found.
48093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool RestoreOneBackPointer(Object* object,
48103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                             Object* real_prototype,
48113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                             bool* keep_entry);
48123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
48133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Computes a hash value for this map, to be used in HashTables and such.
48143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  int Hash();
48153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
48163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Compares this map to another to see if they describe equivalent objects.
48173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // If |mode| is set to CLEAR_INOBJECT_PROPERTIES, |other| is treated as if
48183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // it had exactly zero inobject properties.
48193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // The "shared" flags of both this map and |other| are ignored.
48203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  bool EquivalentToForNormalization(Map* other, PropertyNormalizationMode mode);
48213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
48223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Returns the contents of this map's descriptor array for the given string.
48233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // May return NULL. |safe_to_add_transition| is set to false and NULL
48243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // is returned if adding transitions is not allowed.
48253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Object* GetDescriptorContents(String* sentinel_name,
48263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                bool* safe_to_add_transitions);
48273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
48283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Returns the map that this map transitions to if its elements_kind
48293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // is changed to |elements_kind|, or NULL if no such map is cached yet.
48303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // |safe_to_add_transitions| is set to false if adding transitions is not
48313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // allowed.
48323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Map* LookupElementsTransitionMap(ElementsKind elements_kind,
48333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                   bool* safe_to_add_transition);
48343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
48353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Adds an entry to this map's descriptor array for a transition to
48363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // |transitioned_map| when its elements_kind is changed to |elements_kind|.
48373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT MaybeObject* AddElementsTransition(
48383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      ElementsKind elements_kind, Map* transitioned_map);
48393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
48403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Returns the transitioned map for this map with the most generic
48413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // elements_kind that's found in |candidates|, or null handle if no match is
48423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // found at all.
48433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Map> FindTransitionedMap(MapHandleList* candidates);
48443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Map* FindTransitionedMap(MapList* candidates);
48453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4846592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch
4847a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Dispatched behavior.
4848b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef OBJECT_PRINT
4849b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  inline void MapPrint() {
4850b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    MapPrint(stdout);
4851b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
4852b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void MapPrint(FILE* out);
4853b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif
4854a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG
4855a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void MapVerify();
48560d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  void SharedMapVerify();
4857a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
4858a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4859756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  inline int visitor_id();
4860756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  inline void set_visitor_id(int visitor_id);
48613bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch
48620d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  typedef void (*TraverseCallback)(Map* map, void* data);
48630d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
48640d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  void TraverseTransitionTree(TraverseCallback callback, void* data);
48650d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
4866053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block  static const int kMaxCachedPrototypeTransitions = 256;
4867053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block
4868053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block  Object* GetPrototypeTransition(Object* prototype);
4869053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block
48703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT MaybeObject* PutPrototypeTransition(Object* prototype,
48713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                                      Map* map);
4872053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block
4873a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kMaxPreAllocatedPropertyFields = 255;
4874a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4875a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Layout description.
4876a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kInstanceSizesOffset = HeapObject::kHeaderSize;
4877a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kInstanceAttributesOffset = kInstanceSizesOffset + kIntSize;
4878a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kPrototypeOffset = kInstanceAttributesOffset + kIntSize;
4879a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kConstructorOffset = kPrototypeOffset + kPointerSize;
4880257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Storage for instance descriptors is overloaded to also contain additional
4881257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // map flags when unused (bit_field3). When the map has instance descriptors,
4882257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // the flags are transferred to the instance descriptor array and accessed
4883257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // through an extra indirection.
4884257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // TODO(1399): It should be possible to make room for bit_field3 in the map
4885257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // without overloading the instance descriptors field, but the map is
4886257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // currently perfectly aligned to 32 bytes and extending it at all would
4887257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // double its size.  After the increment GC work lands, this size restriction
4888257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // could be loosened and bit_field3 moved directly back in the map.
4889257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  static const int kInstanceDescriptorsOrBitField3Offset =
4890a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      kConstructorOffset + kPointerSize;
4891257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  static const int kCodeCacheOffset =
4892257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      kInstanceDescriptorsOrBitField3Offset + kPointerSize;
4893053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block  static const int kPrototypeTransitionsOffset =
4894053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block      kCodeCacheOffset + kPointerSize;
4895053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block  static const int kPadStart = kPrototypeTransitionsOffset + kPointerSize;
48967f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  static const int kSize = MAP_POINTER_ALIGN(kPadStart);
48977f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
48987f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // Layout of pointer fields. Heap iteration code relies on them
48993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // being continuously allocated.
49007f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  static const int kPointerFieldsBeginOffset = Map::kPrototypeOffset;
49017f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  static const int kPointerFieldsEndOffset =
4902053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block      Map::kPrototypeTransitionsOffset + kPointerSize;
4903a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4904a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Byte offsets within kInstanceSizesOffset.
4905a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kInstanceSizeOffset = kInstanceSizesOffset + 0;
4906a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kInObjectPropertiesByte = 1;
4907a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kInObjectPropertiesOffset =
4908a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      kInstanceSizesOffset + kInObjectPropertiesByte;
4909a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kPreAllocatedPropertyFieldsByte = 2;
4910a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kPreAllocatedPropertyFieldsOffset =
4911a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      kInstanceSizesOffset + kPreAllocatedPropertyFieldsByte;
49129ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick  static const int kVisitorIdByte = 3;
49139ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick  static const int kVisitorIdOffset = kInstanceSizesOffset + kVisitorIdByte;
4914a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4915a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Byte offsets within kInstanceAttributesOffset attributes.
4916a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kInstanceTypeOffset = kInstanceAttributesOffset + 0;
4917a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kUnusedPropertyFieldsOffset = kInstanceAttributesOffset + 1;
4918a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kBitFieldOffset = kInstanceAttributesOffset + 2;
4919a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kBitField2Offset = kInstanceAttributesOffset + 3;
4920a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4921a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  STATIC_CHECK(kInstanceTypeOffset == Internals::kMapInstanceTypeOffset);
4922a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4923a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Bit positions for bit field.
4924a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kUnused = 0;  // To be used for marking recently used maps.
4925a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kHasNonInstancePrototype = 1;
4926a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kIsHiddenPrototype = 2;
4927a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kHasNamedInterceptor = 3;
4928a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kHasIndexedInterceptor = 4;
4929a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kIsUndetectable = 5;
4930a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kHasInstanceCallHandler = 6;
4931a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kIsAccessCheckNeeded = 7;
4932a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4933a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Bit positions for bit field 2
49343100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  static const int kIsExtensible = 0;
49356ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static const int kFunctionWithPrototype = 1;
49363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  static const int kStringWrapperSafeForDefaultValueOf = 2;
49373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  static const int kAttachedToSharedFunctionInfo = 3;
49383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // No bits can be used after kElementsKindFirstBit, they are all reserved for
49393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // storing ElementKind.
49403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  static const int kElementsKindShift = 4;
49413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  static const int kElementsKindBitCount = 4;
49423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
49433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Derived values from bit field 2
49443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  static const int kElementsKindMask = (-1 << kElementsKindShift) &
49453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      ((1 << (kElementsKindShift + kElementsKindBitCount)) - 1);
49463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  static const int8_t kMaximumBitField2FastElementValue = static_cast<int8_t>(
4947589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      (FAST_ELEMENTS + 1) << Map::kElementsKindShift) - 1;
49483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int8_t kMaximumBitField2FastSmiOnlyElementValue =
49493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      static_cast<int8_t>((FAST_SMI_ONLY_ELEMENTS + 1) <<
49503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                          Map::kElementsKindShift) - 1;
4951257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
4952257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Bit positions for bit field 3
49533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  static const int kIsShared = 0;
49546ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
49556ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Layout of the default cache. It holds alternating name and code objects.
49566ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static const int kCodeCacheEntrySize = 2;
49576ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static const int kCodeCacheEntryNameOffset = 0;
49586ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static const int kCodeCacheEntryCodeOffset = 1;
4959a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4960756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  typedef FixedBodyDescriptor<kPointerFieldsBeginOffset,
4961756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick                              kPointerFieldsEndOffset,
4962756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick                              kSize> BodyDescriptor;
4963756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
4964a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
49653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  String* elements_transition_sentinel_name();
4966a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DISALLOW_IMPLICIT_CONSTRUCTORS(Map);
4967a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
4968a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4969a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4970a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// An abstract superclass, a marker class really, for simple structure classes.
4971257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// It doesn't carry much functionality but allows struct classes to be
4972a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// identified in the type system.
4973a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass Struct: public HeapObject {
4974a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
4975a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void InitializeBody(int object_size);
4976a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline Struct* cast(Object* that);
4977a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
4978a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4979a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4980a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Script describes a script which has been added to the VM.
4981a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass Script: public Struct {
4982a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
4983a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Script types.
4984a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  enum Type {
4985a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    TYPE_NATIVE = 0,
4986a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    TYPE_EXTENSION = 1,
4987a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    TYPE_NORMAL = 2
4988a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  };
4989a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4990a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Script compilation types.
4991a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  enum CompilationType {
4992a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    COMPILATION_TYPE_HOST = 0,
49933e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu    COMPILATION_TYPE_EVAL = 1
4994a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  };
4995a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
49963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Script compilation state.
49973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  enum CompilationState {
49983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    COMPILATION_STATE_INITIAL = 0,
49993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    COMPILATION_STATE_COMPILED = 1
50003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  };
50013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5002a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // [source]: the script source.
5003a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(source, Object)
5004a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5005a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // [name]: the script name.
5006a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(name, Object)
5007a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5008a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // [id]: the script id.
5009a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(id, Object)
5010a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5011a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // [line_offset]: script line offset in resource from where it was extracted.
5012a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(line_offset, Smi)
5013a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5014a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // [column_offset]: script column offset in resource from where it was
5015a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // extracted.
5016a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(column_offset, Smi)
5017a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5018a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // [data]: additional data associated with this script.
5019a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(data, Object)
5020a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5021a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // [context_data]: context data for the context this script was compiled in.
5022a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(context_data, Object)
5023a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5024a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // [wrapper]: the wrapper cache.
5025257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  DECL_ACCESSORS(wrapper, Foreign)
5026a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5027a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // [type]: the script type.
5028a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(type, Smi)
5029a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5030a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // [compilation]: how the the script was compiled.
5031a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(compilation_type, Smi)
5032a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
50333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // [is_compiled]: determines whether the script has already been compiled.
50343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  DECL_ACCESSORS(compilation_state, Smi)
50353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5036d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // [line_ends]: FixedArray of line ends positions.
5037a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(line_ends, Object)
5038a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5039d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // [eval_from_shared]: for eval scripts the shared funcion info for the
5040d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // function from which eval was called.
5041d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  DECL_ACCESSORS(eval_from_shared, Object)
5042a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5043a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // [eval_from_instructions_offset]: the instruction offset in the code for the
5044a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // function from which eval was called where eval was called.
5045a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(eval_from_instructions_offset, Smi)
5046a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5047a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline Script* cast(Object* obj);
5048a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
50493ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // If script source is an external string, check that the underlying
50503ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // resource is accessible. Otherwise, always return true.
50513ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  inline bool HasValidSource();
50523ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
5053b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef OBJECT_PRINT
5054b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  inline void ScriptPrint() {
5055b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    ScriptPrint(stdout);
5056b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
5057b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void ScriptPrint(FILE* out);
5058b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif
5059a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG
5060a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void ScriptVerify();
5061a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
5062a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5063a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kSourceOffset = HeapObject::kHeaderSize;
5064a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kNameOffset = kSourceOffset + kPointerSize;
5065a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kLineOffsetOffset = kNameOffset + kPointerSize;
5066a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kColumnOffsetOffset = kLineOffsetOffset + kPointerSize;
5067a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kDataOffset = kColumnOffsetOffset + kPointerSize;
5068a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kContextOffset = kDataOffset + kPointerSize;
5069a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kWrapperOffset = kContextOffset + kPointerSize;
5070a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kTypeOffset = kWrapperOffset + kPointerSize;
5071a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kCompilationTypeOffset = kTypeOffset + kPointerSize;
50723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kCompilationStateOffset =
50733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      kCompilationTypeOffset + kPointerSize;
50743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kLineEndsOffset = kCompilationStateOffset + kPointerSize;
5075a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kIdOffset = kLineEndsOffset + kPointerSize;
5076d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  static const int kEvalFromSharedOffset = kIdOffset + kPointerSize;
5077a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kEvalFrominstructionsOffsetOffset =
5078d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      kEvalFromSharedOffset + kPointerSize;
5079a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kSize = kEvalFrominstructionsOffsetOffset + kPointerSize;
5080a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5081a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
5082a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DISALLOW_IMPLICIT_CONSTRUCTORS(Script);
5083a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
5084a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5085a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5086b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// List of builtin functions we want to identify to improve code
5087b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// generation.
5088b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch//
5089b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Each entry has a name of a global object property holding an object
5090b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// optionally followed by ".prototype", a name of a builtin function
5091b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// on the object (the one the id is set for), and a label.
5092b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch//
5093b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Installation of ids for the selected builtin functions is handled
5094b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// by the bootstrapper.
5095b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch//
5096b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// NOTE: Order is important: math functions should be at the end of
5097b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// the list and MathFloor should be the first math function.
5098b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#define FUNCTIONS_WITH_ID_LIST(V)                   \
5099b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  V(Array.prototype, push, ArrayPush)               \
5100b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  V(Array.prototype, pop, ArrayPop)                 \
510142effa50d92d47f80404ee63808dbde9921e6202Ben Murdoch  V(Function.prototype, apply, FunctionApply)       \
5102b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  V(String.prototype, charCodeAt, StringCharCodeAt) \
5103b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  V(String.prototype, charAt, StringCharAt)         \
5104b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  V(String, fromCharCode, StringFromCharCode)       \
5105b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  V(Math, floor, MathFloor)                         \
5106b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  V(Math, round, MathRound)                         \
5107b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  V(Math, ceil, MathCeil)                           \
5108b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  V(Math, abs, MathAbs)                             \
5109b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  V(Math, log, MathLog)                             \
5110b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  V(Math, sin, MathSin)                             \
5111b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  V(Math, cos, MathCos)                             \
5112b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  V(Math, tan, MathTan)                             \
5113b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  V(Math, asin, MathASin)                           \
5114b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  V(Math, acos, MathACos)                           \
5115b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  V(Math, atan, MathATan)                           \
5116b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  V(Math, exp, MathExp)                             \
5117b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  V(Math, sqrt, MathSqrt)                           \
51183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  V(Math, pow, MathPow)                             \
51193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  V(Math, random, MathRandom)                       \
51203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  V(Math, max, MathMax)                             \
51213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  V(Math, min, MathMin)
5122b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
5123b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
5124b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochenum BuiltinFunctionId {
5125b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#define DECLARE_FUNCTION_ID(ignored1, ignore2, name)    \
5126b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  k##name,
5127b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  FUNCTIONS_WITH_ID_LIST(DECLARE_FUNCTION_ID)
5128b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#undef DECLARE_FUNCTION_ID
5129b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Fake id for a special case of Math.pow. Note, it continues the
5130b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // list of math functions.
5131b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  kMathPowHalf,
5132b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  kFirstMathFunctionId = kMathFloor
5133b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
5134b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
5135b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
5136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SharedFunctionInfo describes the JSFunction information that can be
5137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// shared by multiple instances of the function.
5138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass SharedFunctionInfo: public HeapObject {
5139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
5140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // [name]: Function name.
5141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(name, Object)
5142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // [code]: Function code.
5144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(code, Code)
5145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
51463bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  // [scope_info]: Scope info.
51473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  DECL_ACCESSORS(scope_info, ScopeInfo)
51483bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch
5149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // [construct stub]: Code stub for constructing instances of this function.
5150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(construct_stub, Code)
5151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5152756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  inline Code* unchecked_code();
5153756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
5154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Returns if this function has been compiled to native code yet.
5155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline bool is_compiled();
5156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // [length]: The function length - usually the number of declared parameters.
5158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Use up to 2^30 parameters.
5159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline int length();
5160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void set_length(int value);
5161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // [formal parameter count]: The declared number of parameters.
5163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline int formal_parameter_count();
5164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void set_formal_parameter_count(int value);
5165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Set the formal parameter count so the function code will be
5167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // called without using argument adaptor frames.
5168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void DontAdaptArguments();
5169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // [expected_nof_properties]: Expected number of properties for the function.
5171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline int expected_nof_properties();
5172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void set_expected_nof_properties(int value);
5173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
51740d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // Inobject slack tracking is the way to reclaim unused inobject space.
51750d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  //
51760d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // The instance size is initially determined by adding some slack to
51770d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // expected_nof_properties (to allow for a few extra properties added
51780d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // after the constructor). There is no guarantee that the extra space
51790d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // will not be wasted.
51800d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  //
51810d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // Here is the algorithm to reclaim the unused inobject space:
51820d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // - Detect the first constructor call for this SharedFunctionInfo.
51830d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  //   When it happens enter the "in progress" state: remember the
51840d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  //   constructor's initial_map and install a special construct stub that
51850d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  //   counts constructor calls.
51860d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // - While the tracking is in progress create objects filled with
51870d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  //   one_pointer_filler_map instead of undefined_value. This way they can be
51880d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  //   resized quickly and safely.
51890d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // - Once enough (kGenerousAllocationCount) objects have been created
51900d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  //   compute the 'slack' (traverse the map transition tree starting from the
51910d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  //   initial_map and find the lowest value of unused_property_fields).
51920d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // - Traverse the transition tree again and decrease the instance size
51930d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  //   of every map. Existing objects will resize automatically (they are
51940d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  //   filled with one_pointer_filler_map). All further allocations will
51950d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  //   use the adjusted instance size.
51960d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // - Decrease expected_nof_properties so that an allocations made from
51970d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  //   another context will use the adjusted instance size too.
51980d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // - Exit "in progress" state by clearing the reference to the initial_map
51990d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  //   and setting the regular construct stub (generic or inline).
52000d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  //
52010d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  //  The above is the main event sequence. Some special cases are possible
52020d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  //  while the tracking is in progress:
52030d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  //
52040d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // - GC occurs.
52050d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  //   Check if the initial_map is referenced by any live objects (except this
52060d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  //   SharedFunctionInfo). If it is, continue tracking as usual.
52070d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  //   If it is not, clear the reference and reset the tracking state. The
52080d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  //   tracking will be initiated again on the next constructor call.
52090d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  //
52100d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // - The constructor is called from another context.
52110d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  //   Immediately complete the tracking, perform all the necessary changes
52120d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  //   to maps. This is  necessary because there is no efficient way to track
52130d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  //   multiple initial_maps.
52140d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  //   Proceed to create an object in the current context (with the adjusted
52150d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  //   size).
52160d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  //
52170d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // - A different constructor function sharing the same SharedFunctionInfo is
52180d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  //   called in the same context. This could be another closure in the same
52190d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  //   context, or the first function could have been disposed.
52200d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  //   This is handled the same way as the previous case.
52210d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  //
52220d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  //  Important: inobject slack tracking is not attempted during the snapshot
52230d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  //  creation.
52240d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
5225f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  static const int kGenerousAllocationCount = 8;
52260d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
52270d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // [construction_count]: Counter for constructor calls made during
52280d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // the tracking phase.
52290d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  inline int construction_count();
52300d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  inline void set_construction_count(int value);
52310d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
52320d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // [initial_map]: initial map of the first function called as a constructor.
52330d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // Saved for the duration of the tracking phase.
52340d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // This is a weak link (GC resets it to undefined_value if no other live
52350d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // object reference this map).
52360d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  DECL_ACCESSORS(initial_map, Object)
52370d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
52380d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // True if the initial_map is not undefined and the countdown stub is
52390d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // installed.
52400d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  inline bool IsInobjectSlackTrackingInProgress();
52410d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
52420d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // Starts the tracking.
52430d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // Stores the initial map and installs the countdown stub.
52440d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // IsInobjectSlackTrackingInProgress is normally true after this call,
52450d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // except when tracking have not been started (e.g. the map has no unused
52460d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // properties or the snapshot is being built).
52470d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  void StartInobjectSlackTracking(Map* map);
52480d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
52490d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // Completes the tracking.
52500d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // IsInobjectSlackTrackingInProgress is false after this call.
52510d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  void CompleteInobjectSlackTracking();
52520d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
52530d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // Clears the initial_map before the GC marking phase to ensure the reference
52540d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // is weak. IsInobjectSlackTrackingInProgress is false after this call.
52550d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  void DetachInitialMap();
52560d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
52570d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // Restores the link to the initial map after the GC marking phase.
52580d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // IsInobjectSlackTrackingInProgress is true after this call.
52590d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  void AttachInitialMap(Map* map);
52600d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
52610d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // False if there are definitely no live objects created from this function.
52620d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // True if live objects _may_ exist (existence not guaranteed).
52630d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // May go back from true to false after GC.
52643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  DECL_BOOLEAN_ACCESSORS(live_objects_may_exist)
52650d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
5266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // [instance class name]: class name for instances.
5267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(instance_class_name, Object)
5268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
52696ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // [function data]: This field holds some additional data for function.
52706ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Currently it either has FunctionTemplateInfo to make benefit the API
5271b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // or Smi identifying a builtin function.
5272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // In the long run we don't want all functions to have this field but
5273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // we can fix that when we have a better model for storing hidden data
5274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // on objects.
5275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(function_data, Object)
5276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
52776ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  inline bool IsApiFunction();
52786ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  inline FunctionTemplateInfo* get_api_func_data();
5279b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  inline bool HasBuiltinFunctionId();
5280b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  inline BuiltinFunctionId builtin_function_id();
52816ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
5282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // [script info]: Script from which the function originates.
5283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(script, Object)
5284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
52856ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // [num_literals]: Number of literals used by this function.
52866ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  inline int num_literals();
52876ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  inline void set_num_literals(int value);
52886ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
5289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // [start_position_and_type]: Field used to store both the source code
5290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // position, whether or not the function is a function expression,
5291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // and whether or not the function is a toplevel function. The two
5292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // least significants bit indicates whether the function is an
5293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // expression and the rest contains the source code position.
5294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline int start_position_and_type();
5295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void set_start_position_and_type(int value);
5296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // [debug info]: Debug information.
5298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(debug_info, Object)
5299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // [inferred name]: Name inferred from variable or property
5301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // assignment of this function. Used to facilitate debugging and
5302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // profiling of JavaScript code written in OO style, where almost
5303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // all functions are anonymous but are assigned to object
5304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // properties.
5305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(inferred_name, String)
5306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5307f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  // The function's name if it is non-empty, otherwise the inferred name.
5308f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  String* DebugName();
5309f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch
5310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Position of the 'function' token in the script source.
5311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline int function_token_position();
5312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void set_function_token_position(int function_token_position);
5313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Position of this function in the script source.
5315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline int start_position();
5316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void set_start_position(int start_position);
5317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // End position of this function in the script source.
5319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline int end_position();
5320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void set_end_position(int end_position);
5321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Is this function a function expression in the source code.
53233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  DECL_BOOLEAN_ACCESSORS(is_expression)
5324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Is this function a top-level function (scripts, evals).
53263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  DECL_BOOLEAN_ACCESSORS(is_toplevel)
5327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Bit field containing various information collected by the compiler to
5329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // drive optimization.
5330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline int compiler_hints();
5331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void set_compiler_hints(int value);
5332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
53338f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch  inline int ast_node_count();
53348f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch  inline void set_ast_node_count(int count);
53358f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch
5336b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // A counter used to determine when to stress the deoptimizer with a
5337b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // deopt.
53383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline int deopt_counter();
53393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline void set_deopt_counter(int counter);
53403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
53418f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch  // Inline cache age is used to infer whether the function survived a context
53428f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch  // disposal or not. In the former case we reset the opt_count.
53438f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch  inline int ic_age();
53448f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch  inline void set_ic_age(int age);
5345b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
5346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Add information on assignments of the form this.x = ...;
5347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void SetThisPropertyAssignmentsInfo(
5348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      bool has_only_simple_this_property_assignments,
5349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      FixedArray* this_property_assignments);
5350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Clear information on assignments of the form this.x = ...;
5352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void ClearThisPropertyAssignmentsInfo();
5353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Indicate that this function only consists of assignments of the form
5355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // this.x = y; where y is either a constant or refers to an argument.
5356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline bool has_only_simple_this_property_assignments();
5357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
53587f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // Indicates if this function can be lazy compiled.
53597f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // This is used to determine if we can safely flush code from a function
53607f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // when doing GC if we expect that the function will no longer be used.
53613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  DECL_BOOLEAN_ACCESSORS(allows_lazy_compilation)
53627f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
5363756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  // Indicates how many full GCs this function has survived with assigned
5364756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  // code object. Used to determine when it is relatively safe to flush
5365756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  // this code object and replace it with lazy compilation stub.
5366756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  // Age is reset when GC notices that the code object is referenced
5367756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  // from the stack or compilation cache.
5368756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  inline int code_age();
5369756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  inline void set_code_age(int age);
5370756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
5371b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Indicates whether optimizations have been disabled for this
5372b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // shared function info. If a function is repeatedly optimized or if
5373b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // we cannot optimize the function we disable optimization to avoid
5374b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // spending time attempting to optimize it again.
53753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  DECL_BOOLEAN_ACCESSORS(optimization_disabled)
5376b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
53773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Indicates the language mode of the function's code as defined by the
53783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // current harmony drafts for the next ES language standard. Possible
53793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // values are:
53803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // 1. CLASSIC_MODE - Unrestricted syntax and semantics, same as in ES5.
53813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // 2. STRICT_MODE - Restricted syntax and semantics, same as in ES5.
53823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // 3. EXTENDED_MODE - Only available under the harmony flag, not part of ES5.
53833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline LanguageMode language_mode();
53843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline void set_language_mode(LanguageMode language_mode);
53853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
53863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Indicates whether the language mode of this function is CLASSIC_MODE.
53873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline bool is_classic_mode();
53883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
53893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Indicates whether the language mode of this function is EXTENDED_MODE.
53903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline bool is_extended_mode();
53913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
53923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // False if the function definitely does not allocate an arguments object.
53933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  DECL_BOOLEAN_ACCESSORS(uses_arguments)
53941e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
53953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // True if the function has any duplicated parameter names.
53963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  DECL_BOOLEAN_ACCESSORS(has_duplicate_parameters)
53973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
53983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Indicates whether the function is a native function.
5399589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // These needs special treatment in .call and .apply since
5400257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // null passed as the receiver should not be translated to the
5401257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // global object.
54023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  DECL_BOOLEAN_ACCESSORS(native)
54033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
54043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Indicates that the function was created by the Function function.
54053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Though it's anonymous, toString should treat it as if it had the name
54063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // "anonymous".  We don't set the name itself so that the system does not
54073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // see a binding for it.
54083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  DECL_BOOLEAN_ACCESSORS(name_should_print_as_anonymous)
54093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
54103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Indicates whether the function is a bound function created using
54113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // the bind function.
54123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  DECL_BOOLEAN_ACCESSORS(bound)
54133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
54143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Indicates that the function is anonymous (the name field can be set
54153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // through the API, which does not change this flag).
54163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  DECL_BOOLEAN_ACCESSORS(is_anonymous)
5417257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
54183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Is this a function or top-level/eval code.
54193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  DECL_BOOLEAN_ACCESSORS(is_function)
54203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
54213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Indicates that the function cannot be optimized.
54223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  DECL_BOOLEAN_ACCESSORS(dont_optimize)
54233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
54243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Indicates that the function cannot be inlined.
54253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  DECL_BOOLEAN_ACCESSORS(dont_inline)
54263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5427b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Indicates whether or not the code in the shared function support
5428b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // deoptimization.
5429b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  inline bool has_deoptimization_support();
5430b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
5431b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Enable deoptimization support through recompiled code.
5432b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void EnableDeoptimizationSupport(Code* recompiled);
5433b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
5434257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Disable (further) attempted optimization of all functions sharing this
54353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // shared function info.
54363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void DisableOptimization();
5437257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
5438b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Lookup the bailout ID and ASSERT that it exists in the non-optimized
5439b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // code, returns whether it asserted (i.e., always true if assertions are
5440b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // disabled).
5441b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  bool VerifyBailoutId(int id);
5442756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
5443402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  // Check whether a inlined constructor can be generated with the given
5444402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  // prototype.
5445402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  bool CanGenerateInlineConstructor(Object* prototype);
5446402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
54470d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // Prevents further attempts to generate inline constructors.
54480d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // To be called if generation failed for any reason.
54490d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  void ForbidInlineConstructor();
54500d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
5451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // For functions which only contains this property assignments this provides
5452a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // access to the names for the properties assigned.
5453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(this_property_assignments, Object)
5454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline int this_property_assignments_count();
5455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void set_this_property_assignments_count(int value);
5456a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  String* GetThisPropertyAssignmentName(int index);
5457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool IsThisPropertyAssignmentArgument(int index);
5458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int GetThisPropertyAssignmentArgument(int index);
5459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* GetThisPropertyAssignmentConstant(int index);
5460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // [source code]: Source code for the function.
5462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool HasSourceCode();
54633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Object> GetSourceCode();
5464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5465b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  inline int opt_count();
5466b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  inline void set_opt_count(int opt_count);
5467b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
5468b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Source size of this function.
5469b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int SourceSize();
5470b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
5471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Calculate the instance size.
5472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int CalculateInstanceSize();
5473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Calculate the number of in-object properties.
5475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int CalculateInObjectProperties();
5476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Dispatched behavior.
5478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Set max_length to -1 for unlimited length.
5479a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void SourceCodePrint(StringStream* accumulator, int max_length);
5480b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef OBJECT_PRINT
5481b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  inline void SharedFunctionInfoPrint() {
5482b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    SharedFunctionInfoPrint(stdout);
5483b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
5484b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void SharedFunctionInfoPrint(FILE* out);
5485b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif
5486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG
5487a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void SharedFunctionInfoVerify();
5488a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
5489a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
54908f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch  void ResetForNewContext(int new_ic_age);
54918f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch
54923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Helpers to compile the shared code.  Returns true on success, false on
54933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // failure (e.g., stack overflow during compilation).
54943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static bool EnsureCompiled(Handle<SharedFunctionInfo> shared,
54953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                             ClearExceptionFlag flag);
54963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static bool CompileLazy(Handle<SharedFunctionInfo> shared,
54973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                          ClearExceptionFlag flag);
54983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
54998f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch  void SharedFunctionInfoIterateBody(ObjectVisitor* v);
55008f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch
5501a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Casting.
5502a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline SharedFunctionInfo* cast(Object* obj);
5503a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Constants.
5505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kDontAdaptArgumentsSentinel = -1;
5506a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Layout description.
55086ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Pointer fields.
5509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kNameOffset = HeapObject::kHeaderSize;
5510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kCodeOffset = kNameOffset + kPointerSize;
55113bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  static const int kScopeInfoOffset = kCodeOffset + kPointerSize;
55123bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  static const int kConstructStubOffset = kScopeInfoOffset + kPointerSize;
55136ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static const int kInstanceClassNameOffset =
55146ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      kConstructStubOffset + kPointerSize;
55156ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static const int kFunctionDataOffset =
55166ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      kInstanceClassNameOffset + kPointerSize;
55176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static const int kScriptOffset = kFunctionDataOffset + kPointerSize;
55186ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static const int kDebugInfoOffset = kScriptOffset + kPointerSize;
55196ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static const int kInferredNameOffset = kDebugInfoOffset + kPointerSize;
55200d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  static const int kInitialMapOffset =
55216ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      kInferredNameOffset + kPointerSize;
55220d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  static const int kThisPropertyAssignmentsOffset =
55230d5e116f6aee03185f237311a943491bb079a768Kristian Monsen      kInitialMapOffset + kPointerSize;
55248f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch  // ic_age is a Smi field. It could be grouped with another Smi field into a
55258f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch  // PSEUDO_SMI_ACCESSORS pair (on x64), if one becomes available.
55268f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch  static const int kICAgeOffset = kThisPropertyAssignmentsOffset + kPointerSize;
55277f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch#if V8_HOST_ARCH_32_BIT
55287f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // Smi fields.
55296ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static const int kLengthOffset =
55308f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch      kICAgeOffset + kPointerSize;
55317f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  static const int kFormalParameterCountOffset = kLengthOffset + kPointerSize;
5532a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kExpectedNofPropertiesOffset =
55337f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      kFormalParameterCountOffset + kPointerSize;
55347f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  static const int kNumLiteralsOffset =
55357f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      kExpectedNofPropertiesOffset + kPointerSize;
5536a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kStartPositionAndTypeOffset =
55377f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      kNumLiteralsOffset + kPointerSize;
55387f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  static const int kEndPositionOffset =
55397f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      kStartPositionAndTypeOffset + kPointerSize;
55407f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  static const int kFunctionTokenPositionOffset =
55417f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      kEndPositionOffset + kPointerSize;
55427f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  static const int kCompilerHintsOffset =
55437f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      kFunctionTokenPositionOffset + kPointerSize;
55447f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  static const int kThisPropertyAssignmentsCountOffset =
55457f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      kCompilerHintsOffset + kPointerSize;
5546b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static const int kOptCountOffset =
5547b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      kThisPropertyAssignmentsCountOffset + kPointerSize;
55483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kAstNodeCountOffset = kOptCountOffset + kPointerSize;
55498f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch  static const int kDeoptCounterOffset = kAstNodeCountOffset + kPointerSize;
55508f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch
55518f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch
55527f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // Total size.
55533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kSize = kDeoptCounterOffset + kPointerSize;
55547f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch#else
55557f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // The only reason to use smi fields instead of int fields
55560d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // is to allow iteration without maps decoding during
55577f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // garbage collections.
55587f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // To avoid wasting space on 64-bit architectures we use
55597f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // the following trick: we group integer fields into pairs
55607f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // First integer in each pair is shifted left by 1.
55617f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // By doing this we guarantee that LSB of each kPointerSize aligned
55627f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // word is not set and thus this word cannot be treated as pointer
55637f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // to HeapObject during old space traversal.
55647f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  static const int kLengthOffset =
55658f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch      kICAgeOffset + kPointerSize;
55667f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  static const int kFormalParameterCountOffset =
55677f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      kLengthOffset + kIntSize;
55687f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
55697f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  static const int kExpectedNofPropertiesOffset =
55707f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      kFormalParameterCountOffset + kIntSize;
55717f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  static const int kNumLiteralsOffset =
55727f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      kExpectedNofPropertiesOffset + kIntSize;
55737f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
55747f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  static const int kEndPositionOffset =
55756ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      kNumLiteralsOffset + kIntSize;
55767f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  static const int kStartPositionAndTypeOffset =
55777f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      kEndPositionOffset + kIntSize;
55787f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
55797f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  static const int kFunctionTokenPositionOffset =
55807f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      kStartPositionAndTypeOffset + kIntSize;
55816ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static const int kCompilerHintsOffset =
5582a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      kFunctionTokenPositionOffset + kIntSize;
55837f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
5584a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kThisPropertyAssignmentsCountOffset =
55856ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      kCompilerHintsOffset + kIntSize;
5586b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static const int kOptCountOffset =
5587b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      kThisPropertyAssignmentsCountOffset + kIntSize;
55887f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
55893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kAstNodeCountOffset = kOptCountOffset + kIntSize;
55903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kDeoptCounterOffset = kAstNodeCountOffset + kIntSize;
55913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
55926ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Total size.
55933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kSize = kDeoptCounterOffset + kIntSize;
55947f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
55957f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch#endif
55960d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
55970d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // The construction counter for inobject slack tracking is stored in the
55980d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // most significant byte of compiler_hints which is otherwise unused.
55990d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // Its offset depends on the endian-ness of the architecture.
56000d5e116f6aee03185f237311a943491bb079a768Kristian Monsen#if __BYTE_ORDER == __LITTLE_ENDIAN
56010d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  static const int kConstructionCountOffset = kCompilerHintsOffset + 3;
56020d5e116f6aee03185f237311a943491bb079a768Kristian Monsen#elif __BYTE_ORDER == __BIG_ENDIAN
56030d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  static const int kConstructionCountOffset = kCompilerHintsOffset + 0;
56040d5e116f6aee03185f237311a943491bb079a768Kristian Monsen#else
56050d5e116f6aee03185f237311a943491bb079a768Kristian Monsen#error Unknown byte ordering
56060d5e116f6aee03185f237311a943491bb079a768Kristian Monsen#endif
56070d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
56086ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static const int kAlignedSize = POINTER_SIZE_ALIGN(kSize);
5609a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5610756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  typedef FixedBodyDescriptor<kNameOffset,
5611756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick                              kThisPropertyAssignmentsOffset + kPointerSize,
5612756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick                              kSize> BodyDescriptor;
5613756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
5614a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Bit positions in start_position_and_type.
5615a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // The source code start position is in the 30 most significant bits of
5616a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // the start_position_and_type field.
5617a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kIsExpressionBit = 0;
5618a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kIsTopLevelBit   = 1;
5619a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kStartPositionShift = 2;
5620a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kStartPositionMask = ~((1 << kStartPositionShift) - 1);
5621a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5622a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Bit positions in compiler_hints.
56233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  static const int kCodeAgeSize = 3;
56243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  static const int kCodeAgeMask = (1 << kCodeAgeSize) - 1;
56253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
56263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  enum CompilerHints {
56273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    kHasOnlySimpleThisPropertyAssignments,
56283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    kAllowLazyCompilation,
56293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    kLiveObjectsMayExist,
56303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    kCodeAgeShift,
56313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    kOptimizationDisabled = kCodeAgeShift + kCodeAgeSize,
56323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    kStrictModeFunction,
56333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    kExtendedModeFunction,
56343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    kUsesArguments,
56353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    kHasDuplicateParameters,
56363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    kNative,
56373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    kBoundFunction,
56383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    kIsAnonymous,
56393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    kNameShouldPrintAsAnonymous,
56403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    kIsFunction,
56413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    kDontOptimize,
56423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    kDontInline,
56433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    kCompilerHintsCount  // Pseudo entry
56443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  };
5645a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5646e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch private:
5647e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch#if V8_HOST_ARCH_32_BIT
5648e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // On 32 bit platforms, compiler hints is a smi.
5649e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  static const int kCompilerHintsSmiTagSize = kSmiTagSize;
5650e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  static const int kCompilerHintsSize = kPointerSize;
5651e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch#else
5652e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // On 64 bit platforms, compiler hints is not a smi, see comment above.
5653e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  static const int kCompilerHintsSmiTagSize = 0;
5654e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  static const int kCompilerHintsSize = kIntSize;
5655e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch#endif
5656e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
56573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  STATIC_ASSERT(SharedFunctionInfo::kCompilerHintsCount <=
56583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                SharedFunctionInfo::kCompilerHintsSize * kBitsPerByte);
56593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
5660e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch public:
5661257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Constants for optimizing codegen for strict mode function and
56623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // native tests.
56633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Allows to use byte-width instructions.
5664e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  static const int kStrictModeBitWithinByte =
5665e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      (kStrictModeFunction + kCompilerHintsSmiTagSize) % kBitsPerByte;
5666e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
56673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kExtendedModeBitWithinByte =
56683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      (kExtendedModeFunction + kCompilerHintsSmiTagSize) % kBitsPerByte;
56693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
56703fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  static const int kNativeBitWithinByte =
56713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      (kNative + kCompilerHintsSmiTagSize) % kBitsPerByte;
5672257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
5673e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch#if __BYTE_ORDER == __LITTLE_ENDIAN
5674e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  static const int kStrictModeByteOffset = kCompilerHintsOffset +
5675257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      (kStrictModeFunction + kCompilerHintsSmiTagSize) / kBitsPerByte;
56763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kExtendedModeByteOffset = kCompilerHintsOffset +
56773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      (kExtendedModeFunction + kCompilerHintsSmiTagSize) / kBitsPerByte;
56783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  static const int kNativeByteOffset = kCompilerHintsOffset +
56793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      (kNative + kCompilerHintsSmiTagSize) / kBitsPerByte;
5680e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch#elif __BYTE_ORDER == __BIG_ENDIAN
5681e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  static const int kStrictModeByteOffset = kCompilerHintsOffset +
5682257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      (kCompilerHintsSize - 1) -
5683257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      ((kStrictModeFunction + kCompilerHintsSmiTagSize) / kBitsPerByte);
56843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kExtendedModeByteOffset = kCompilerHintsOffset +
56853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      (kCompilerHintsSize - 1) -
56863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      ((kExtendedModeFunction + kCompilerHintsSmiTagSize) / kBitsPerByte);
56873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  static const int kNativeByteOffset = kCompilerHintsOffset +
5688257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      (kCompilerHintsSize - 1) -
56893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      ((kNative + kCompilerHintsSmiTagSize) / kBitsPerByte);
5690e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch#else
5691e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch#error Unknown byte ordering
5692e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch#endif
5693e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
5694e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch private:
5695a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DISALLOW_IMPLICIT_CONSTRUCTORS(SharedFunctionInfo);
5696a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
5697a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5698a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5699a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// JSFunction describes JavaScript functions.
5700a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass JSFunction: public JSObject {
5701a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
5702a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // [prototype_or_initial_map]:
5703a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(prototype_or_initial_map, Object)
5704a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5705589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // [shared]: The information about the function that
5706a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // can be shared by instances.
5707a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(shared, SharedFunctionInfo)
5708a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5709756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  inline SharedFunctionInfo* unchecked_shared();
5710756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
5711a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // [context]: The context for this function.
5712a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline Context* context();
5713a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline Object* unchecked_context();
5714a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void set_context(Object* context);
5715a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5716a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // [code]: The generated code object for this function.  Executed
5717a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // when the function is invoked, e.g. foo() or new foo(). See
5718a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // [[Call]] and [[Construct]] description in ECMA-262, section
5719a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // 8.6.2, page 27.
5720a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline Code* code();
5721b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  inline void set_code(Code* code);
5722b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  inline void ReplaceCode(Code* code);
5723a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5724756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  inline Code* unchecked_code();
5725756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
5726a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Tells whether this function is builtin.
5727a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline bool IsBuiltin();
5728a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5729b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Tells whether or not the function needs arguments adaption.
5730b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  inline bool NeedsArgumentsAdaption();
5731b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
5732b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Tells whether or not this function has been optimized.
5733b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  inline bool IsOptimized();
5734b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
57358b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  // Tells whether or not this function can be optimized.
57368b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  inline bool IsOptimizable();
57378b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
5738b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Mark this function for lazy recompilation. The function will be
5739b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // recompiled the next time it is executed.
5740b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void MarkForLazyRecompilation();
5741b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
57423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Helpers to compile this function.  Returns true on success, false on
57433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // failure (e.g., stack overflow during compilation).
57443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static bool CompileLazy(Handle<JSFunction> function,
57453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                          ClearExceptionFlag flag);
57463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static bool CompileOptimized(Handle<JSFunction> function,
57473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                               int osr_ast_id,
57483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                               ClearExceptionFlag flag);
57493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5750b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Tells whether or not the function is already marked for lazy
5751b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // recompilation.
5752b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  inline bool IsMarkedForLazyRecompilation();
5753b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
5754b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Check whether or not this function is inlineable.
5755b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  bool IsInlineable();
5756b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
57573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // [literals_or_bindings]: Fixed array holding either
57583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // the materialized literals or the bindings of a bound function.
5759a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  //
5760a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // If the function contains object, regexp or array literals, the
5761a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // literals array prefix contains the object, regexp, and array
5762a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // function to be used when creating these literals.  This is
5763a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // necessary so that we do not dynamically lookup the object, regexp
5764a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // or array functions.  Performing a dynamic lookup, we might end up
5765a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // using the functions from a new context that we should not have
5766a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // access to.
57673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //
57683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // On bound functions, the array is a (copy-on-write) fixed-array containing
57693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // the function that was bound, bound this-value and any bound
57703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // arguments. Bound functions never contain literals.
57713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  DECL_ACCESSORS(literals_or_bindings, FixedArray)
57723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
57733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline FixedArray* literals();
57743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline void set_literals(FixedArray* literals);
57753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
57763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline FixedArray* function_bindings();
57773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline void set_function_bindings(FixedArray* bindings);
5778a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5779a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // The initial map for an object created by this constructor.
5780a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline Map* initial_map();
5781a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void set_initial_map(Map* value);
57823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT inline MaybeObject* set_initial_map_and_cache_transitions(
57833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Map* value);
5784a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline bool has_initial_map();
5785a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5786a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Get and set the prototype property on a JSFunction. If the
5787a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // function has an initial map the prototype is set on the initial
5788a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // map. Otherwise, the prototype is put in the initial map field
5789a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // until an initial map is needed.
5790a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline bool has_prototype();
5791a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline bool has_instance_prototype();
5792a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline Object* prototype();
5793a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline Object* instance_prototype();
57943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT MaybeObject* SetInstancePrototype(Object* value);
57955913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* SetPrototype(Object* value);
5796a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
57976ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // After prototype is removed, it will not be created when accessed, and
57986ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // [[Construct]] from this function will not be allowed.
57996ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Object* RemovePrototype();
58006ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  inline bool should_have_prototype();
58016ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
5802a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Accessor for this function's initial map's [[class]]
5803a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // property. This is primarily used by ECMA native functions.  This
5804a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // method sets the class_name field of this function's initial map
5805a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // to a given value. It creates an initial map if this function does
5806a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // not have one. Note that this method does not copy the initial map
5807a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // if it has one already, but simply replaces it with the new value.
5808a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Instances created afterwards will have a map whose [[class]] is
5809a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // set to 'value', but there is no guarantees on instances created
5810a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // before.
5811a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* SetInstanceClassName(String* name);
5812a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5813a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Returns if this function has been compiled to native code yet.
5814a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline bool is_compiled();
5815a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5816b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // [next_function_link]: Field for linking functions. This list is treated as
5817b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // a weak list by the GC.
5818b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  DECL_ACCESSORS(next_function_link, Object)
5819b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
5820b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Prints the name of the function using PrintF.
5821b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  inline void PrintName() {
5822b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    PrintName(stdout);
5823b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
5824b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void PrintName(FILE* out);
5825b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
5826a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Casting.
5827a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline JSFunction* cast(Object* obj);
5828a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5829791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block  // Iterates the objects, including code objects indirectly referenced
5830791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block  // through pointers to the first instruction in the code object.
5831791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block  void JSFunctionIterateBody(int object_size, ObjectVisitor* v);
5832791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block
5833a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Dispatched behavior.
5834b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef OBJECT_PRINT
5835b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  inline void JSFunctionPrint() {
5836b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    JSFunctionPrint(stdout);
5837b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
5838b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void JSFunctionPrint(FILE* out);
5839b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif
5840a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG
5841a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void JSFunctionVerify();
5842a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
5843a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5844a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Returns the number of allocated literals.
5845a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline int NumberOfLiterals();
5846a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5847a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Retrieve the global context from a function's literal array.
5848a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static Context* GlobalContextFromLiterals(FixedArray* literals);
5849a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5850b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Layout descriptors. The last property (from kNonWeakFieldsEndOffset to
5851b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // kSize) is weak and has special handling during garbage collection.
5852791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block  static const int kCodeEntryOffset = JSObject::kHeaderSize;
5853756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  static const int kPrototypeOrInitialMapOffset =
5854791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block      kCodeEntryOffset + kPointerSize;
5855a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kSharedFunctionInfoOffset =
5856a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      kPrototypeOrInitialMapOffset + kPointerSize;
5857a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kContextOffset = kSharedFunctionInfoOffset + kPointerSize;
5858a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kLiteralsOffset = kContextOffset + kPointerSize;
5859b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static const int kNonWeakFieldsEndOffset = kLiteralsOffset + kPointerSize;
5860b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static const int kNextFunctionLinkOffset = kNonWeakFieldsEndOffset;
5861b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static const int kSize = kNextFunctionLinkOffset + kPointerSize;
5862a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5863a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Layout of the literals array.
5864a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kLiteralsPrefixSize = 1;
5865a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kLiteralGlobalContextIndex = 0;
58663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
58673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Layout of the bound-function binding array.
58683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kBoundFunctionIndex = 0;
58693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kBoundThisIndex = 1;
58703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kBoundArgumentsStartIndex = 2;
58713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5872a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
5873a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DISALLOW_IMPLICIT_CONSTRUCTORS(JSFunction);
5874a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
5875a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5876a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5877a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// JSGlobalProxy's prototype must be a JSGlobalObject or null,
5878a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// and the prototype is hidden. JSGlobalProxy always delegates
5879a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// property accesses to its prototype if the prototype is not null.
5880a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
5881a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A JSGlobalProxy can be reinitialized which will preserve its identity.
5882a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
5883a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Accessing a JSGlobalProxy requires security check.
5884a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5885a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass JSGlobalProxy : public JSObject {
5886a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
5887257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // [context]: the owner global context of this global proxy object.
5888a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // It is null value if this object is not used by any context.
5889a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(context, Object)
5890a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5891a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Casting.
5892a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline JSGlobalProxy* cast(Object* obj);
5893a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5894a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Dispatched behavior.
5895b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef OBJECT_PRINT
5896b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  inline void JSGlobalProxyPrint() {
5897b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    JSGlobalProxyPrint(stdout);
5898b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
5899b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void JSGlobalProxyPrint(FILE* out);
5900b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif
5901a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG
5902a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void JSGlobalProxyVerify();
5903a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
5904a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5905a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Layout description.
5906a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kContextOffset = JSObject::kHeaderSize;
5907a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kSize = kContextOffset + kPointerSize;
5908a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5909a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
5910a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DISALLOW_IMPLICIT_CONSTRUCTORS(JSGlobalProxy);
5911a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
5912a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5913a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5914a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Forward declaration.
5915a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass JSBuiltinsObject;
5916a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5917a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Common super class for JavaScript global objects and the special
5918a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// builtins global objects.
5919a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass GlobalObject: public JSObject {
5920a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
5921a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // [builtins]: the object holding the runtime routines written in JS.
5922a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(builtins, JSBuiltinsObject)
5923a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5924a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // [global context]: the global context corresponding to this global object.
5925a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(global_context, Context)
5926a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5927a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // [global receiver]: the global receiver object of the context
5928a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(global_receiver, JSObject)
5929a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5930a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Retrieve the property cell used to store a property.
5931b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  JSGlobalPropertyCell* GetPropertyCell(LookupResult* result);
5932a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
59335913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  // This is like GetProperty, but is used when you know the lookup won't fail
59345913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  // by throwing an exception.  This is for the debug and builtins global
59355913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  // objects, where it is known which properties can be expected to be present
59365913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  // on the object.
59375913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  Object* GetPropertyNoExceptionThrown(String* key) {
59385913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    Object* answer = GetProperty(key)->ToObjectUnchecked();
59395913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    return answer;
59405913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  }
59415913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck
5942a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Ensure that the global object has a cell for the given property name.
59433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static Handle<JSGlobalPropertyCell> EnsurePropertyCell(
59443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Handle<GlobalObject> global,
59453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Handle<String> name);
59463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // TODO(kmillikin): This function can be eliminated once the stub cache is
59473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // full handlified (and the static helper can be written directly).
59485913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* EnsurePropertyCell(String* name);
5949a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5950a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Casting.
5951a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline GlobalObject* cast(Object* obj);
5952a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5953a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Layout description.
5954a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kBuiltinsOffset = JSObject::kHeaderSize;
5955a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kGlobalContextOffset = kBuiltinsOffset + kPointerSize;
5956a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kGlobalReceiverOffset = kGlobalContextOffset + kPointerSize;
5957a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kHeaderSize = kGlobalReceiverOffset + kPointerSize;
5958a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5959a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
5960a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DISALLOW_IMPLICIT_CONSTRUCTORS(GlobalObject);
5961a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
5962a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5963a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5964a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// JavaScript global object.
5965a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass JSGlobalObject: public GlobalObject {
5966a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
5967a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Casting.
5968a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline JSGlobalObject* cast(Object* obj);
5969a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5970a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Dispatched behavior.
5971b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef OBJECT_PRINT
5972b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  inline void JSGlobalObjectPrint() {
5973b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    JSGlobalObjectPrint(stdout);
5974b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
5975b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void JSGlobalObjectPrint(FILE* out);
5976b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif
5977a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG
5978a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void JSGlobalObjectVerify();
5979a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
5980a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5981a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Layout description.
5982a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kSize = GlobalObject::kHeaderSize;
5983a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5984a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
5985a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DISALLOW_IMPLICIT_CONSTRUCTORS(JSGlobalObject);
5986a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
5987a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5988a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5989a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Builtins global object which holds the runtime routines written in
5990a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// JavaScript.
5991a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass JSBuiltinsObject: public GlobalObject {
5992a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
5993a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Accessors for the runtime routines written in JavaScript.
5994a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline Object* javascript_builtin(Builtins::JavaScript id);
5995a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void set_javascript_builtin(Builtins::JavaScript id, Object* value);
5996a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
59976ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Accessors for code of the runtime routines written in JavaScript.
59986ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  inline Code* javascript_builtin_code(Builtins::JavaScript id);
59996ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  inline void set_javascript_builtin_code(Builtins::JavaScript id, Code* value);
60006ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
6001a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Casting.
6002a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline JSBuiltinsObject* cast(Object* obj);
6003a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6004a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Dispatched behavior.
6005b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef OBJECT_PRINT
6006b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  inline void JSBuiltinsObjectPrint() {
6007b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    JSBuiltinsObjectPrint(stdout);
6008b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
6009b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void JSBuiltinsObjectPrint(FILE* out);
6010b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif
6011a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG
6012a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void JSBuiltinsObjectVerify();
6013a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
6014a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6015a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Layout description.  The size of the builtins object includes
60166ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // room for two pointers per runtime routine written in javascript
60176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // (function and code object).
6018a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kJSBuiltinsCount = Builtins::id_count;
6019a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kJSBuiltinsOffset = GlobalObject::kHeaderSize;
60206ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static const int kJSBuiltinsCodeOffset =
60216ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      GlobalObject::kHeaderSize + (kJSBuiltinsCount * kPointerSize);
6022a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kSize =
60236ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      kJSBuiltinsCodeOffset + (kJSBuiltinsCount * kPointerSize);
60246ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
60256ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static int OffsetOfFunctionWithId(Builtins::JavaScript id) {
60266ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    return kJSBuiltinsOffset + id * kPointerSize;
60276ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
60286ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
60296ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static int OffsetOfCodeWithId(Builtins::JavaScript id) {
60306ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    return kJSBuiltinsCodeOffset + id * kPointerSize;
60316ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
60326ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
6033a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
6034a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DISALLOW_IMPLICIT_CONSTRUCTORS(JSBuiltinsObject);
6035a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
6036a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6037a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
60383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Representation for JS Wrapper objects, String, Number, Boolean, etc.
6039a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass JSValue: public JSObject {
6040a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
6041a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // [value]: the object being wrapped.
6042a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(value, Object)
6043a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6044a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Casting.
6045a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline JSValue* cast(Object* obj);
6046a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6047a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Dispatched behavior.
6048b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef OBJECT_PRINT
6049b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  inline void JSValuePrint() {
6050b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    JSValuePrint(stdout);
6051b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
6052b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void JSValuePrint(FILE* out);
6053b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif
6054a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG
6055a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void JSValueVerify();
6056a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
6057a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6058a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Layout description.
6059a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kValueOffset = JSObject::kHeaderSize;
6060a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kSize = kValueOffset + kPointerSize;
6061a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6062a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
6063a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DISALLOW_IMPLICIT_CONSTRUCTORS(JSValue);
6064a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
6065a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
60661e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
60673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochclass DateCache;
60683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
60693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Representation for JS date objects.
60703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochclass JSDate: public JSObject {
60713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public:
60723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // If one component is NaN, all of them are, indicating a NaN time value.
60733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // [value]: the time value.
60743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  DECL_ACCESSORS(value, Object)
60753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // [year]: caches year. Either undefined, smi, or NaN.
60763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  DECL_ACCESSORS(year, Object)
60773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // [month]: caches month. Either undefined, smi, or NaN.
60783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  DECL_ACCESSORS(month, Object)
60793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // [day]: caches day. Either undefined, smi, or NaN.
60803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  DECL_ACCESSORS(day, Object)
60813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // [weekday]: caches day of week. Either undefined, smi, or NaN.
60823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  DECL_ACCESSORS(weekday, Object)
60833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // [hour]: caches hours. Either undefined, smi, or NaN.
60843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  DECL_ACCESSORS(hour, Object)
60853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // [min]: caches minutes. Either undefined, smi, or NaN.
60863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  DECL_ACCESSORS(min, Object)
60873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // [sec]: caches seconds. Either undefined, smi, or NaN.
60883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  DECL_ACCESSORS(sec, Object)
60893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // [cache stamp]: sample of the date cache stamp at the
60903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // moment when local fields were cached.
60913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  DECL_ACCESSORS(cache_stamp, Object)
60923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
60933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Casting.
60943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static inline JSDate* cast(Object* obj);
60953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
60963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Returns the date field with the specified index.
60973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // See FieldIndex for the list of date fields.
60983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static MaybeObject* GetField(Object* date, Smi* index);
60993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
61003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void SetValue(Object* value, bool is_value_nan);
61013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
61023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
61033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Dispatched behavior.
61043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#ifdef OBJECT_PRINT
61053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline void JSDatePrint() {
61063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    JSDatePrint(stdout);
61073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
61083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void JSDatePrint(FILE* out);
61093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif
61103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#ifdef DEBUG
61113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void JSDateVerify();
61123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif
61133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // The order is important. It must be kept in sync with date macros
61143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // in macros.py.
61153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  enum FieldIndex {
61163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    kDateValue,
61173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    kYear,
61183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    kMonth,
61193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    kDay,
61203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    kWeekday,
61213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    kHour,
61223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    kMinute,
61233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    kSecond,
61243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    kFirstUncachedField,
61253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    kMillisecond = kFirstUncachedField,
61263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    kDays,
61273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    kTimeInDay,
61283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    kFirstUTCField,
61293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    kYearUTC = kFirstUTCField,
61303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    kMonthUTC,
61313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    kDayUTC,
61323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    kWeekdayUTC,
61333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    kHourUTC,
61343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    kMinuteUTC,
61353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    kSecondUTC,
61363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    kMillisecondUTC,
61373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    kDaysUTC,
61383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    kTimeInDayUTC,
61393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    kTimezoneOffset
61403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  };
61413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
61423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Layout description.
61433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kValueOffset = JSObject::kHeaderSize;
61443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kYearOffset = kValueOffset + kPointerSize;
61453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kMonthOffset = kYearOffset + kPointerSize;
61463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kDayOffset = kMonthOffset + kPointerSize;
61473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kWeekdayOffset = kDayOffset + kPointerSize;
61483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kHourOffset = kWeekdayOffset  + kPointerSize;
61493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kMinOffset = kHourOffset + kPointerSize;
61503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kSecOffset = kMinOffset + kPointerSize;
61513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kCacheStampOffset = kSecOffset + kPointerSize;
61523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kSize = kCacheStampOffset + kPointerSize;
61533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
61543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch private:
61553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline Object* DoGetField(FieldIndex index);
61563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
61573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Object* GetUTCField(FieldIndex index, double value, DateCache* date_cache);
61583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
61593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Computes and caches the cacheable fields of the date.
61603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline void SetLocalFields(int64_t local_time_ms, DateCache* date_cache);
61613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
61623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
61633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  DISALLOW_IMPLICIT_CONSTRUCTORS(JSDate);
61643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch};
61653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
61663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
61671e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// Representation of message objects used for error reporting through
61681e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// the API. The messages are formatted in JavaScript so this object is
61691e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// a real JavaScript object. The information used for formatting the
61701e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// error messages are not directly accessible from JavaScript to
61711e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// prevent leaking information to user code called during error
61721e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// formatting.
61731e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockclass JSMessageObject: public JSObject {
61741e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block public:
61751e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // [type]: the type of error message.
61761e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  DECL_ACCESSORS(type, String)
61771e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
61781e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // [arguments]: the arguments for formatting the error message.
61791e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  DECL_ACCESSORS(arguments, JSArray)
61801e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
61811e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // [script]: the script from which the error message originated.
61821e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  DECL_ACCESSORS(script, Object)
61831e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
61841e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // [stack_trace]: the stack trace for this error message.
61851e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  DECL_ACCESSORS(stack_trace, Object)
61861e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
61871e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // [stack_frames]: an array of stack frames for this error object.
61881e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  DECL_ACCESSORS(stack_frames, Object)
61891e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
61901e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // [start_position]: the start position in the script for the error message.
61911e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  inline int start_position();
61921e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  inline void set_start_position(int value);
61931e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
61941e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // [end_position]: the end position in the script for the error message.
61951e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  inline int end_position();
61961e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  inline void set_end_position(int value);
61971e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
61981e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // Casting.
61991e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  static inline JSMessageObject* cast(Object* obj);
62001e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
62011e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // Dispatched behavior.
62021e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block#ifdef OBJECT_PRINT
62031e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  inline void JSMessageObjectPrint() {
62041e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    JSMessageObjectPrint(stdout);
62051e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
62061e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void JSMessageObjectPrint(FILE* out);
62071e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block#endif
62081e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block#ifdef DEBUG
62091e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void JSMessageObjectVerify();
62101e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block#endif
62111e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
62121e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // Layout description.
62131e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  static const int kTypeOffset = JSObject::kHeaderSize;
62141e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  static const int kArgumentsOffset = kTypeOffset + kPointerSize;
62151e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  static const int kScriptOffset = kArgumentsOffset + kPointerSize;
62161e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  static const int kStackTraceOffset = kScriptOffset + kPointerSize;
62171e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  static const int kStackFramesOffset = kStackTraceOffset + kPointerSize;
62181e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  static const int kStartPositionOffset = kStackFramesOffset + kPointerSize;
62191e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  static const int kEndPositionOffset = kStartPositionOffset + kPointerSize;
62201e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  static const int kSize = kEndPositionOffset + kPointerSize;
62211e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
62221e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  typedef FixedBodyDescriptor<HeapObject::kMapOffset,
62231e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block                              kStackFramesOffset + kPointerSize,
62241e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block                              kSize> BodyDescriptor;
62251e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block};
62261e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
62271e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
6228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Regular expressions
6229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The regular expression holds a single reference to a FixedArray in
6230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// the kDataOffset field.
6231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The FixedArray contains the following data:
6232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// - tag : type of regexp implementation (not compiled yet, atom or irregexp)
6233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// - reference to the original source string
6234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// - reference to the original flag string
6235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// If it is an atom regexp
6236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// - a reference to a literal string to search for
6237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// If it is an irregexp regexp:
6238257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// - a reference to code for ASCII inputs (bytecode or compiled), or a smi
6239257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// used for tracking the last usage (used for code flushing).
6240257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// - a reference to code for UC16 inputs (bytecode or compiled), or a smi
6241257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// used for tracking the last usage (used for code flushing)..
6242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// - max number of registers used by irregexp implementations.
6243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// - number of capture registers (output values) of the regexp.
6244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass JSRegExp: public JSObject {
6245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
6246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Meaning of Type:
6247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // NOT_COMPILED: Initial value. No data has been stored in the JSRegExp yet.
6248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ATOM: A simple string to match against using an indexOf operation.
6249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // IRREGEXP: Compiled with Irregexp.
6250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // IRREGEXP_NATIVE: Compiled to native code with Irregexp.
6251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  enum Type { NOT_COMPILED, ATOM, IRREGEXP };
6252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  enum Flag { NONE = 0, GLOBAL = 1, IGNORE_CASE = 2, MULTILINE = 4 };
6253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  class Flags {
6255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block   public:
6256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    explicit Flags(uint32_t value) : value_(value) { }
6257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    bool is_global() { return (value_ & GLOBAL) != 0; }
6258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    bool is_ignore_case() { return (value_ & IGNORE_CASE) != 0; }
6259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    bool is_multiline() { return (value_ & MULTILINE) != 0; }
6260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    uint32_t value() { return value_; }
6261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block   private:
6262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    uint32_t value_;
6263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  };
6264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(data, Object)
6266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline Type TypeTag();
6268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline int CaptureCount();
6269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline Flags GetFlags();
6270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline String* Pattern();
6271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline Object* DataAt(int index);
6272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Set implementation data after the object has been prepared.
6273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void SetDataAt(int index, Object* value);
6274257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
6275257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Used during GC when flushing code or setting age.
6276257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  inline Object* DataAtUnchecked(int index);
6277257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  inline void SetDataAtUnchecked(int index, Object* value, Heap* heap);
6278257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  inline Type TypeTagUnchecked();
6279257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
6280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static int code_index(bool is_ascii) {
6281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (is_ascii) {
6282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      return kIrregexpASCIICodeIndex;
6283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    } else {
6284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      return kIrregexpUC16CodeIndex;
6285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
6286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
6287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6288257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  static int saved_code_index(bool is_ascii) {
6289257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    if (is_ascii) {
6290257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      return kIrregexpASCIICodeSavedIndex;
6291257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    } else {
6292257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      return kIrregexpUC16CodeSavedIndex;
6293257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    }
6294257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
6295257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
6296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline JSRegExp* cast(Object* obj);
6297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Dispatched behavior.
6299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG
6300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void JSRegExpVerify();
6301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
6302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kDataOffset = JSObject::kHeaderSize;
6304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kSize = kDataOffset + kPointerSize;
6305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Indices in the data array.
6307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kTagIndex = 0;
6308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kSourceIndex = kTagIndex + 1;
6309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kFlagsIndex = kSourceIndex + 1;
6310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kDataIndex = kFlagsIndex + 1;
6311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // The data fields are used in different ways depending on the
6312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // value of the tag.
6313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Atom regexps (literal strings).
6314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kAtomPatternIndex = kDataIndex;
6315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kAtomDataSize = kAtomPatternIndex + 1;
6317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Irregexp compiled code or bytecode for ASCII. If compilation
6319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // fails, this fields hold an exception object that should be
6320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // thrown if the regexp is used again.
6321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kIrregexpASCIICodeIndex = kDataIndex;
6322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Irregexp compiled code or bytecode for UC16.  If compilation
6323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // fails, this fields hold an exception object that should be
6324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // thrown if the regexp is used again.
6325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kIrregexpUC16CodeIndex = kDataIndex + 1;
6326257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
6327257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Saved instance of Irregexp compiled code or bytecode for ASCII that
6328257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // is a potential candidate for flushing.
6329257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  static const int kIrregexpASCIICodeSavedIndex = kDataIndex + 2;
6330257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Saved instance of Irregexp compiled code or bytecode for UC16 that is
6331257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // a potential candidate for flushing.
6332257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  static const int kIrregexpUC16CodeSavedIndex = kDataIndex + 3;
6333257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
6334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Maximal number of registers used by either ASCII or UC16.
6335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Only used to check that there is enough stack space
6336257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  static const int kIrregexpMaxRegisterCountIndex = kDataIndex + 4;
6337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Number of captures in the compiled regexp.
6338257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  static const int kIrregexpCaptureCountIndex = kDataIndex + 5;
6339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kIrregexpDataSize = kIrregexpCaptureCountIndex + 1;
6341e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
6342e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Offsets directly into the data fixed array.
6343e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  static const int kDataTagOffset =
6344e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke      FixedArray::kHeaderSize + kTagIndex * kPointerSize;
6345e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  static const int kDataAsciiCodeOffset =
6346e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke      FixedArray::kHeaderSize + kIrregexpASCIICodeIndex * kPointerSize;
6347d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  static const int kDataUC16CodeOffset =
6348d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      FixedArray::kHeaderSize + kIrregexpUC16CodeIndex * kPointerSize;
6349e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  static const int kIrregexpCaptureCountOffset =
6350e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke      FixedArray::kHeaderSize + kIrregexpCaptureCountIndex * kPointerSize;
63516ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
63526ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // In-object fields.
63536ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static const int kSourceFieldIndex = 0;
63546ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static const int kGlobalFieldIndex = 1;
63556ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static const int kIgnoreCaseFieldIndex = 2;
63566ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static const int kMultilineFieldIndex = 3;
63576ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static const int kLastIndexFieldIndex = 4;
6358bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  static const int kInObjectFieldCount = 5;
6359257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
6360257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // The uninitialized value for a regexp code object.
6361257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  static const int kUninitializedValue = -1;
6362257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
6363257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // The compilation error value for the regexp code object. The real error
6364257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // object is in the saved code field.
6365257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  static const int kCompilationErrorValue = -2;
6366257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
6367257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // When we store the sweep generation at which we moved the code from the
6368257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // code index to the saved code index we mask it of to be in the [0:255]
6369257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // range.
6370257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  static const int kCodeAgeMask = 0xff;
6371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
6372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6373a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6374c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdochclass CompilationCacheShape : public BaseShape<HashTableKey*> {
6375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
6376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline bool IsMatch(HashTableKey* key, Object* value) {
6377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return key->IsMatch(value);
6378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
6379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6380a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline uint32_t Hash(HashTableKey* key) {
6381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return key->Hash();
6382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
6383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline uint32_t HashForObject(HashTableKey* key, Object* object) {
6385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return key->HashForObject(object);
6386a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
6387a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
63885913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT static MaybeObject* AsObject(HashTableKey* key) {
6389a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return key->AsObject();
6390a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
6391a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6392a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kPrefixSize = 0;
6393a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kEntrySize = 2;
6394a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
6395a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
63963ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
6397a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass CompilationCacheTable: public HashTable<CompilationCacheShape,
6398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                              HashTableKey*> {
6399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
6400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Find cached value for a string key, otherwise return null.
6401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* Lookup(String* src);
64023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Object* LookupEval(String* src,
64033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                     Context* context,
64043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                     LanguageMode language_mode,
64053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                     int scope_position);
6406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* LookupRegExp(String* source, JSRegExp::Flags flags);
64073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT MaybeObject* Put(String* src, Object* value);
64083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT MaybeObject* PutEval(String* src,
64093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                       Context* context,
64103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                       SharedFunctionInfo* value,
64113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                       int scope_position);
64123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT MaybeObject* PutRegExp(String* src,
64133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                         JSRegExp::Flags flags,
64143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                         FixedArray* value);
6415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6416b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Remove given value from cache.
6417b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void Remove(Object* value);
6418b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
6419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline CompilationCacheTable* cast(Object* obj);
6420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
6422a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationCacheTable);
6423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
6424a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6425a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
64266ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockclass CodeCache: public Struct {
64276ded16be15dd865a9b21ea304d5273c8be299c87Steve Block public:
64286ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  DECL_ACCESSORS(default_cache, FixedArray)
64296ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  DECL_ACCESSORS(normal_type_cache, Object)
64306ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
64316ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Add the code object to the cache.
64325913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* Update(String* name, Code* code);
64336ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
64346ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Lookup code object in the cache. Returns code object if found and undefined
64356ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // if not.
64366ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Object* Lookup(String* name, Code::Flags flags);
64376ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
64386ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Get the internal index of a code object in the cache. Returns -1 if the
64396ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // code object is not in that cache. This index can be used to later call
64406ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // RemoveByIndex. The cache cannot be modified between a call to GetIndex and
64416ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // RemoveByIndex.
64426ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  int GetIndex(Object* name, Code* code);
64436ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
64446ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Remove an object from the cache with the provided internal index.
64456ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void RemoveByIndex(Object* name, Code* code, int index);
64466ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
64476ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static inline CodeCache* cast(Object* obj);
64486ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
6449b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef OBJECT_PRINT
6450b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  inline void CodeCachePrint() {
6451b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    CodeCachePrint(stdout);
6452b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
6453b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void CodeCachePrint(FILE* out);
6454b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif
64556ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#ifdef DEBUG
64566ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void CodeCacheVerify();
64576ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#endif
64586ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
64596ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static const int kDefaultCacheOffset = HeapObject::kHeaderSize;
64606ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static const int kNormalTypeCacheOffset =
64616ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      kDefaultCacheOffset + kPointerSize;
64626ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static const int kSize = kNormalTypeCacheOffset + kPointerSize;
64636ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
64646ded16be15dd865a9b21ea304d5273c8be299c87Steve Block private:
64655913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* UpdateDefaultCache(String* name, Code* code);
64665913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* UpdateNormalTypeCache(String* name, Code* code);
64676ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Object* LookupDefaultCache(String* name, Code::Flags flags);
64686ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Object* LookupNormalTypeCache(String* name, Code::Flags flags);
64696ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
64706ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Code cache layout of the default cache. Elements are alternating name and
64716ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // code objects for non normal load/store/call IC's.
64726ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static const int kCodeCacheEntrySize = 2;
64736ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static const int kCodeCacheEntryNameOffset = 0;
64746ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static const int kCodeCacheEntryCodeOffset = 1;
64756ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
64766ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  DISALLOW_IMPLICIT_CONSTRUCTORS(CodeCache);
64776ded16be15dd865a9b21ea304d5273c8be299c87Steve Block};
64786ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
64796ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
6480c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdochclass CodeCacheHashTableShape : public BaseShape<HashTableKey*> {
64816ded16be15dd865a9b21ea304d5273c8be299c87Steve Block public:
64826ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static inline bool IsMatch(HashTableKey* key, Object* value) {
64836ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    return key->IsMatch(value);
64846ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
64856ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
64866ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static inline uint32_t Hash(HashTableKey* key) {
64876ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    return key->Hash();
64886ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
64896ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
64906ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static inline uint32_t HashForObject(HashTableKey* key, Object* object) {
64916ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    return key->HashForObject(object);
64926ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
64936ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
64945913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT static MaybeObject* AsObject(HashTableKey* key) {
64956ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    return key->AsObject();
64966ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
64976ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
64986ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static const int kPrefixSize = 0;
64996ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static const int kEntrySize = 2;
65006ded16be15dd865a9b21ea304d5273c8be299c87Steve Block};
65016ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
65026ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
65036ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockclass CodeCacheHashTable: public HashTable<CodeCacheHashTableShape,
65046ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                           HashTableKey*> {
65056ded16be15dd865a9b21ea304d5273c8be299c87Steve Block public:
65066ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Object* Lookup(String* name, Code::Flags flags);
65075913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* Put(String* name, Code* code);
65086ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
65096ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  int GetIndex(String* name, Code::Flags flags);
65106ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void RemoveByIndex(int index);
65116ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
65126ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static inline CodeCacheHashTable* cast(Object* obj);
65136ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
65146ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Initial size of the fixed array backing the hash table.
65156ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static const int kInitialSize = 64;
65166ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
65176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block private:
65186ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  DISALLOW_IMPLICIT_CONSTRUCTORS(CodeCacheHashTable);
65196ded16be15dd865a9b21ea304d5273c8be299c87Steve Block};
65206ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
65216ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
65223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochclass PolymorphicCodeCache: public Struct {
65233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch public:
65243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  DECL_ACCESSORS(cache, Object)
65253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
65263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static void Update(Handle<PolymorphicCodeCache> cache,
65273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                     MapHandleList* maps,
65283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                     Code::Flags flags,
65293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                     Handle<Code> code);
65303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
65313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT MaybeObject* Update(MapHandleList* maps,
65323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                      Code::Flags flags,
65333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                      Code* code);
65343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
65353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Returns an undefined value if the entry is not found.
65363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Object> Lookup(MapHandleList* maps, Code::Flags flags);
65373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
65383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  static inline PolymorphicCodeCache* cast(Object* obj);
65393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
65403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#ifdef OBJECT_PRINT
65413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  inline void PolymorphicCodeCachePrint() {
65423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    PolymorphicCodeCachePrint(stdout);
65433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
65443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  void PolymorphicCodeCachePrint(FILE* out);
65453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif
65463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#ifdef DEBUG
65473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  void PolymorphicCodeCacheVerify();
65483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif
65493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
65503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  static const int kCacheOffset = HeapObject::kHeaderSize;
65513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  static const int kSize = kCacheOffset + kPointerSize;
65523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
65533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch private:
65543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  DISALLOW_IMPLICIT_CONSTRUCTORS(PolymorphicCodeCache);
65553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch};
65563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
65573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
65583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochclass PolymorphicCodeCacheHashTable
65593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    : public HashTable<CodeCacheHashTableShape, HashTableKey*> {
65603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch public:
65613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Object* Lookup(MapHandleList* maps, int code_kind);
65623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
65633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT MaybeObject* Put(MapHandleList* maps,
65643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                   int code_kind,
65653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                   Code* code);
65663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
65673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  static inline PolymorphicCodeCacheHashTable* cast(Object* obj);
65683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
65693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  static const int kInitialSize = 64;
65703fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch private:
65713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  DISALLOW_IMPLICIT_CONSTRUCTORS(PolymorphicCodeCacheHashTable);
65723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch};
65733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
65743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
65753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochclass TypeFeedbackInfo: public Struct {
65763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public:
65773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline int ic_total_count();
65783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline void set_ic_total_count(int count);
65793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
65808f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch  inline int ic_with_type_info_count();
65818f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch  inline void set_ic_with_type_info_count(int count);
65823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
65833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  DECL_ACCESSORS(type_feedback_cells, TypeFeedbackCells)
65843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
65853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static inline TypeFeedbackInfo* cast(Object* obj);
65863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
65873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#ifdef OBJECT_PRINT
65883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline void TypeFeedbackInfoPrint() {
65893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    TypeFeedbackInfoPrint(stdout);
65903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
65913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void TypeFeedbackInfoPrint(FILE* out);
65923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif
65933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#ifdef DEBUG
65943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void TypeFeedbackInfoVerify();
65953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif
65963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
65973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kIcTotalCountOffset = HeapObject::kHeaderSize;
65983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kIcWithTypeinfoCountOffset =
65993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      kIcTotalCountOffset + kPointerSize;
66003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kTypeFeedbackCellsOffset =
66013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      kIcWithTypeinfoCountOffset + kPointerSize;
66023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kSize = kTypeFeedbackCellsOffset + kPointerSize;
66033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
66043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch private:
66053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  DISALLOW_IMPLICIT_CONSTRUCTORS(TypeFeedbackInfo);
66063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch};
66073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
66083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
66093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Representation of a slow alias as part of a non-strict arguments objects.
66103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// For fast aliases (if HasNonStrictArgumentsElements()):
66113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// - the parameter map contains an index into the context
66123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// - all attributes of the element have default values
66133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// For slow aliases (if HasDictionaryArgumentsElements()):
66143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// - the parameter map contains no fast alias mapping (i.e. the hole)
66153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// - this struct (in the slow backing store) contains an index into the context
66163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// - all attributes are available as part if the property details
66173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochclass AliasedArgumentsEntry: public Struct {
66183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public:
66193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline int aliased_context_slot();
66203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline void set_aliased_context_slot(int count);
66213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
66223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static inline AliasedArgumentsEntry* cast(Object* obj);
66233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
66243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#ifdef OBJECT_PRINT
66253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline void AliasedArgumentsEntryPrint() {
66263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    AliasedArgumentsEntryPrint(stdout);
66273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
66283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void AliasedArgumentsEntryPrint(FILE* out);
66293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif
66303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#ifdef DEBUG
66313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void AliasedArgumentsEntryVerify();
66323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif
66333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
66343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kAliasedContextSlot = HeapObject::kHeaderSize;
66353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kSize = kAliasedContextSlot + kPointerSize;
66363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
66373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch private:
66383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  DISALLOW_IMPLICIT_CONSTRUCTORS(AliasedArgumentsEntry);
66393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch};
66403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
66413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
6642a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockenum AllowNullsFlag {ALLOW_NULLS, DISALLOW_NULLS};
6643a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockenum RobustnessFlag {ROBUST_STRING_TRAVERSAL, FAST_STRING_TRAVERSAL};
6644a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6645a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6646a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass StringHasher {
6647a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
6648c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch  explicit inline StringHasher(int length, uint32_t seed);
6649a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6650a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Returns true if the hash of this string can be computed without
6651a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // looking at the contents.
6652a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline bool has_trivial_hash();
6653a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6654a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Add a character to the hash and update the array index calculation.
66553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline void AddCharacter(uint32_t c);
6656a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6657a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Adds a character to the hash but does not update the array index
6658a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // calculation.  This can only be called when it has been verified
6659a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // that the input is not an array index.
66603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline void AddCharacterNoIndex(uint32_t c);
66613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
66623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Add a character above 0xffff as a surrogate pair.  These can get into
66633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // the hasher through the routines that take a UTF-8 string and make a symbol.
66643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void AddSurrogatePair(uc32 c);
66653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void AddSurrogatePairNoIndex(uc32 c);
6666a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6667a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Returns the value to store in the hash field of a string with
6668a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // the given length and contents.
6669a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  uint32_t GetHashField();
6670a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6671a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Returns true if the characters seen so far make up a legal array
6672a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // index.
6673a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool is_array_index() { return is_array_index_; }
6674a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6675a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool is_valid() { return is_valid_; }
6676a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6677a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void invalidate() { is_valid_ = false; }
6678a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
667980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  // Calculated hash value for a string consisting of 1 to
668080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  // String::kMaxArrayIndexSize digits with no leading zeros (except "0").
668180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  // value is represented decimal value.
66829ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick  static uint32_t MakeArrayIndexHash(uint32_t value, int length);
668380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
6684c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch  // No string is allowed to have a hash of zero.  That value is reserved
6685c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch  // for internal properties.  If the hash calculation yields zero then we
6686c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch  // use 27 instead.
6687c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch  static const int kZeroHash = 27;
6688c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch
6689a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
6690a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  uint32_t array_index() {
6691a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    ASSERT(is_array_index());
6692a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return array_index_;
6693a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
6694a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6695a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline uint32_t GetHash();
6696a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6697a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int length_;
6698a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  uint32_t raw_running_hash_;
6699a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  uint32_t array_index_;
6700a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool is_array_index_;
6701a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool is_first_char_;
6702a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool is_valid_;
6703d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  friend class TwoCharHashTableKey;
6704a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
6705a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6706a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
670744f0eee88ff00398ff7f715fab053374d808c90dSteve Block// Calculates string hash.
670844f0eee88ff00398ff7f715fab053374d808c90dSteve Blocktemplate <typename schar>
6709c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdochinline uint32_t HashSequentialString(const schar* chars,
6710c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch                                     int length,
6711c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch                                     uint32_t seed);
671244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
671344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
6714a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The characteristics of a string are stored in its map.  Retrieving these
6715a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// few bits of information is moderately expensive, involving two memory
6716a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// loads where the second is dependent on the first.  To improve efficiency
6717a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// the shape of the string is given its own class so that it can be retrieved
6718a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// once and used for several string operations.  A StringShape is small enough
6719a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// to be passed by value and is immutable, but be aware that flattening a
6720a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// string can potentially alter its shape.  Also be aware that a GC caused by
6721a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// something else can alter the shape of a string due to ConsString
6722a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// shortcutting.  Keeping these restrictions in mind has proven to be error-
6723a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// prone and so we no longer put StringShapes in variables unless there is a
6724a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// concrete performance benefit at that particular point in the code.
6725a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass StringShape BASE_EMBEDDED {
6726a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
6727a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline explicit StringShape(String* s);
6728a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline explicit StringShape(Map* s);
6729a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline explicit StringShape(InstanceType t);
6730a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline bool IsSequential();
6731a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline bool IsExternal();
6732a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline bool IsCons();
673369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  inline bool IsSliced();
673469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  inline bool IsIndirect();
6735a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline bool IsExternalAscii();
6736a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline bool IsExternalTwoByte();
6737a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline bool IsSequentialAscii();
6738a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline bool IsSequentialTwoByte();
6739a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline bool IsSymbol();
6740a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline StringRepresentationTag representation_tag();
674169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  inline uint32_t encoding_tag();
6742a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline uint32_t full_representation_tag();
6743a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline uint32_t size_tag();
6744a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG
6745a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline uint32_t type() { return type_; }
6746a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void invalidate() { valid_ = false; }
6747a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline bool valid() { return valid_; }
6748a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#else
6749a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void invalidate() { }
6750a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
67513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
6752a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
6753a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  uint32_t type_;
6754a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG
6755a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void set_valid() { valid_ = true; }
6756a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool valid_;
6757a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#else
6758a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void set_valid() { }
6759a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
6760a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
6761a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6762a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6763a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The String abstract class captures JavaScript string values:
6764a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
6765a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Ecma-262:
6766a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//  4.3.16 String Value
6767a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//    A string value is a member of the type String and is a finite
6768a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//    ordered sequence of zero or more 16-bit unsigned integer values.
6769a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
6770a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// All string values have a length field.
6771a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass String: public HeapObject {
6772a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
677369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  // Representation of the flat content of a String.
677469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  // A non-flat string doesn't have flat content.
677569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  // A flat string has content that's encoded as a sequence of either
677669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  // ASCII chars or two-byte UC16.
677769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  // Returned by String::GetFlatContent().
677869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  class FlatContent {
677969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch   public:
678069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    // Returns true if the string is flat and this structure contains content.
678169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    bool IsFlat() { return state_ != NON_FLAT; }
678269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    // Returns true if the structure contains ASCII content.
678369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    bool IsAscii() { return state_ == ASCII; }
678469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    // Returns true if the structure contains two-byte content.
678569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    bool IsTwoByte() { return state_ == TWO_BYTE; }
678669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
678769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    // Return the ASCII content of the string. Only use if IsAscii() returns
678869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    // true.
678969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    Vector<const char> ToAsciiVector() {
679069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch      ASSERT_EQ(ASCII, state_);
679169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch      return Vector<const char>::cast(buffer_);
679269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    }
679369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    // Return the two-byte content of the string. Only use if IsTwoByte()
679469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    // returns true.
679569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    Vector<const uc16> ToUC16Vector() {
679669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch      ASSERT_EQ(TWO_BYTE, state_);
679769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch      return Vector<const uc16>::cast(buffer_);
679869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    }
679969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
680069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch   private:
680169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    enum State { NON_FLAT, ASCII, TWO_BYTE };
680269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
680369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    // Constructors only used by String::GetFlatContent().
680469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    explicit FlatContent(Vector<const char> chars)
680569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch        : buffer_(Vector<const byte>::cast(chars)),
680669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch          state_(ASCII) { }
680769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    explicit FlatContent(Vector<const uc16> chars)
680869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch        : buffer_(Vector<const byte>::cast(chars)),
680969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch          state_(TWO_BYTE) { }
681069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    FlatContent() : buffer_(), state_(NON_FLAT) { }
681169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
681269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    Vector<const byte> buffer_;
681369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    State state_;
681469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
681569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    friend class String;
681669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  };
681769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
6818a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Get and set the length of the string.
6819a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline int length();
6820a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void set_length(int value);
6821a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6822d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // Get and set the hash field of the string.
6823d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  inline uint32_t hash_field();
6824d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  inline void set_hash_field(uint32_t value);
6825a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
682669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  // Returns whether this string has only ASCII chars, i.e. all of them can
682769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  // be ASCII encoded.  This might be the case even if the string is
682869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  // two-byte.  Such strings may appear when the embedder prefers
682969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  // two-byte external representations even for ASCII data.
6830a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline bool IsAsciiRepresentation();
6831a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline bool IsTwoByteRepresentation();
6832a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
683369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  // Cons and slices have an encoding flag that may not represent the actual
683469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  // encoding of the underlying string.  This is taken into account here.
683569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  // Requires: this->IsFlat()
683669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  inline bool IsAsciiRepresentationUnderneath();
683769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  inline bool IsTwoByteRepresentationUnderneath();
683869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
68399dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  // NOTE: this should be considered only a hint.  False negatives are
68409dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  // possible.
68419dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  inline bool HasOnlyAsciiChars();
68426ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
6843a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Get and set individual two byte chars in the string.
6844a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void Set(int index, uint16_t value);
6845a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Get individual two byte char in the string.  Repeated calls
6846a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // to this method are not efficient unless the string is flat.
6847a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline uint16_t Get(int index);
6848a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6849f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // Try to flatten the string.  Checks first inline to see if it is
6850f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // necessary.  Does nothing if the string is not a cons string.
6851f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // Flattening allocates a sequential string with the same data as
6852f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // the given string and mutates the cons string to a degenerate
6853f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // form, where the first component is the new sequential string and
6854f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // the second component is the empty string.  If allocation fails,
6855f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // this function returns a failure.  If flattening succeeds, this
6856f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // function returns the sequential string that is now the first
6857f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // component of the cons string.
6858f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  //
6859f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // Degenerate cons strings are handled specially by the garbage
6860f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // collector (see IsShortcutCandidate).
6861f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  //
6862f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // Use FlattenString from Handles.cc to flatten even in case an
6863f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // allocation failure happens.
68645913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  inline MaybeObject* TryFlatten(PretenureFlag pretenure = NOT_TENURED);
6865a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6866f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // Convenience function.  Has exactly the same behavior as
6867f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // TryFlatten(), except in the case of failure returns the original
6868f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // string.
6869f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  inline String* TryFlattenGetString(PretenureFlag pretenure = NOT_TENURED);
6870f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
687169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  // Tries to return the content of a flat string as a structure holding either
687269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  // a flat vector of char or of uc16.
687369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  // If the string isn't flat, and therefore doesn't have flat content, the
687469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  // returned structure will report so, and can't provide a vector of either
687569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  // kind.
687669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  FlatContent GetFlatContent();
687769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
687869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  // Returns the parent of a sliced string or first part of a flat cons string.
687969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  // Requires: StringShape(this).IsIndirect() && this->IsFlat()
688069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  inline String* GetUnderlying();
6881a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6882a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Mark the string as an undetectable object. It only applies to
68833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // ASCII and two byte string types.
6884a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool MarkAsUndetectable();
6885a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6886d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // Return a substring.
68875913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* SubString(int from,
68885913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck                                         int to,
68895913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck                                         PretenureFlag pretenure = NOT_TENURED);
6890a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6891a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // String equality operations.
6892a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline bool Equals(String* other);
6893a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool IsEqualTo(Vector<const char> str);
68949fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  bool IsAsciiEqualTo(Vector<const char> str);
68959fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  bool IsTwoByteEqualTo(Vector<const uc16> str);
6896a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6897a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Return a UTF8 representation of the string.  The string is null
6898a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // terminated but may optionally contain nulls.  Length is returned
6899a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // in length_output if length_output is not a null pointer  The string
6900a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // should be nearly flat, otherwise the performance of this method may
6901a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // be very slow (quadratic in the length).  Setting robustness_flag to
6902a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ROBUST_STRING_TRAVERSAL invokes behaviour that is robust  This means it
6903a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // handles unexpected data without causing assert failures and it does not
6904a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // do any heap allocations.  This is useful when printing stack traces.
6905589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  SmartArrayPointer<char> ToCString(AllowNullsFlag allow_nulls,
6906589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch                                    RobustnessFlag robustness_flag,
6907589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch                                    int offset,
6908589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch                                    int length,
6909589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch                                    int* length_output = 0);
6910589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  SmartArrayPointer<char> ToCString(
6911a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      AllowNullsFlag allow_nulls = DISALLOW_NULLS,
6912a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      RobustnessFlag robustness_flag = FAST_STRING_TRAVERSAL,
6913a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      int* length_output = 0);
6914a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6915a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Return a 16 bit Unicode representation of the string.
6916a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // The string should be nearly flat, otherwise the performance of
6917a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // of this method may be very bad.  Setting robustness_flag to
6918a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ROBUST_STRING_TRAVERSAL invokes behaviour that is robust  This means it
6919a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // handles unexpected data without causing assert failures and it does not
6920a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // do any heap allocations.  This is useful when printing stack traces.
6921589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  SmartArrayPointer<uc16> ToWideCString(
6922a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      RobustnessFlag robustness_flag = FAST_STRING_TRAVERSAL);
6923a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6924a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Tells whether the hash code has been computed.
6925a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline bool HasHashCode();
6926a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6927a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Returns a hash value used for the property table
6928a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline uint32_t Hash();
6929a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6930d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  static uint32_t ComputeHashField(unibrow::CharacterStream* buffer,
6931c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch                                   int length,
6932c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch                                   uint32_t seed);
6933a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6934a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static bool ComputeArrayIndex(unibrow::CharacterStream* buffer,
6935a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                uint32_t* index,
6936a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                int length);
6937a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6938a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Externalization.
6939a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool MakeExternal(v8::String::ExternalStringResource* resource);
6940a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool MakeExternal(v8::String::ExternalAsciiStringResource* resource);
6941a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6942a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Conversion.
6943a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline bool AsArrayIndex(uint32_t* index);
6944a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6945a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Casting.
6946a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline String* cast(Object* obj);
6947a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6948a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void PrintOn(FILE* out);
6949a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6950a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // For use during stack traces.  Performs rudimentary sanity check.
6951a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool LooksValid();
6952a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6953a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Dispatched behavior.
6954a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void StringShortPrint(StringStream* accumulator);
6955b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef OBJECT_PRINT
6956b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  inline void StringPrint() {
6957b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    StringPrint(stdout);
6958b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
6959b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void StringPrint(FILE* out);
696069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
696169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  char* ToAsciiArray();
6962b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif
6963a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG
6964a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void StringVerify();
6965a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
6966a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline bool IsFlat();
6967a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6968a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Layout description.
6969a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kLengthOffset = HeapObject::kHeaderSize;
69706ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static const int kHashFieldOffset = kLengthOffset + kPointerSize;
69717f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  static const int kSize = kHashFieldOffset + kPointerSize;
6972a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6973d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // Maximum number of characters to consider when trying to convert a string
6974d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // value into an array index.
6975a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kMaxArrayIndexSize = 10;
6976a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
69773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Max ASCII char code.
6978a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kMaxAsciiCharCode = unibrow::Utf8::kMaxOneByteChar;
6979a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const unsigned kMaxAsciiCharCodeU = unibrow::Utf8::kMaxOneByteChar;
69803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kMaxUtf16CodeUnit = 0xffff;
6981a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6982a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Mask constant for checking if a string has a computed hash code
6983a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // and if it is an array index.  The least significant bit indicates
6984a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // whether a hash code has been computed.  If the hash code has been
6985a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // computed the 2nd bit tells whether the string can be used as an
6986a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // array index.
69877f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  static const int kHashNotComputedMask = 1;
69887f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  static const int kIsNotArrayIndexMask = 1 << 1;
69897f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  static const int kNofHashBitFields = 2;
6990a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6991d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // Shift constant retrieving hash code from hash field.
69927f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  static const int kHashShift = kNofHashBitFields;
6993d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
6994c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch  // Only these bits are relevant in the hash, since the top two are shifted
6995c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch  // out.
6996c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch  static const uint32_t kHashBitMask = 0xffffffffu >> kHashShift;
6997c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch
6998a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Array index strings this short can keep their index in the hash
6999a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // field.
7000a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kMaxCachedArrayIndexLength = 7;
7001a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7002d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // For strings which are array indexes the hash value has the string length
7003d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // mixed into the hash, mainly to avoid a hash value of zero which would be
7004d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // the case for the string '0'. 24 bits are used for the array index value.
70057f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  static const int kArrayIndexValueBits = 24;
70067f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  static const int kArrayIndexLengthBits =
70077f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      kBitsPerInt - kArrayIndexValueBits - kNofHashBitFields;
70087f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
70097f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  STATIC_CHECK((kArrayIndexLengthBits > 0));
70109ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick  STATIC_CHECK(kMaxArrayIndexSize < (1 << kArrayIndexLengthBits));
70117f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
70127f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  static const int kArrayIndexHashLengthShift =
70137f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      kArrayIndexValueBits + kNofHashBitFields;
70147f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
7015d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  static const int kArrayIndexHashMask = (1 << kArrayIndexHashLengthShift) - 1;
70167f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
70177f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  static const int kArrayIndexValueMask =
70187f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      ((1 << kArrayIndexValueBits) - 1) << kHashShift;
70197f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
70207f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // Check that kMaxCachedArrayIndexLength + 1 is a power of two so we
70217f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // could use a mask to test if the length of string is less than or equal to
70227f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // kMaxCachedArrayIndexLength.
70237f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  STATIC_CHECK(IS_POWER_OF_TWO(kMaxCachedArrayIndexLength + 1));
70247f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
70257f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  static const int kContainsCachedArrayIndexMask =
70267f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      (~kMaxCachedArrayIndexLength << kArrayIndexHashLengthShift) |
70277f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      kIsNotArrayIndexMask;
7028d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
7029d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // Value of empty hash field indicating that the hash is not computed.
70307f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  static const int kEmptyHashField =
70317f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      kIsNotArrayIndexMask | kHashNotComputedMask;
70327f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
70337f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // Value of hash field containing computed hash equal to zero.
70347f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  static const int kZeroHash = kIsNotArrayIndexMask;
7035d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
7036d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // Maximal string length.
7037d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  static const int kMaxLength = (1 << (32 - 2)) - 1;
7038d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
7039d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // Max length for computing hash. For strings longer than this limit the
7040d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // string length is used as the hash value.
7041d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  static const int kMaxHashCalcLength = 16383;
7042a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7043a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Limit for truncation in short printing.
7044a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kMaxShortPrintLength = 1024;
7045a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7046a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Support for regular expressions.
7047a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  const uc16* GetTwoByteData();
7048a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  const uc16* GetTwoByteData(unsigned start);
7049a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7050a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Support for StringInputBuffer
7051a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const unibrow::byte* ReadBlock(String* input,
7052a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                        unibrow::byte* util_buffer,
7053a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                        unsigned capacity,
7054a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                        unsigned* remaining,
7055a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                        unsigned* offset);
7056a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const unibrow::byte* ReadBlock(String** input,
7057a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                        unibrow::byte* util_buffer,
7058a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                        unsigned capacity,
7059a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                        unsigned* remaining,
7060a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                        unsigned* offset);
7061a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7062a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Helper function for flattening strings.
7063a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  template <typename sinkchar>
7064a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static void WriteToFlat(String* source,
7065a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          sinkchar* sink,
7066a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          int from,
7067a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          int to);
7068a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
70699fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  static inline bool IsAscii(const char* chars, int length) {
70709fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block    const char* limit = chars + length;
70719fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block#ifdef V8_HOST_CAN_READ_UNALIGNED
70729fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block    ASSERT(kMaxAsciiCharCode == 0x7F);
70739fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block    const uintptr_t non_ascii_mask = kUintptrAllBitsSet / 0xFF * 0x80;
70749fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block    while (chars <= limit - sizeof(uintptr_t)) {
70759fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block      if (*reinterpret_cast<const uintptr_t*>(chars) & non_ascii_mask) {
70769fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block        return false;
70779fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block      }
70789fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block      chars += sizeof(uintptr_t);
70799fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block    }
70809fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block#endif
70819fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block    while (chars < limit) {
70829fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block      if (static_cast<uint8_t>(*chars) > kMaxAsciiCharCodeU) return false;
70839fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block      ++chars;
70849fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block    }
70859fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block    return true;
70869fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  }
70879fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block
70889fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  static inline bool IsAscii(const uc16* chars, int length) {
70899fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block    const uc16* limit = chars + length;
70909fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block    while (chars < limit) {
70919fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block      if (*chars > kMaxAsciiCharCodeU) return false;
70929fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block      ++chars;
70939fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block    }
70949fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block    return true;
70959fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  }
70969fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block
7097a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block protected:
7098a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  class ReadBlockBuffer {
7099a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block   public:
7100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    ReadBlockBuffer(unibrow::byte* util_buffer_,
7101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                    unsigned cursor_,
7102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                    unsigned capacity_,
7103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                    unsigned remaining_) :
7104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      util_buffer(util_buffer_),
7105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      cursor(cursor_),
7106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      capacity(capacity_),
7107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      remaining(remaining_) {
7108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
7109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    unibrow::byte* util_buffer;
7110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    unsigned       cursor;
7111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    unsigned       capacity;
7112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    unsigned       remaining;
7113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  };
7114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline const unibrow::byte* ReadBlock(String* input,
7116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                               ReadBlockBuffer* buffer,
7117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                               unsigned* offset,
7118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                               unsigned max_chars);
7119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static void ReadBlockIntoBuffer(String* input,
7120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                  ReadBlockBuffer* buffer,
7121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                  unsigned* offset_ptr,
7122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                  unsigned max_chars);
7123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
7125f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // Try to flatten the top level ConsString that is hiding behind this
7126f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // string.  This is a no-op unless the string is a ConsString.  Flatten
7127f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // mutates the ConsString and might return a failure.
71285913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* SlowTryFlatten(PretenureFlag pretenure);
7129f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
71307f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  static inline bool IsHashFieldComputed(uint32_t field);
71317f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
7132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Slow case of String::Equals.  This implementation works on any strings
7133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // but it is most efficient on strings that are almost flat.
7134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool SlowEquals(String* other);
7135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Slow case of AsArrayIndex.
7137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool SlowAsArrayIndex(uint32_t* index);
7138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Compute and set the hash code.
7140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  uint32_t ComputeAndSetHash();
7141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DISALLOW_IMPLICIT_CONSTRUCTORS(String);
7143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
7144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The SeqString abstract class captures sequential string values.
7147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass SeqString: public String {
7148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
7149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Casting.
7150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline SeqString* cast(Object* obj);
7151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
71523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Layout description.
71533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kHeaderSize = String::kSize;
71543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
7155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
7156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DISALLOW_IMPLICIT_CONSTRUCTORS(SeqString);
7157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
7158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
71603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// The AsciiString class captures sequential ASCII string objects.
71613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Each character in the AsciiString is an ASCII character.
7162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass SeqAsciiString: public SeqString {
7163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
7164ac95265630a4e0c317a7a7201d17a57df7d9bcceLeon Clarke  static const bool kHasAsciiEncoding = true;
7165ac95265630a4e0c317a7a7201d17a57df7d9bcceLeon Clarke
7166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Dispatched behavior.
7167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline uint16_t SeqAsciiStringGet(int index);
7168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void SeqAsciiStringSet(int index, uint16_t value);
7169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Get the address of the characters in this string.
7171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline Address GetCharsAddress();
7172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline char* GetChars();
7174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Casting
7176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline SeqAsciiString* cast(Object* obj);
7177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Garbage collection support.  This method is called by the
7179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // garbage collector to compute the actual size of an AsciiString
7180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // instance.
7181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline int SeqAsciiStringSize(InstanceType instance_type);
7182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Computes the size for an AsciiString instance of a given length.
7184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static int SizeFor(int length) {
71857f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    return OBJECT_POINTER_ALIGN(kHeaderSize + length * kCharSize);
7186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
7187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7188e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Maximal memory usage for a single sequential ASCII string.
71893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kMaxSize = 512 * MB - 1;
7190e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Maximal length of a single sequential ASCII string.
7191e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Q.v. String::kMaxLength which is the maximal size of concatenated strings.
7192e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  static const int kMaxLength = (kMaxSize - kHeaderSize);
7193e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
7194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Support for StringInputBuffer.
7195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void SeqAsciiStringReadBlockIntoBuffer(ReadBlockBuffer* buffer,
7196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                                unsigned* offset,
7197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                                unsigned chars);
7198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline const unibrow::byte* SeqAsciiStringReadBlock(unsigned* remaining,
7199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                                      unsigned* offset,
7200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                                      unsigned chars);
7201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
7203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DISALLOW_IMPLICIT_CONSTRUCTORS(SeqAsciiString);
7204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
7205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The TwoByteString class captures sequential unicode string objects.
7208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Each character in the TwoByteString is a two-byte uint16_t.
7209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass SeqTwoByteString: public SeqString {
7210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
7211ac95265630a4e0c317a7a7201d17a57df7d9bcceLeon Clarke  static const bool kHasAsciiEncoding = false;
7212ac95265630a4e0c317a7a7201d17a57df7d9bcceLeon Clarke
7213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Dispatched behavior.
7214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline uint16_t SeqTwoByteStringGet(int index);
7215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void SeqTwoByteStringSet(int index, uint16_t value);
7216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Get the address of the characters in this string.
7218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline Address GetCharsAddress();
7219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline uc16* GetChars();
7221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // For regexp code.
7223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  const uint16_t* SeqTwoByteStringGetData(unsigned start);
7224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Casting
7226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline SeqTwoByteString* cast(Object* obj);
7227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Garbage collection support.  This method is called by the
7229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // garbage collector to compute the actual size of a TwoByteString
7230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // instance.
7231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline int SeqTwoByteStringSize(InstanceType instance_type);
7232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Computes the size for a TwoByteString instance of a given length.
7234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static int SizeFor(int length) {
72357f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    return OBJECT_POINTER_ALIGN(kHeaderSize + length * kShortSize);
7236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
7237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7238e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Maximal memory usage for a single sequential two-byte string.
72393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kMaxSize = 512 * MB - 1;
7240e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Maximal length of a single sequential two-byte string.
7241e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Q.v. String::kMaxLength which is the maximal size of concatenated strings.
7242e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  static const int kMaxLength = (kMaxSize - kHeaderSize) / sizeof(uint16_t);
7243e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
7244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Support for StringInputBuffer.
7245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void SeqTwoByteStringReadBlockIntoBuffer(ReadBlockBuffer* buffer,
7246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                                  unsigned* offset_ptr,
7247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                                  unsigned chars);
7248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
7250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DISALLOW_IMPLICIT_CONSTRUCTORS(SeqTwoByteString);
7251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
7252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The ConsString class describes string values built by using the
7255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// addition operator on strings.  A ConsString is a pair where the
7256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// first and second components are pointers to other string values.
7257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// One or both components of a ConsString can be pointers to other
7258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ConsStrings, creating a binary tree of ConsStrings where the leaves
7259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// are non-ConsString string values.  The string value represented by
7260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// a ConsString can be obtained by concatenating the leaf string
7261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// values in a left-to-right depth-first traversal of the tree.
7262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass ConsString: public String {
7263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
7264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // First string of the cons cell.
7265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline String* first();
7266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Doesn't check that the result is a string, even in debug mode.  This is
7267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // useful during GC where the mark bits confuse the checks.
7268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline Object* unchecked_first();
7269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void set_first(String* first,
7270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                        WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
7271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Second string of the cons cell.
7273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline String* second();
7274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Doesn't check that the result is a string, even in debug mode.  This is
7275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // useful during GC where the mark bits confuse the checks.
7276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline Object* unchecked_second();
7277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void set_second(String* second,
7278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                         WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
7279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Dispatched behavior.
7281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  uint16_t ConsStringGet(int index);
7282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Casting.
7284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline ConsString* cast(Object* obj);
7285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Layout description.
7287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kFirstOffset = POINTER_SIZE_ALIGN(String::kSize);
7288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kSecondOffset = kFirstOffset + kPointerSize;
7289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kSize = kSecondOffset + kPointerSize;
7290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Support for StringInputBuffer.
7292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline const unibrow::byte* ConsStringReadBlock(ReadBlockBuffer* buffer,
7293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                                  unsigned* offset_ptr,
7294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                                  unsigned chars);
7295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void ConsStringReadBlockIntoBuffer(ReadBlockBuffer* buffer,
7296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                            unsigned* offset_ptr,
7297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                            unsigned chars);
7298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Minimum length for a cons string.
7300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kMinLength = 13;
7301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7302756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  typedef FixedBodyDescriptor<kFirstOffset, kSecondOffset + kPointerSize, kSize>
7303756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick          BodyDescriptor;
7304756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
730569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#ifdef DEBUG
730669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  void ConsStringVerify();
730769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#endif
730869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
7309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
7310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DISALLOW_IMPLICIT_CONSTRUCTORS(ConsString);
7311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
7312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
731469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// The Sliced String class describes strings that are substrings of another
731569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// sequential string.  The motivation is to save time and memory when creating
731669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// a substring.  A Sliced String is described as a pointer to the parent,
731769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// the offset from the start of the parent string and the length.  Using
731869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// a Sliced String therefore requires unpacking of the parent string and
731969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// adding the offset to the start address.  A substring of a Sliced String
732069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// are not nested since the double indirection is simplified when creating
732169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// such a substring.
732269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// Currently missing features are:
732369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch//  - handling externalized parent strings
732469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch//  - external strings as parent
732569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch//  - truncating sliced string to enable otherwise unneeded parent to be GC'ed.
732669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochclass SlicedString: public String {
732769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch public:
732869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  inline String* parent();
732969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  inline void set_parent(String* parent);
733069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  inline int offset();
733169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  inline void set_offset(int offset);
733269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
733369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  // Dispatched behavior.
733469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  uint16_t SlicedStringGet(int index);
733569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
733669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  // Casting.
733769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  static inline SlicedString* cast(Object* obj);
733869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
733969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  // Layout description.
734069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  static const int kParentOffset = POINTER_SIZE_ALIGN(String::kSize);
734169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  static const int kOffsetOffset = kParentOffset + kPointerSize;
734269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  static const int kSize = kOffsetOffset + kPointerSize;
734369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
734469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  // Support for StringInputBuffer
734569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  inline const unibrow::byte* SlicedStringReadBlock(ReadBlockBuffer* buffer,
734669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch                                                    unsigned* offset_ptr,
734769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch                                                    unsigned chars);
734869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  inline void SlicedStringReadBlockIntoBuffer(ReadBlockBuffer* buffer,
734969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch                                              unsigned* offset_ptr,
735069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch                                              unsigned chars);
735169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  // Minimum length for a sliced string.
735269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  static const int kMinLength = 13;
735369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
735469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  typedef FixedBodyDescriptor<kParentOffset,
735569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch                              kOffsetOffset + kPointerSize, kSize>
735669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch          BodyDescriptor;
735769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
735869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#ifdef DEBUG
735969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  void SlicedStringVerify();
736069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#endif
736169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
736269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch private:
736369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  DISALLOW_IMPLICIT_CONSTRUCTORS(SlicedString);
736469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch};
736569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
736669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
7367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The ExternalString class describes string values that are backed by
7368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// a string resource that lies outside the V8 heap.  ExternalStrings
7369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// consist of the length field common to all strings, a pointer to the
7370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// external resource.  It is important to ensure (externally) that the
7371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// resource is not deallocated while the ExternalString is live in the
7372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// V8 heap.
7373a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
7374a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The API expects that all ExternalStrings are created through the
7375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// API.  Therefore, ExternalStrings should not be used internally.
7376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass ExternalString: public String {
7377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
7378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Casting
7379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline ExternalString* cast(Object* obj);
7380a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Layout description.
7382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kResourceOffset = POINTER_SIZE_ALIGN(String::kSize);
73833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kShortSize = kResourceOffset + kPointerSize;
73843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kResourceDataOffset = kResourceOffset + kPointerSize;
73853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kSize = kResourceDataOffset + kPointerSize;
73863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
73873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Return whether external string is short (data pointer is not cached).
73883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline bool is_short();
7389a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7390a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  STATIC_CHECK(kResourceOffset == Internals::kStringResourceOffset);
7391a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7392a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
7393a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalString);
7394a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
7395a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7396a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7397a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The ExternalAsciiString class is an external string backed by an
7398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ASCII string.
7399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass ExternalAsciiString: public ExternalString {
7400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
7401ac95265630a4e0c317a7a7201d17a57df7d9bcceLeon Clarke  static const bool kHasAsciiEncoding = true;
7402ac95265630a4e0c317a7a7201d17a57df7d9bcceLeon Clarke
7403a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  typedef v8::String::ExternalAsciiStringResource Resource;
7404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // The underlying resource.
74063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline const Resource* resource();
74073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline void set_resource(const Resource* buffer);
74083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
74093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Update the pointer cache to the external character array.
74103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // The cached pointer is always valid, as the external character array does =
74113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // not move during lifetime.  Deserialization is the only exception, after
74123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // which the pointer cache has to be refreshed.
74133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline void update_data_cache();
74143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
74153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline const char* GetChars();
7416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7417a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Dispatched behavior.
74183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline uint16_t ExternalAsciiStringGet(int index);
7419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Casting.
7421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline ExternalAsciiString* cast(Object* obj);
7422a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7423d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // Garbage collection support.
7424756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  inline void ExternalAsciiStringIterateBody(ObjectVisitor* v);
7425756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
7426756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  template<typename StaticVisitor>
7427756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  inline void ExternalAsciiStringIterateBody();
7428d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
7429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Support for StringInputBuffer.
7430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  const unibrow::byte* ExternalAsciiStringReadBlock(unsigned* remaining,
7431a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                                    unsigned* offset,
7432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                                    unsigned chars);
7433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void ExternalAsciiStringReadBlockIntoBuffer(ReadBlockBuffer* buffer,
7434a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                                     unsigned* offset,
7435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                                     unsigned chars);
7436a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7437a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
7438a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalAsciiString);
7439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
7440a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The ExternalTwoByteString class is an external string backed by a UTF-16
7443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// encoded string.
7444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass ExternalTwoByteString: public ExternalString {
7445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
7446ac95265630a4e0c317a7a7201d17a57df7d9bcceLeon Clarke  static const bool kHasAsciiEncoding = false;
7447ac95265630a4e0c317a7a7201d17a57df7d9bcceLeon Clarke
7448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  typedef v8::String::ExternalStringResource Resource;
7449a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7450a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // The underlying string resource.
74513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline const Resource* resource();
74523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline void set_resource(const Resource* buffer);
74533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
74543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Update the pointer cache to the external character array.
74553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // The cached pointer is always valid, as the external character array does =
74563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // not move during lifetime.  Deserialization is the only exception, after
74573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // which the pointer cache has to be refreshed.
74583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline void update_data_cache();
74593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
74603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline const uint16_t* GetChars();
7461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Dispatched behavior.
74633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline uint16_t ExternalTwoByteStringGet(int index);
7464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // For regexp code.
74663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline const uint16_t* ExternalTwoByteStringGetData(unsigned start);
7467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Casting.
7469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline ExternalTwoByteString* cast(Object* obj);
7470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7471d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // Garbage collection support.
7472756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  inline void ExternalTwoByteStringIterateBody(ObjectVisitor* v);
7473756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
7474756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  template<typename StaticVisitor>
7475756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  inline void ExternalTwoByteStringIterateBody();
7476756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
7477d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
7478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Support for StringInputBuffer.
7479a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void ExternalTwoByteStringReadBlockIntoBuffer(ReadBlockBuffer* buffer,
7480a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                                unsigned* offset_ptr,
7481a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                                unsigned chars);
7482a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7483a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
7484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalTwoByteString);
7485a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
7486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7487a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7488a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Utility superclass for stack-allocated objects that must be updated
7489a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// on gc.  It provides two ways for the gc to update instances, either
7490a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// iterating or updating after gc.
7491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass Relocatable BASE_EMBEDDED {
7492a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
749344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  explicit inline Relocatable(Isolate* isolate);
749444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  inline virtual ~Relocatable();
7495a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  virtual void IterateInstance(ObjectVisitor* v) { }
7496a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  virtual void PostGarbageCollection() { }
7497a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7498a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static void PostGarbageCollectionProcessing();
7499a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static int ArchiveSpacePerThread();
7500257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  static char* ArchiveState(Isolate* isolate, char* to);
7501257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  static char* RestoreState(Isolate* isolate, char* from);
7502a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static void Iterate(ObjectVisitor* v);
7503a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static void Iterate(ObjectVisitor* v, Relocatable* top);
7504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static char* Iterate(ObjectVisitor* v, char* t);
7505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
750644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Isolate* isolate_;
7507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Relocatable* prev_;
7508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
7509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A flat string reader provides random access to the contents of a
7512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// string independent of the character width of the string.  The handle
7513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// must be valid as long as the reader is being used.
7514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass FlatStringReader : public Relocatable {
7515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
751644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  FlatStringReader(Isolate* isolate, Handle<String> str);
751744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  FlatStringReader(Isolate* isolate, Vector<const char> input);
7518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void PostGarbageCollection();
7519a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline uc32 Get(int index);
7520a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int length() { return length_; }
7521a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
7522a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  String** str_;
7523a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool is_ascii_;
7524a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int length_;
7525a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  const void* start_;
7526a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
7527a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7528a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7529a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Note that StringInputBuffers are not valid across a GC!  To fix this
7530a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// it would have to store a String Handle instead of a String* and
7531a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// AsciiStringReadBlock would have to be modified to use memcpy.
7532a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
7533a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// StringInputBuffer is able to traverse any string regardless of how
7534a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// deeply nested a sequence of ConsStrings it is made of.  However,
7535a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// performance will be better if deep strings are flattened before they
7536a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// are traversed.  Since flattening requires memory allocation this is
7537a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// not always desirable, however (esp. in debugging situations).
7538a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass StringInputBuffer: public unibrow::InputBuffer<String, String*, 1024> {
7539a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
7540a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  virtual void Seek(unsigned pos);
7541a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline StringInputBuffer(): unibrow::InputBuffer<String, String*, 1024>() {}
75428b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  explicit inline StringInputBuffer(String* backing):
7543a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      unibrow::InputBuffer<String, String*, 1024>(backing) {}
7544a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
7545a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7546a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7547a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass SafeStringInputBuffer
7548a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  : public unibrow::InputBuffer<String, String**, 256> {
7549a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
7550a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  virtual void Seek(unsigned pos);
7551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline SafeStringInputBuffer()
7552a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      : unibrow::InputBuffer<String, String**, 256>() {}
75538b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  explicit inline SafeStringInputBuffer(String** backing)
7554a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      : unibrow::InputBuffer<String, String**, 256>(backing) {}
7555a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
7556a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7557a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7558a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocktemplate <typename T>
7559a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass VectorIterator {
7560a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
7561a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  VectorIterator(T* d, int l) : data_(Vector<const T>(d, l)), index_(0) { }
7562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  explicit VectorIterator(Vector<const T> data) : data_(data), index_(0) { }
7563a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  T GetNext() { return data_[index_++]; }
7564a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool has_more() { return index_ < data_.length(); }
7565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
7566a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Vector<const T> data_;
7567a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int index_;
7568a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
7569a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7570a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The Oddball describes objects null, undefined, true, and false.
7572a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass Oddball: public HeapObject {
7573a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
7574a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // [to_string]: Cached to_string computed at startup.
7575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(to_string, String)
7576a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7577a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // [to_number]: Cached to_number computed at startup.
7578a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(to_number, Object)
7579a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
758044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  inline byte kind();
758144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  inline void set_kind(byte kind);
758244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
7583a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Casting.
7584a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline Oddball* cast(Object* obj);
7585a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7586a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Dispatched behavior.
7587a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG
7588a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void OddballVerify();
7589a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
7590a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Initialize the fields.
75925913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* Initialize(const char* to_string,
759344f0eee88ff00398ff7f715fab053374d808c90dSteve Block                                          Object* to_number,
759444f0eee88ff00398ff7f715fab053374d808c90dSteve Block                                          byte kind);
7595a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7596a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Layout description.
7597a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kToStringOffset = HeapObject::kHeaderSize;
7598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kToNumberOffset = kToStringOffset + kPointerSize;
759944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  static const int kKindOffset = kToNumberOffset + kPointerSize;
760044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  static const int kSize = kKindOffset + kPointerSize;
760144f0eee88ff00398ff7f715fab053374d808c90dSteve Block
760244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  static const byte kFalse = 0;
760344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  static const byte kTrue = 1;
760444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  static const byte kNotBooleanMask = ~1;
760544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  static const byte kTheHole = 2;
760644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  static const byte kNull = 3;
760744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  static const byte kArgumentMarker = 4;
760844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  static const byte kUndefined = 5;
760944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  static const byte kOther = 6;
7610a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7611756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  typedef FixedBodyDescriptor<kToStringOffset,
7612756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick                              kToNumberOffset + kPointerSize,
7613756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick                              kSize> BodyDescriptor;
7614756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
7615a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
7616a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DISALLOW_IMPLICIT_CONSTRUCTORS(Oddball);
7617a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
7618a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7619a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7620a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass JSGlobalPropertyCell: public HeapObject {
7621a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
7622a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // [value]: value of the global property.
7623a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(value, Object)
7624a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7625a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Casting.
7626a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline JSGlobalPropertyCell* cast(Object* obj);
7627a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7628a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG
7629a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void JSGlobalPropertyCellVerify();
7630b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif
7631b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef OBJECT_PRINT
7632b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  inline void JSGlobalPropertyCellPrint() {
7633b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    JSGlobalPropertyCellPrint(stdout);
7634b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
7635b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void JSGlobalPropertyCellPrint(FILE* out);
7636a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
7637a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7638a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Layout description.
7639a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kValueOffset = HeapObject::kHeaderSize;
7640a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kSize = kValueOffset + kPointerSize;
7641a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7642756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  typedef FixedBodyDescriptor<kValueOffset,
7643756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick                              kValueOffset + kPointerSize,
7644756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick                              kSize> BodyDescriptor;
7645756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
7646a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
7647a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DISALLOW_IMPLICIT_CONSTRUCTORS(JSGlobalPropertyCell);
7648a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
7649a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7650a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7651257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// The JSProxy describes EcmaScript Harmony proxies
76523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochclass JSProxy: public JSReceiver {
7653257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch public:
7654257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // [handler]: The handler property.
7655257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  DECL_ACCESSORS(handler, Object)
7656257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
76573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // [hash]: The hash code property (undefined if not initialized yet).
76583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  DECL_ACCESSORS(hash, Object)
76593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
7660257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Casting.
7661257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  static inline JSProxy* cast(Object* obj);
7662a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
76633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  bool HasPropertyWithHandler(String* name);
76643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool HasElementWithHandler(uint32_t index);
76653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
76663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT MaybeObject* GetPropertyWithHandler(
76673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Object* receiver,
76683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      String* name);
76693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT MaybeObject* GetElementWithHandler(
76703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Object* receiver,
76713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      uint32_t index);
76723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
76733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  MUST_USE_RESULT MaybeObject* SetPropertyWithHandler(
76743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      String* name,
76753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      Object* value,
76763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      PropertyAttributes attributes,
76773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      StrictModeFlag strict_mode);
76783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT MaybeObject* SetElementWithHandler(
76793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      uint32_t index,
76803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Object* value,
76813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      StrictModeFlag strict_mode);
76823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
76833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // If the handler defines an accessor property, invoke its setter
76843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // (or throw if only a getter exists) and set *found to true. Otherwise false.
76853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT MaybeObject* SetPropertyWithHandlerIfDefiningSetter(
76863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      String* name,
76873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Object* value,
76883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      PropertyAttributes attributes,
76893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      StrictModeFlag strict_mode,
76903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      bool* found);
76913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
76923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  MUST_USE_RESULT MaybeObject* DeletePropertyWithHandler(
76933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      String* name,
76943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      DeleteMode mode);
76953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT MaybeObject* DeleteElementWithHandler(
76963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      uint32_t index,
76973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      DeleteMode mode);
76983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
76993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  MUST_USE_RESULT PropertyAttributes GetPropertyAttributeWithHandler(
77003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      JSReceiver* receiver,
77013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      String* name);
77023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT PropertyAttributes GetElementAttributeWithHandler(
77033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      JSReceiver* receiver,
77043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      uint32_t index);
77053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
77063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT MaybeObject* GetIdentityHash(CreationFlag flag);
77073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
77083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Turn this into an (empty) JSObject.
77093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  void Fix();
77103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
7711589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // Initializes the body after the handler slot.
7712589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  inline void InitializeBody(int object_size, Object* value);
7713589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
77143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Invoke a trap by name. If the trap does not exist on this's handler,
77153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // but derived_trap is non-NULL, invoke that instead.  May cause GC.
77163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Object> CallTrap(const char* name,
77173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                          Handle<Object> derived_trap,
77183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                          int argc,
77193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                          Handle<Object> args[]);
77203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
7721257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Dispatched behavior.
7722257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#ifdef OBJECT_PRINT
7723257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  inline void JSProxyPrint() {
7724257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    JSProxyPrint(stdout);
7725257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
7726257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void JSProxyPrint(FILE* out);
7727257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#endif
7728257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#ifdef DEBUG
7729257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void JSProxyVerify();
7730257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#endif
7731257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
77323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Layout description. We add padding so that a proxy has the same
77333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // size as a virgin JSObject. This is essential for becoming a JSObject
77343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // upon freeze.
7735257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  static const int kHandlerOffset = HeapObject::kHeaderSize;
77363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kHashOffset = kHandlerOffset + kPointerSize;
77373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kPaddingOffset = kHashOffset + kPointerSize;
7738589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  static const int kSize = JSObject::kHeaderSize;
7739589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  static const int kHeaderSize = kPaddingOffset;
7740589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  static const int kPaddingSize = kSize - kPaddingOffset;
77413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
7742589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  STATIC_CHECK(kPaddingSize >= 0);
7743257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
7744257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  typedef FixedBodyDescriptor<kHandlerOffset,
77453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                              kPaddingOffset,
7746257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                              kSize> BodyDescriptor;
7747257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
7748257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch private:
7749257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  DISALLOW_IMPLICIT_CONSTRUCTORS(JSProxy);
7750257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch};
7751257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
7752257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
77533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochclass JSFunctionProxy: public JSProxy {
77543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch public:
7755589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // [call_trap]: The call trap.
7756589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  DECL_ACCESSORS(call_trap, Object)
7757589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
7758589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // [construct_trap]: The construct trap.
7759589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  DECL_ACCESSORS(construct_trap, Object)
7760589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
77613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Casting.
77623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  static inline JSFunctionProxy* cast(Object* obj);
77633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
7764589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // Dispatched behavior.
7765589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch#ifdef OBJECT_PRINT
7766589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  inline void JSFunctionProxyPrint() {
7767589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    JSFunctionProxyPrint(stdout);
7768589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  }
7769589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  void JSFunctionProxyPrint(FILE* out);
7770589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch#endif
7771589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch#ifdef DEBUG
7772589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  void JSFunctionProxyVerify();
7773589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch#endif
7774589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
7775589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // Layout description.
77763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kCallTrapOffset = JSProxy::kPaddingOffset;
7777589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  static const int kConstructTrapOffset = kCallTrapOffset + kPointerSize;
7778589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  static const int kPaddingOffset = kConstructTrapOffset + kPointerSize;
7779589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  static const int kSize = JSFunction::kSize;
7780589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  static const int kPaddingSize = kSize - kPaddingOffset;
7781589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
7782589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  STATIC_CHECK(kPaddingSize >= 0);
7783589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
7784589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  typedef FixedBodyDescriptor<kHandlerOffset,
7785589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch                              kConstructTrapOffset + kPointerSize,
7786589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch                              kSize> BodyDescriptor;
7787589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
77883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch private:
77893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  DISALLOW_IMPLICIT_CONSTRUCTORS(JSFunctionProxy);
77903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch};
77913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
7792257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
77933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// The JSSet describes EcmaScript Harmony sets
77943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochclass JSSet: public JSObject {
77953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public:
77963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // [set]: the backing hash set containing keys.
77973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  DECL_ACCESSORS(table, Object)
77983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
77993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Casting.
78003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static inline JSSet* cast(Object* obj);
78013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
78023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#ifdef OBJECT_PRINT
78033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline void JSSetPrint() {
78043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    JSSetPrint(stdout);
78053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
78063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void JSSetPrint(FILE* out);
78073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif
78083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#ifdef DEBUG
78093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void JSSetVerify();
78103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif
78113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
78123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kTableOffset = JSObject::kHeaderSize;
78133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kSize = kTableOffset + kPointerSize;
78143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
78153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch private:
78163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  DISALLOW_IMPLICIT_CONSTRUCTORS(JSSet);
78173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch};
78183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
78193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
78203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// The JSMap describes EcmaScript Harmony maps
78213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochclass JSMap: public JSObject {
78223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public:
78233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // [table]: the backing hash table mapping keys to values.
78243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  DECL_ACCESSORS(table, Object)
78253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
78263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Casting.
78273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static inline JSMap* cast(Object* obj);
78283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
78293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#ifdef OBJECT_PRINT
78303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline void JSMapPrint() {
78313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    JSMapPrint(stdout);
78323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
78333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void JSMapPrint(FILE* out);
78343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif
78353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#ifdef DEBUG
78363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void JSMapVerify();
78373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif
78383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
78393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kTableOffset = JSObject::kHeaderSize;
78403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kSize = kTableOffset + kPointerSize;
78413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
78423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch private:
78433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  DISALLOW_IMPLICIT_CONSTRUCTORS(JSMap);
78443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch};
78453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
78463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
784769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// The JSWeakMap describes EcmaScript Harmony weak maps
784869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochclass JSWeakMap: public JSObject {
784969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch public:
785069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  // [table]: the backing hash table mapping keys to values.
78513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  DECL_ACCESSORS(table, Object)
785269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
785369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  // [next]: linked list of encountered weak maps during GC.
785469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  DECL_ACCESSORS(next, Object)
785569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
785669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  // Casting.
785769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  static inline JSWeakMap* cast(Object* obj);
785869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
785969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#ifdef OBJECT_PRINT
786069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  inline void JSWeakMapPrint() {
786169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    JSWeakMapPrint(stdout);
786269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  }
786369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  void JSWeakMapPrint(FILE* out);
786469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#endif
786569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#ifdef DEBUG
786669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  void JSWeakMapVerify();
786769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#endif
786869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
786969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  static const int kTableOffset = JSObject::kHeaderSize;
787069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  static const int kNextOffset = kTableOffset + kPointerSize;
787169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  static const int kSize = kNextOffset + kPointerSize;
787269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
787369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch private:
787469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  DISALLOW_IMPLICIT_CONSTRUCTORS(JSWeakMap);
787569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch};
787669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
787769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
7878257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// Foreign describes objects pointing from JavaScript to C structures.
7879a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Since they cannot contain references to JS HeapObjects they can be
7880a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// placed in old_data_space.
7881257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochclass Foreign: public HeapObject {
7882a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
7883257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // [address]: field containing the address.
78843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline Address foreign_address();
78853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline void set_foreign_address(Address value);
7886a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7887a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Casting.
7888257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  static inline Foreign* cast(Object* obj);
7889a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7890a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Dispatched behavior.
7891257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  inline void ForeignIterateBody(ObjectVisitor* v);
7892756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
7893756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  template<typename StaticVisitor>
7894257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  inline void ForeignIterateBody();
7895756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
7896b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef OBJECT_PRINT
7897257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  inline void ForeignPrint() {
7898257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    ForeignPrint(stdout);
7899b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
7900257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void ForeignPrint(FILE* out);
7901b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif
7902a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG
7903257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void ForeignVerify();
7904a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
7905a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7906a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Layout description.
7907a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
79083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kForeignAddressOffset = HeapObject::kHeaderSize;
79093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kSize = kForeignAddressOffset + kPointerSize;
7910a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
79113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  STATIC_CHECK(kForeignAddressOffset == Internals::kForeignAddressOffset);
7912a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7913a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
7914257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  DISALLOW_IMPLICIT_CONSTRUCTORS(Foreign);
7915a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
7916a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7917a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7918a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The JSArray describes JavaScript Arrays
7919a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//  Such an array can be in one of two modes:
7920a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//    - fast, backing storage is a FixedArray and length <= elements.length();
7921a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       Please note: push and pop can be used to grow and shrink the array.
7922a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//    - slow, backing storage is a HashTable with numbers as keys.
7923a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass JSArray: public JSObject {
7924a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
7925a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // [length]: The length property.
7926a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(length, Object)
7927a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
79284515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  // Overload the length setter to skip write barrier when the length
79294515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  // is set to a smi. This matches the set function on FixedArray.
79304515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  inline void set_length(Smi* length);
79314515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke
79325913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* JSArrayUpdateLengthFromIndex(uint32_t index,
79335913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck                                                            Object* value);
7934a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7935a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Initialize the array with the given capacity. The function may
7936a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // fail due to out-of-memory situations, but only if the requested
7937a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // capacity is non-zero.
79385913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* Initialize(int capacity);
7939a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
79403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Initializes the array to a certain length.
79413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline bool AllowsSetElementsLength();
79423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT MaybeObject* SetElementsLength(Object* length);
79433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
7944a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Set the content of the array to the content of storage.
79453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT inline MaybeObject* SetContent(FixedArrayBase* storage);
7946a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7947a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Casting.
7948a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline JSArray* cast(Object* obj);
7949a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7950a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Uses handles.  Ensures that the fixed array backing the JSArray has at
7951a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // least the stated size.
7952a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void EnsureSize(int minimum_size_of_backing_fixed_array);
7953a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7954a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Dispatched behavior.
7955b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef OBJECT_PRINT
7956b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  inline void JSArrayPrint() {
7957b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    JSArrayPrint(stdout);
7958b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
7959b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void JSArrayPrint(FILE* out);
7960b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif
7961a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG
7962a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void JSArrayVerify();
7963a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
7964a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7965a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Number of element slots to pre-allocate for an empty array.
7966a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kPreallocatedArrayElements = 4;
7967a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7968a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Layout description.
7969a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kLengthOffset = JSObject::kHeaderSize;
7970a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kSize = kLengthOffset + kPointerSize;
7971a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7972a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
7973a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Expand the fixed array backing of a fast-case JSArray to at least
7974a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // the requested size.
7975a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Expand(int minimum_size_of_backing_fixed_array);
7976a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7977a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DISALLOW_IMPLICIT_CONSTRUCTORS(JSArray);
7978a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
7979a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7980a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
79816ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// JSRegExpResult is just a JSArray with a specific initial map.
79826ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// This initial map adds in-object properties for "index" and "input"
79836ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// properties, as assigned by RegExp.prototype.exec, which allows
79846ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// faster creation of RegExp exec results.
79856ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// This class just holds constants used when creating the result.
79866ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// After creation the result must be treated as a JSArray in all regards.
79876ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockclass JSRegExpResult: public JSArray {
79886ded16be15dd865a9b21ea304d5273c8be299c87Steve Block public:
79896ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Offsets of object fields.
79906ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static const int kIndexOffset = JSArray::kSize;
79916ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static const int kInputOffset = kIndexOffset + kPointerSize;
79926ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static const int kSize = kInputOffset + kPointerSize;
79936ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Indices of in-object properties.
79946ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static const int kIndexIndex = 0;
79956ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static const int kInputIndex = 1;
79966ded16be15dd865a9b21ea304d5273c8be299c87Steve Block private:
79976ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  DISALLOW_IMPLICIT_CONSTRUCTORS(JSRegExpResult);
79986ded16be15dd865a9b21ea304d5273c8be299c87Steve Block};
79996ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
80006ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
8001a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// An accessor must have a getter, but can have no setter.
8002a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
8003a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// When setting a property, V8 searches accessors in prototypes.
8004a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// If an accessor was found and it does not have a setter,
8005a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// the request is ignored.
8006a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
8007a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// If the accessor in the prototype has the READ_ONLY property attribute, then
8008a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// a new value is added to the local object when the property is set.
8009a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// This shadows the accessor in the prototype.
8010a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass AccessorInfo: public Struct {
8011a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
8012a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(getter, Object)
8013a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(setter, Object)
8014a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(data, Object)
8015a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(name, Object)
8016a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(flag, Smi)
8017a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8018a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline bool all_can_read();
8019a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void set_all_can_read(bool value);
8020a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8021a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline bool all_can_write();
8022a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void set_all_can_write(bool value);
8023a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8024a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline bool prohibits_overwriting();
8025a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void set_prohibits_overwriting(bool value);
8026a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8027a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline PropertyAttributes property_attributes();
8028a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void set_property_attributes(PropertyAttributes attributes);
8029a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8030a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline AccessorInfo* cast(Object* obj);
8031a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8032b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef OBJECT_PRINT
8033b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  inline void AccessorInfoPrint() {
8034b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    AccessorInfoPrint(stdout);
8035b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
8036b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void AccessorInfoPrint(FILE* out);
8037b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif
8038a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG
8039a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void AccessorInfoVerify();
8040a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
8041a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8042a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kGetterOffset = HeapObject::kHeaderSize;
8043a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kSetterOffset = kGetterOffset + kPointerSize;
8044a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kDataOffset = kSetterOffset + kPointerSize;
8045a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kNameOffset = kDataOffset + kPointerSize;
8046a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kFlagOffset = kNameOffset + kPointerSize;
80478a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  static const int kSize = kFlagOffset + kPointerSize;
8048a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8049a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
8050a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Bit positions in flag.
8051a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kAllCanReadBit = 0;
8052a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kAllCanWriteBit = 1;
8053a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kProhibitsOverwritingBit = 2;
8054a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  class AttributesField: public BitField<PropertyAttributes, 3, 3> {};
8055a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8056a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DISALLOW_IMPLICIT_CONSTRUCTORS(AccessorInfo);
8057a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
8058a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8059a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
80603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Support for JavaScript accessors: A pair of a getter and a setter. Each
80613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// accessor can either be
80623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch//   * a pointer to a JavaScript function or proxy: a real accessor
80633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch//   * undefined: considered an accessor by the spec, too, strangely enough
80643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch//   * the hole: an accessor which has not been set
80653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch//   * a pointer to a map: a transition used to ensure map sharing
80663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochclass AccessorPair: public Struct {
80673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public:
80683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  DECL_ACCESSORS(getter, Object)
80693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  DECL_ACCESSORS(setter, Object)
80703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
80713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static inline AccessorPair* cast(Object* obj);
80723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
80733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MUST_USE_RESULT MaybeObject* CopyWithoutTransitions();
80743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
80753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Note: Returns undefined instead in case of a hole.
80763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Object* GetComponent(AccessorComponent component);
80773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
80783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Set both components, skipping arguments which are a JavaScript null.
80793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void SetComponents(Object* getter, Object* setter) {
80803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (!getter->IsNull()) set_getter(getter);
80813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (!setter->IsNull()) set_setter(setter);
80823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
80833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
80843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool ContainsAccessor() {
80853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return IsJSAccessor(getter()) || IsJSAccessor(setter());
80863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
80873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
80883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#ifdef OBJECT_PRINT
80893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void AccessorPairPrint(FILE* out = stdout);
80903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif
80913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#ifdef DEBUG
80923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void AccessorPairVerify();
80933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif
80943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
80953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kGetterOffset = HeapObject::kHeaderSize;
80963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kSetterOffset = kGetterOffset + kPointerSize;
80973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kSize = kSetterOffset + kPointerSize;
80983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
80993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch private:
81003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Strangely enough, in addition to functions and harmony proxies, the spec
81013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // requires us to consider undefined as a kind of accessor, too:
81023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //    var obj = {};
81033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //    Object.defineProperty(obj, "foo", {get: undefined});
81043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //    assertTrue("foo" in obj);
81053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool IsJSAccessor(Object* obj) {
81063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return obj->IsSpecFunction() || obj->IsUndefined();
81073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
81083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
81093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  DISALLOW_IMPLICIT_CONSTRUCTORS(AccessorPair);
81103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch};
81113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
81123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
8113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass AccessCheckInfo: public Struct {
8114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
8115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(named_callback, Object)
8116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(indexed_callback, Object)
8117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(data, Object)
8118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline AccessCheckInfo* cast(Object* obj);
8120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8121b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef OBJECT_PRINT
8122b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  inline void AccessCheckInfoPrint() {
8123b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    AccessCheckInfoPrint(stdout);
8124b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
8125b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void AccessCheckInfoPrint(FILE* out);
8126b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif
8127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG
8128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void AccessCheckInfoVerify();
8129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
8130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kNamedCallbackOffset   = HeapObject::kHeaderSize;
8132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kIndexedCallbackOffset = kNamedCallbackOffset + kPointerSize;
8133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kDataOffset = kIndexedCallbackOffset + kPointerSize;
8134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kSize = kDataOffset + kPointerSize;
8135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
8137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DISALLOW_IMPLICIT_CONSTRUCTORS(AccessCheckInfo);
8138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
8139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass InterceptorInfo: public Struct {
8142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
8143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(getter, Object)
8144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(setter, Object)
8145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(query, Object)
8146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(deleter, Object)
8147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(enumerator, Object)
8148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(data, Object)
8149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline InterceptorInfo* cast(Object* obj);
8151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8152b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef OBJECT_PRINT
8153b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  inline void InterceptorInfoPrint() {
8154b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    InterceptorInfoPrint(stdout);
8155b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
8156b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void InterceptorInfoPrint(FILE* out);
8157b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif
8158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG
8159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void InterceptorInfoVerify();
8160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
8161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kGetterOffset = HeapObject::kHeaderSize;
8163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kSetterOffset = kGetterOffset + kPointerSize;
8164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kQueryOffset = kSetterOffset + kPointerSize;
8165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kDeleterOffset = kQueryOffset + kPointerSize;
8166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kEnumeratorOffset = kDeleterOffset + kPointerSize;
8167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kDataOffset = kEnumeratorOffset + kPointerSize;
8168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kSize = kDataOffset + kPointerSize;
8169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
8171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DISALLOW_IMPLICIT_CONSTRUCTORS(InterceptorInfo);
8172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
8173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass CallHandlerInfo: public Struct {
8176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
8177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(callback, Object)
8178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(data, Object)
8179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline CallHandlerInfo* cast(Object* obj);
8181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8182b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef OBJECT_PRINT
8183b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  inline void CallHandlerInfoPrint() {
8184b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    CallHandlerInfoPrint(stdout);
8185b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
8186b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void CallHandlerInfoPrint(FILE* out);
8187b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif
8188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG
8189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void CallHandlerInfoVerify();
8190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
8191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kCallbackOffset = HeapObject::kHeaderSize;
8193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kDataOffset = kCallbackOffset + kPointerSize;
81948a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  static const int kSize = kDataOffset + kPointerSize;
8195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
8197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DISALLOW_IMPLICIT_CONSTRUCTORS(CallHandlerInfo);
8198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
8199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass TemplateInfo: public Struct {
8202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
8203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(tag, Object)
8204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(property_list, Object)
8205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG
8207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void TemplateInfoVerify();
8208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
8209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kTagOffset          = HeapObject::kHeaderSize;
8211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kPropertyListOffset = kTagOffset + kPointerSize;
8212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kHeaderSize         = kPropertyListOffset + kPointerSize;
82133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
82143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch private:
8215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DISALLOW_IMPLICIT_CONSTRUCTORS(TemplateInfo);
8216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
8217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass FunctionTemplateInfo: public TemplateInfo {
8220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
8221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(serial_number, Object)
8222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(call_code, Object)
8223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(property_accessors, Object)
8224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(prototype_template, Object)
8225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(parent_template, Object)
8226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(named_property_handler, Object)
8227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(indexed_property_handler, Object)
8228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(instance_template, Object)
8229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(class_name, Object)
8230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(signature, Object)
8231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(instance_call_handler, Object)
8232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(access_check_info, Object)
8233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(flag, Smi)
8234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Following properties use flag bits.
8236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_BOOLEAN_ACCESSORS(hidden_prototype)
8237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_BOOLEAN_ACCESSORS(undetectable)
8238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // If the bit is set, object instances created by this function
8239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // requires access check.
8240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_BOOLEAN_ACCESSORS(needs_access_check)
824169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  DECL_BOOLEAN_ACCESSORS(read_only_prototype)
8242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline FunctionTemplateInfo* cast(Object* obj);
8244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8245b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef OBJECT_PRINT
8246b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  inline void FunctionTemplateInfoPrint() {
8247b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    FunctionTemplateInfoPrint(stdout);
8248b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
8249b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void FunctionTemplateInfoPrint(FILE* out);
8250b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif
8251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG
8252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void FunctionTemplateInfoVerify();
8253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
8254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kSerialNumberOffset = TemplateInfo::kHeaderSize;
8256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kCallCodeOffset = kSerialNumberOffset + kPointerSize;
8257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kPropertyAccessorsOffset = kCallCodeOffset + kPointerSize;
8258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kPrototypeTemplateOffset =
8259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      kPropertyAccessorsOffset + kPointerSize;
8260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kParentTemplateOffset =
8261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      kPrototypeTemplateOffset + kPointerSize;
8262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kNamedPropertyHandlerOffset =
8263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      kParentTemplateOffset + kPointerSize;
8264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kIndexedPropertyHandlerOffset =
8265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      kNamedPropertyHandlerOffset + kPointerSize;
8266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kInstanceTemplateOffset =
8267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      kIndexedPropertyHandlerOffset + kPointerSize;
8268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kClassNameOffset = kInstanceTemplateOffset + kPointerSize;
8269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kSignatureOffset = kClassNameOffset + kPointerSize;
8270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kInstanceCallHandlerOffset = kSignatureOffset + kPointerSize;
8271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kAccessCheckInfoOffset =
8272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      kInstanceCallHandlerOffset + kPointerSize;
8273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kFlagOffset = kAccessCheckInfoOffset + kPointerSize;
827469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  static const int kSize = kFlagOffset + kPointerSize;
8275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
8277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Bit position in the flag, from least significant bit position.
8278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kHiddenPrototypeBit   = 0;
8279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kUndetectableBit      = 1;
8280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kNeedsAccessCheckBit  = 2;
828169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  static const int kReadOnlyPrototypeBit = 3;
8282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DISALLOW_IMPLICIT_CONSTRUCTORS(FunctionTemplateInfo);
8284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
8285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass ObjectTemplateInfo: public TemplateInfo {
8288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
8289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(constructor, Object)
8290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(internal_field_count, Object)
8291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline ObjectTemplateInfo* cast(Object* obj);
8293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8294b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef OBJECT_PRINT
8295b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  inline void ObjectTemplateInfoPrint() {
8296b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    ObjectTemplateInfoPrint(stdout);
8297b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
8298b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void ObjectTemplateInfoPrint(FILE* out);
8299b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif
8300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG
8301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void ObjectTemplateInfoVerify();
8302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
8303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kConstructorOffset = TemplateInfo::kHeaderSize;
8305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kInternalFieldCountOffset =
8306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      kConstructorOffset + kPointerSize;
8307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kSize = kInternalFieldCountOffset + kPointerSize;
8308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
8309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass SignatureInfo: public Struct {
8312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
8313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(receiver, Object)
8314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(args, Object)
8315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline SignatureInfo* cast(Object* obj);
8317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8318b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef OBJECT_PRINT
8319b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  inline void SignatureInfoPrint() {
8320b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    SignatureInfoPrint(stdout);
8321b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
8322b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void SignatureInfoPrint(FILE* out);
8323b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif
8324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG
8325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void SignatureInfoVerify();
8326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
8327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kReceiverOffset = Struct::kHeaderSize;
8329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kArgsOffset     = kReceiverOffset + kPointerSize;
8330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kSize           = kArgsOffset + kPointerSize;
8331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
8333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DISALLOW_IMPLICIT_CONSTRUCTORS(SignatureInfo);
8334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
8335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass TypeSwitchInfo: public Struct {
8338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
8339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(types, Object)
8340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline TypeSwitchInfo* cast(Object* obj);
8342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8343b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef OBJECT_PRINT
8344b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  inline void TypeSwitchInfoPrint() {
8345b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    TypeSwitchInfoPrint(stdout);
8346b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
8347b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void TypeSwitchInfoPrint(FILE* out);
8348b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif
8349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG
8350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void TypeSwitchInfoVerify();
8351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
8352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kTypesOffset = Struct::kHeaderSize;
8354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kSize        = kTypesOffset + kPointerSize;
8355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
8356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8358a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_DEBUGGER_SUPPORT
8359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The DebugInfo class holds additional information for a function being
8360a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// debugged.
8361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass DebugInfo: public Struct {
8362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
8363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // The shared function info for the source being debugged.
8364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(shared, SharedFunctionInfo)
8365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Code object for the original code.
8366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(original_code, Code)
8367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Code object for the patched code. This code object is the code object
8368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // currently active for the function.
8369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(code, Code)
8370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Fixed array holding status information for each active break point.
8371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(break_points, FixedArray)
8372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8373a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Check if there is a break point at a code position.
8374a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool HasBreakPoint(int code_position);
8375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Get the break point info object for a code position.
8376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* GetBreakPointInfo(int code_position);
8377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Clear a break point.
8378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static void ClearBreakPoint(Handle<DebugInfo> debug_info,
8379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                              int code_position,
8380a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                              Handle<Object> break_point_object);
8381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Set a break point.
8382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static void SetBreakPoint(Handle<DebugInfo> debug_info, int code_position,
8383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                            int source_position, int statement_position,
8384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                            Handle<Object> break_point_object);
8385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Get the break point objects for a code position.
8386a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* GetBreakPointObjects(int code_position);
8387a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Find the break point info holding this break point object.
8388a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static Object* FindBreakPointInfo(Handle<DebugInfo> debug_info,
8389a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                    Handle<Object> break_point_object);
8390a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Get the number of break points for this function.
8391a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int GetBreakPointCount();
8392a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8393a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline DebugInfo* cast(Object* obj);
8394a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8395b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef OBJECT_PRINT
8396b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  inline void DebugInfoPrint() {
8397b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    DebugInfoPrint(stdout);
8398b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
8399b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void DebugInfoPrint(FILE* out);
8400b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif
8401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG
8402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void DebugInfoVerify();
8403a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
8404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kSharedFunctionInfoIndex = Struct::kHeaderSize;
8406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kOriginalCodeIndex = kSharedFunctionInfoIndex + kPointerSize;
8407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kPatchedCodeIndex = kOriginalCodeIndex + kPointerSize;
8408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kActiveBreakPointsCountIndex =
8409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      kPatchedCodeIndex + kPointerSize;
8410a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kBreakPointsStateIndex =
8411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      kActiveBreakPointsCountIndex + kPointerSize;
8412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kSize = kBreakPointsStateIndex + kPointerSize;
8413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
8415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kNoBreakPointInfo = -1;
8416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8417a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Lookup the index in the break_points array for a code position.
8418a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int GetBreakPointInfoIndex(int code_position);
8419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DISALLOW_IMPLICIT_CONSTRUCTORS(DebugInfo);
8421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
8422a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8424a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The BreakPointInfo class holds information for break points set in a
8425a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// function. The DebugInfo object holds a BreakPointInfo object for each code
8426a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// position with one or more break points.
8427a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass BreakPointInfo: public Struct {
8428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
8429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // The position in the code for the break point.
8430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(code_position, Smi)
8431a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // The position in the source for the break position.
8432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(source_position, Smi)
8433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // The position in the source for the last statement before this break
8434a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // position.
8435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(statement_position, Smi)
8436a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // List of related JavaScript break points.
8437a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DECL_ACCESSORS(break_point_objects, Object)
8438a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Removes a break point.
8440a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static void ClearBreakPoint(Handle<BreakPointInfo> info,
8441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                              Handle<Object> break_point_object);
8442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Set a break point.
8443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static void SetBreakPoint(Handle<BreakPointInfo> info,
8444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                            Handle<Object> break_point_object);
8445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Check if break point info has this break point object.
8446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static bool HasBreakPointObject(Handle<BreakPointInfo> info,
8447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                  Handle<Object> break_point_object);
8448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Get the number of break points for this code position.
8449a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int GetBreakPointCount();
8450a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline BreakPointInfo* cast(Object* obj);
8452a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8453b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef OBJECT_PRINT
8454b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  inline void BreakPointInfoPrint() {
8455b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    BreakPointInfoPrint(stdout);
8456b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
8457b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void BreakPointInfoPrint(FILE* out);
8458b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif
8459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG
8460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void BreakPointInfoVerify();
8461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
8462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kCodePositionIndex = Struct::kHeaderSize;
8464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kSourcePositionIndex = kCodePositionIndex + kPointerSize;
8465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kStatementPositionIndex =
8466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      kSourcePositionIndex + kPointerSize;
8467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kBreakPointObjectsIndex =
8468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      kStatementPositionIndex + kPointerSize;
8469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kSize = kBreakPointObjectsIndex + kPointerSize;
8470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
8472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DISALLOW_IMPLICIT_CONSTRUCTORS(BreakPointInfo);
8473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
8474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif  // ENABLE_DEBUGGER_SUPPORT
8475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#undef DECL_BOOLEAN_ACCESSORS
8478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#undef DECL_ACCESSORS
8479a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
84803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#define VISITOR_SYNCHRONIZATION_TAGS_LIST(V)                            \
84813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  V(kSymbolTable, "symbol_table", "(Symbols)")                          \
84823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  V(kExternalStringsTable, "external_strings_table", "(External strings)") \
84833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  V(kStrongRootList, "strong_root_list", "(Strong roots)")              \
84843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  V(kSymbol, "symbol", "(Symbol)")                                      \
84853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  V(kBootstrapper, "bootstrapper", "(Bootstrapper)")                    \
84863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  V(kTop, "top", "(Isolate)")                                           \
84873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  V(kRelocatable, "relocatable", "(Relocatable)")                       \
84883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  V(kDebug, "debug", "(Debugger)")                                      \
84893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  V(kCompilationCache, "compilationcache", "(Compilation cache)")       \
84903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  V(kHandleScope, "handlescope", "(Handle scope)")                      \
84913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  V(kBuiltins, "builtins", "(Builtins)")                                \
84923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  V(kGlobalHandles, "globalhandles", "(Global handles)")                \
84933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  V(kThreadManager, "threadmanager", "(Thread manager)")                \
84943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  V(kExtensions, "Extensions", "(Extensions)")
84953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
84963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochclass VisitorSynchronization : public AllStatic {
84973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public:
84983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#define DECLARE_ENUM(enum_item, ignore1, ignore2) enum_item,
84993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  enum SyncTag {
85003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    VISITOR_SYNCHRONIZATION_TAGS_LIST(DECLARE_ENUM)
85013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    kNumberOfSyncTags
85023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  };
85033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#undef DECLARE_ENUM
85043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
85053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const char* const kTags[kNumberOfSyncTags];
85063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const char* const kTagNames[kNumberOfSyncTags];
85073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch};
8508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Abstract base class for visiting, and optionally modifying, the
8510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// pointers contained in Objects. Used in GC and serialization/deserialization.
8511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass ObjectVisitor BASE_EMBEDDED {
8512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
8513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  virtual ~ObjectVisitor() {}
8514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Visits a contiguous arrays of pointers in the half-open range
8516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // [start, end). Any or all of the values may be modified on return.
8517a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  virtual void VisitPointers(Object** start, Object** end) = 0;
8518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8519a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // To allow lazy clearing of inline caches the visitor has
8520a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // a rich interface for iterating over Code objects..
8521a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8522a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Visits a code target in the instruction stream.
8523a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  virtual void VisitCodeTarget(RelocInfo* rinfo);
8524a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8525791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block  // Visits a code entry in a JS function.
8526791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block  virtual void VisitCodeEntry(Address entry_address);
8527791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block
8528b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Visits a global property cell reference in the instruction stream.
8529b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  virtual void VisitGlobalPropertyCell(RelocInfo* rinfo);
8530b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
8531a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Visits a runtime entry in the instruction stream.
8532a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  virtual void VisitRuntimeEntry(RelocInfo* rinfo) {}
8533a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8534d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // Visits the resource of an ASCII or two-byte string.
8535d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  virtual void VisitExternalAsciiString(
8536d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      v8::String::ExternalAsciiStringResource** resource) {}
8537d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  virtual void VisitExternalTwoByteString(
8538d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      v8::String::ExternalStringResource** resource) {}
8539d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
8540a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Visits a debug call target in the instruction stream.
8541a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  virtual void VisitDebugTarget(RelocInfo* rinfo);
8542a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8543a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Handy shorthand for visiting a single pointer.
8544a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  virtual void VisitPointer(Object** p) { VisitPointers(p, p + 1); }
8545a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
85463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Visit pointer embedded into a code object.
85473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  virtual void VisitEmbeddedPointer(RelocInfo* rinfo);
85483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
85498f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch  virtual void VisitSharedFunctionInfo(SharedFunctionInfo* shared) {}
85508f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch
8551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Visits a contiguous arrays of external references (references to the C++
8552a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // heap) in the half-open range [start, end). Any or all of the values
8553a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // may be modified on return.
8554a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  virtual void VisitExternalReferences(Address* start, Address* end) {}
8555a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
85563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  virtual void VisitExternalReference(RelocInfo* rinfo);
85573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
8558a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void VisitExternalReference(Address* p) {
8559a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    VisitExternalReferences(p, p + 1);
8560a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
8561a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
856244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Visits a handle that has an embedder-assigned class ID.
856344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  virtual void VisitEmbedderReference(Object** p, uint16_t class_id) {}
856444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
8565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Intended for serialization/deserialization checking: insert, or
8566a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // check for the presence of, a tag at this position in the stream.
85673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Also used for marking up GC roots in heap snapshots.
85683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  virtual void Synchronize(VisitorSynchronization::SyncTag tag) {}
8569a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
8570a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8572756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrickclass StructBodyDescriptor : public
8573756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  FlexibleBodyDescriptor<HeapObject::kHeaderSize> {
8574756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick public:
8575756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  static inline int SizeOf(Map* map, HeapObject* object) {
8576756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick    return map->instance_size();
8577756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  }
8578756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick};
8579756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
8580756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
8581a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// BooleanBit is a helper class for setting and getting a bit in an
8582a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// integer or Smi.
8583a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass BooleanBit : public AllStatic {
8584a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
8585a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline bool get(Smi* smi, int bit_position) {
8586a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return get(smi->value(), bit_position);
8587a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
8588a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8589a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline bool get(int value, int bit_position) {
8590a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return (value & (1 << bit_position)) != 0;
8591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
8592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8593a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline Smi* set(Smi* smi, int bit_position, bool v) {
8594a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return Smi::FromInt(set(smi->value(), bit_position, v));
8595a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
8596a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8597a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline int set(int value, int bit_position, bool v) {
8598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (v) {
8599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      value |= (1 << bit_position);
8600a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    } else {
8601a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      value &= ~(1 << bit_position);
8602a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
8603a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return value;
8604a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
8605a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
8606a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8607a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} }  // namespace v8::internal
8608a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8609a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif  // V8_OBJECTS_H_
8610