blob: 15d2d7278076720a4b117312bf419f1c3848a97f [file] [log] [blame]
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001// Copyright 2015 the V8 project authors. All rights reserved.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
Steve Blocka7e24c12009-10-30 11:49:00 +00004
5#ifndef V8_OBJECTS_H_
6#define V8_OBJECTS_H_
7
Emily Bernierd0a1eb72015-03-24 16:35:39 -04008#include <iosfwd>
9
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010#include "src/assert-scope.h"
11#include "src/bailout-reason.h"
12#include "src/base/bits.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000013#include "src/base/flags.h"
14#include "src/base/smart-pointers.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000015#include "src/builtins.h"
16#include "src/checks.h"
17#include "src/elements-kind.h"
18#include "src/field-index.h"
19#include "src/flags.h"
20#include "src/list.h"
21#include "src/property-details.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000022#include "src/unicode.h"
Emily Bernierd0a1eb72015-03-24 16:35:39 -040023#include "src/unicode-decoder.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000024#include "src/zone.h"
25
Steve Block3ce2e202009-11-05 08:53:23 +000026#if V8_TARGET_ARCH_ARM
Ben Murdochb8a8cc12014-11-26 15:28:44 +000027#include "src/arm/constants-arm.h" // NOLINT
28#elif V8_TARGET_ARCH_ARM64
29#include "src/arm64/constants-arm64.h" // NOLINT
Andrei Popescu31002712010-02-23 13:46:05 +000030#elif V8_TARGET_ARCH_MIPS
Ben Murdochb8a8cc12014-11-26 15:28:44 +000031#include "src/mips/constants-mips.h" // NOLINT
32#elif V8_TARGET_ARCH_MIPS64
33#include "src/mips64/constants-mips64.h" // NOLINT
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000034#elif V8_TARGET_ARCH_PPC
35#include "src/ppc/constants-ppc.h" // NOLINT
Ben Murdochda12d292016-06-02 14:46:10 +010036#elif V8_TARGET_ARCH_S390
37#include "src/s390/constants-s390.h" // NOLINT
Steve Block3ce2e202009-11-05 08:53:23 +000038#endif
Ben Murdoch3ef787d2012-04-12 10:51:47 +010039
Steve Blocka7e24c12009-10-30 11:49:00 +000040
41//
Kristian Monsen50ef84f2010-07-29 15:18:00 +010042// Most object types in the V8 JavaScript are described in this file.
Steve Blocka7e24c12009-10-30 11:49:00 +000043//
44// Inheritance hierarchy:
Ben Murdochb8a8cc12014-11-26 15:28:44 +000045// - Object
46// - Smi (immediate small integer)
47// - HeapObject (superclass for everything allocated in the heap)
48// - JSReceiver (suitable for property access)
49// - JSObject
50// - JSArray
51// - JSArrayBuffer
52// - JSArrayBufferView
53// - JSTypedArray
54// - JSDataView
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000055// - JSBoundFunction
Ben Murdochb8a8cc12014-11-26 15:28:44 +000056// - JSCollection
Ben Murdoch3ef787d2012-04-12 10:51:47 +010057// - JSSet
58// - JSMap
Ben Murdochb8a8cc12014-11-26 15:28:44 +000059// - JSSetIterator
60// - JSMapIterator
61// - JSWeakCollection
Ben Murdoch69a99ed2011-11-30 16:03:39 +000062// - JSWeakMap
Ben Murdochb8a8cc12014-11-26 15:28:44 +000063// - JSWeakSet
64// - JSRegExp
65// - JSFunction
66// - JSGeneratorObject
67// - JSModule
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000068// - JSGlobalObject
Ben Murdochb8a8cc12014-11-26 15:28:44 +000069// - JSGlobalProxy
70// - JSValue
71// - JSDate
72// - JSMessageObject
73// - JSProxy
Ben Murdochb8a8cc12014-11-26 15:28:44 +000074// - FixedArrayBase
75// - ByteArray
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000076// - BytecodeArray
Ben Murdochb8a8cc12014-11-26 15:28:44 +000077// - FixedArray
78// - DescriptorArray
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000079// - LiteralsArray
Ben Murdochb8a8cc12014-11-26 15:28:44 +000080// - HashTable
81// - Dictionary
82// - StringTable
Ben Murdochda12d292016-06-02 14:46:10 +010083// - StringSet
Ben Murdochb8a8cc12014-11-26 15:28:44 +000084// - CompilationCacheTable
85// - CodeCacheHashTable
86// - MapCache
87// - OrderedHashTable
88// - OrderedHashSet
89// - OrderedHashMap
90// - Context
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000091// - TypeFeedbackMetadata
Ben Murdochb8a8cc12014-11-26 15:28:44 +000092// - TypeFeedbackVector
Ben Murdochb8a8cc12014-11-26 15:28:44 +000093// - ScopeInfo
94// - TransitionArray
Emily Bernierd0a1eb72015-03-24 16:35:39 -040095// - ScriptContextTable
96// - WeakFixedArray
Ben Murdochb8a8cc12014-11-26 15:28:44 +000097// - FixedDoubleArray
Ben Murdochb8a8cc12014-11-26 15:28:44 +000098// - Name
Steve Blocka7e24c12009-10-30 11:49:00 +000099// - String
100// - SeqString
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000101// - SeqOneByteString
Steve Blocka7e24c12009-10-30 11:49:00 +0000102// - SeqTwoByteString
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000103// - SlicedString
Steve Blocka7e24c12009-10-30 11:49:00 +0000104// - ConsString
Steve Blocka7e24c12009-10-30 11:49:00 +0000105// - ExternalString
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000106// - ExternalOneByteString
Steve Blocka7e24c12009-10-30 11:49:00 +0000107// - ExternalTwoByteString
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000108// - InternalizedString
109// - SeqInternalizedString
110// - SeqOneByteInternalizedString
111// - SeqTwoByteInternalizedString
112// - ConsInternalizedString
113// - ExternalInternalizedString
114// - ExternalOneByteInternalizedString
115// - ExternalTwoByteInternalizedString
116// - Symbol
117// - HeapNumber
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000118// - Simd128Value
119// - Float32x4
120// - Int32x4
121// - Uint32x4
122// - Bool32x4
123// - Int16x8
124// - Uint16x8
125// - Bool16x8
126// - Int8x16
127// - Uint8x16
128// - Bool8x16
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000129// - Cell
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000130// - PropertyCell
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000131// - Code
Ben Murdoch097c5b22016-05-18 11:27:45 +0100132// - AbstractCode, a wrapper around Code or BytecodeArray
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000133// - Map
134// - Oddball
135// - Foreign
136// - SharedFunctionInfo
137// - Struct
138// - Box
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000139// - AccessorInfo
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000140// - AccessorPair
141// - AccessCheckInfo
142// - InterceptorInfo
143// - CallHandlerInfo
144// - TemplateInfo
145// - FunctionTemplateInfo
146// - ObjectTemplateInfo
147// - Script
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000148// - DebugInfo
149// - BreakPointInfo
150// - CodeCache
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000151// - PrototypeInfo
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400152// - WeakCell
Steve Blocka7e24c12009-10-30 11:49:00 +0000153//
154// Formats of Object*:
155// Smi: [31 bit signed int] 0
156// HeapObject: [32 bit direct pointer] (4 byte aligned) | 01
Steve Blocka7e24c12009-10-30 11:49:00 +0000157
Steve Blocka7e24c12009-10-30 11:49:00 +0000158namespace v8 {
159namespace internal {
160
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000161enum KeyedAccessStoreMode {
162 STANDARD_STORE,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000163 STORE_TRANSITION_TO_OBJECT,
164 STORE_TRANSITION_TO_DOUBLE,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000165 STORE_AND_GROW_NO_TRANSITION,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000166 STORE_AND_GROW_TRANSITION_TO_OBJECT,
167 STORE_AND_GROW_TRANSITION_TO_DOUBLE,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000168 STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS,
169 STORE_NO_TRANSITION_HANDLE_COW
Ben Murdoch589d6972011-11-30 16:04:58 +0000170};
171
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000172
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000173// Valid hints for the abstract operation ToPrimitive,
174// implemented according to ES6, section 7.1.1.
175enum class ToPrimitiveHint { kDefault, kNumber, kString };
176
177
178// Valid hints for the abstract operation OrdinaryToPrimitive,
179// implemented according to ES6, section 7.1.1.
180enum class OrdinaryToPrimitiveHint { kNumber, kString };
181
182
183enum TypeofMode : int { INSIDE_TYPEOF, NOT_INSIDE_TYPEOF };
Ben Murdochc7cc0282012-03-05 14:35:55 +0000184
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000185
186enum MutableMode {
187 MUTABLE,
188 IMMUTABLE
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100189};
190
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100191
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000192enum ExternalArrayType {
193 kExternalInt8Array = 1,
194 kExternalUint8Array,
195 kExternalInt16Array,
196 kExternalUint16Array,
197 kExternalInt32Array,
198 kExternalUint32Array,
199 kExternalFloat32Array,
200 kExternalFloat64Array,
201 kExternalUint8ClampedArray,
202};
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000203
204
205static inline bool IsTransitionStoreMode(KeyedAccessStoreMode store_mode) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000206 return store_mode == STORE_TRANSITION_TO_OBJECT ||
207 store_mode == STORE_TRANSITION_TO_DOUBLE ||
208 store_mode == STORE_AND_GROW_TRANSITION_TO_OBJECT ||
209 store_mode == STORE_AND_GROW_TRANSITION_TO_DOUBLE;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000210}
211
212
213static inline KeyedAccessStoreMode GetNonTransitioningStoreMode(
214 KeyedAccessStoreMode store_mode) {
215 if (store_mode >= STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) {
216 return store_mode;
217 }
218 if (store_mode >= STORE_AND_GROW_NO_TRANSITION) {
219 return STORE_AND_GROW_NO_TRANSITION;
220 }
221 return STANDARD_STORE;
222}
223
224
225static inline bool IsGrowStoreMode(KeyedAccessStoreMode store_mode) {
226 return store_mode >= STORE_AND_GROW_NO_TRANSITION &&
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000227 store_mode <= STORE_AND_GROW_TRANSITION_TO_DOUBLE;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000228}
229
Steve Blocka7e24c12009-10-30 11:49:00 +0000230
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400231enum IcCheckType { ELEMENT, PROPERTY };
232
233
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000234// SKIP_WRITE_BARRIER skips the write barrier.
235// UPDATE_WEAK_WRITE_BARRIER skips the marking part of the write barrier and
236// only performs the generational part.
237// UPDATE_WRITE_BARRIER is doing the full barrier, marking and generational.
238enum WriteBarrierMode {
239 SKIP_WRITE_BARRIER,
240 UPDATE_WEAK_WRITE_BARRIER,
241 UPDATE_WRITE_BARRIER
242};
Steve Blocka7e24c12009-10-30 11:49:00 +0000243
244
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000245// Indicates whether a value can be loaded as a constant.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000246enum StoreMode { ALLOW_IN_DESCRIPTOR, FORCE_FIELD };
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000247
248
Steve Blocka7e24c12009-10-30 11:49:00 +0000249// PropertyNormalizationMode is used to specify whether to keep
250// inobject properties when normalizing properties of a JSObject.
251enum PropertyNormalizationMode {
252 CLEAR_INOBJECT_PROPERTIES,
253 KEEP_INOBJECT_PROPERTIES
254};
255
256
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000257// Indicates how aggressively the prototype should be optimized. FAST_PROTOTYPE
258// will give the fastest result by tailoring the map to the prototype, but that
259// will cause polymorphism with other objects. REGULAR_PROTOTYPE is to be used
260// (at least for now) when dynamically modifying the prototype chain of an
261// object using __proto__ or Object.setPrototypeOf.
262enum PrototypeOptimizationMode { REGULAR_PROTOTYPE, FAST_PROTOTYPE };
263
264
265// Indicates whether transitions can be added to a source map or not.
266enum TransitionFlag {
267 INSERT_TRANSITION,
268 OMIT_TRANSITION
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100269};
270
271
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000272// Indicates whether the transition is simple: the target map of the transition
273// either extends the current map with a new property, or it modifies the
274// property that was added last to the current map.
275enum SimpleTransitionFlag {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400276 SIMPLE_PROPERTY_TRANSITION,
277 PROPERTY_TRANSITION,
278 SPECIAL_TRANSITION
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000279};
280
281
282// Indicates whether we are only interested in the descriptors of a particular
283// map, or in all descriptors in the descriptor array.
284enum DescriptorFlag {
285 ALL_DESCRIPTORS,
286 OWN_DESCRIPTORS
287};
288
289// The GC maintains a bit of information, the MarkingParity, which toggles
290// from odd to even and back every time marking is completed. Incremental
291// marking can visit an object twice during a marking phase, so algorithms that
292// that piggy-back on marking can use the parity to ensure that they only
293// perform an operation on an object once per marking phase: they record the
294// MarkingParity when they visit an object, and only re-visit the object when it
295// is marked again and the MarkingParity changes.
296enum MarkingParity {
297 NO_MARKING_PARITY,
298 ODD_MARKING_PARITY,
299 EVEN_MARKING_PARITY
300};
301
302// ICs store extra state in a Code object. The default extra state is
303// kNoExtraICState.
304typedef int ExtraICState;
305static const ExtraICState kNoExtraICState = 0;
306
Steve Block791712a2010-08-27 10:21:07 +0100307// Instance size sentinel for objects of variable size.
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100308const int kVariableSizeSentinel = 0;
Steve Block791712a2010-08-27 10:21:07 +0100309
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000310// We may store the unsigned bit field as signed Smi value and do not
311// use the sign bit.
Ben Murdochc5610432016-08-08 18:44:38 +0100312const int kStubMajorKeyBits = 8;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000313const int kStubMinorKeyBits = kSmiValueSize - kStubMajorKeyBits - 1;
Steve Block791712a2010-08-27 10:21:07 +0100314
Steve Blocka7e24c12009-10-30 11:49:00 +0000315// All Maps have a field instance_type containing a InstanceType.
316// It describes the type of the instances.
317//
318// As an example, a JavaScript object is a heap object and its map
319// instance_type is JS_OBJECT_TYPE.
320//
321// The names of the string instance types are intended to systematically
Leon Clarkee46be812010-01-19 14:06:41 +0000322// mirror their encoding in the instance_type field of the map. The default
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000323// encoding is considered TWO_BYTE. It is not mentioned in the name. ONE_BYTE
Leon Clarkee46be812010-01-19 14:06:41 +0000324// encoding is mentioned explicitly in the name. Likewise, the default
325// representation is considered sequential. It is not mentioned in the
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100326// name. The other representations (e.g. CONS, EXTERNAL) are explicitly
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000327// mentioned. Finally, the string is either a STRING_TYPE (if it is a normal
328// string) or a INTERNALIZED_STRING_TYPE (if it is a internalized string).
Steve Blocka7e24c12009-10-30 11:49:00 +0000329//
330// NOTE: The following things are some that depend on the string types having
331// instance_types that are less than those of all other types:
332// HeapObject::Size, HeapObject::IterateBody, the typeof operator, and
333// Object::IsString.
334//
335// NOTE: Everything following JS_VALUE_TYPE is considered a
336// JSObject for GC purposes. The first four entries here have typeof
337// 'object', whereas JS_FUNCTION_TYPE has typeof 'function'.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000338#define INSTANCE_TYPE_LIST(V) \
339 V(STRING_TYPE) \
340 V(ONE_BYTE_STRING_TYPE) \
341 V(CONS_STRING_TYPE) \
342 V(CONS_ONE_BYTE_STRING_TYPE) \
343 V(SLICED_STRING_TYPE) \
344 V(SLICED_ONE_BYTE_STRING_TYPE) \
345 V(EXTERNAL_STRING_TYPE) \
346 V(EXTERNAL_ONE_BYTE_STRING_TYPE) \
347 V(EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE) \
348 V(SHORT_EXTERNAL_STRING_TYPE) \
349 V(SHORT_EXTERNAL_ONE_BYTE_STRING_TYPE) \
350 V(SHORT_EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE) \
351 \
352 V(INTERNALIZED_STRING_TYPE) \
353 V(ONE_BYTE_INTERNALIZED_STRING_TYPE) \
354 V(EXTERNAL_INTERNALIZED_STRING_TYPE) \
355 V(EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE) \
356 V(EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE) \
357 V(SHORT_EXTERNAL_INTERNALIZED_STRING_TYPE) \
358 V(SHORT_EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE) \
359 V(SHORT_EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE) \
360 \
361 V(SYMBOL_TYPE) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000362 V(SIMD128_VALUE_TYPE) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000363 \
364 V(MAP_TYPE) \
365 V(CODE_TYPE) \
366 V(ODDBALL_TYPE) \
367 V(CELL_TYPE) \
368 V(PROPERTY_CELL_TYPE) \
369 \
370 V(HEAP_NUMBER_TYPE) \
371 V(MUTABLE_HEAP_NUMBER_TYPE) \
372 V(FOREIGN_TYPE) \
373 V(BYTE_ARRAY_TYPE) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000374 V(BYTECODE_ARRAY_TYPE) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000375 V(FREE_SPACE_TYPE) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000376 \
377 V(FIXED_INT8_ARRAY_TYPE) \
378 V(FIXED_UINT8_ARRAY_TYPE) \
379 V(FIXED_INT16_ARRAY_TYPE) \
380 V(FIXED_UINT16_ARRAY_TYPE) \
381 V(FIXED_INT32_ARRAY_TYPE) \
382 V(FIXED_UINT32_ARRAY_TYPE) \
383 V(FIXED_FLOAT32_ARRAY_TYPE) \
384 V(FIXED_FLOAT64_ARRAY_TYPE) \
385 V(FIXED_UINT8_CLAMPED_ARRAY_TYPE) \
386 \
387 V(FILLER_TYPE) \
388 \
Ben Murdoch097c5b22016-05-18 11:27:45 +0100389 V(ACCESSOR_INFO_TYPE) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000390 V(ACCESSOR_PAIR_TYPE) \
391 V(ACCESS_CHECK_INFO_TYPE) \
392 V(INTERCEPTOR_INFO_TYPE) \
393 V(CALL_HANDLER_INFO_TYPE) \
394 V(FUNCTION_TEMPLATE_INFO_TYPE) \
395 V(OBJECT_TEMPLATE_INFO_TYPE) \
396 V(SIGNATURE_INFO_TYPE) \
397 V(TYPE_SWITCH_INFO_TYPE) \
398 V(ALLOCATION_MEMENTO_TYPE) \
399 V(ALLOCATION_SITE_TYPE) \
400 V(SCRIPT_TYPE) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000401 V(TYPE_FEEDBACK_INFO_TYPE) \
402 V(ALIASED_ARGUMENTS_ENTRY_TYPE) \
403 V(BOX_TYPE) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000404 V(PROTOTYPE_INFO_TYPE) \
405 V(SLOPPY_BLOCK_WITH_EVAL_CONTEXT_EXTENSION_TYPE) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000406 \
407 V(FIXED_ARRAY_TYPE) \
408 V(FIXED_DOUBLE_ARRAY_TYPE) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000409 V(SHARED_FUNCTION_INFO_TYPE) \
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400410 V(WEAK_CELL_TYPE) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000411 V(TRANSITION_ARRAY_TYPE) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000412 \
413 V(JS_MESSAGE_OBJECT_TYPE) \
414 \
415 V(JS_VALUE_TYPE) \
416 V(JS_DATE_TYPE) \
417 V(JS_OBJECT_TYPE) \
418 V(JS_CONTEXT_EXTENSION_OBJECT_TYPE) \
419 V(JS_GENERATOR_OBJECT_TYPE) \
420 V(JS_MODULE_TYPE) \
421 V(JS_GLOBAL_OBJECT_TYPE) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000422 V(JS_GLOBAL_PROXY_TYPE) \
Ben Murdochc5610432016-08-08 18:44:38 +0100423 V(JS_API_OBJECT_TYPE) \
Ben Murdochda12d292016-06-02 14:46:10 +0100424 V(JS_SPECIAL_API_OBJECT_TYPE) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000425 V(JS_ARRAY_TYPE) \
426 V(JS_ARRAY_BUFFER_TYPE) \
427 V(JS_TYPED_ARRAY_TYPE) \
428 V(JS_DATA_VIEW_TYPE) \
429 V(JS_PROXY_TYPE) \
430 V(JS_SET_TYPE) \
431 V(JS_MAP_TYPE) \
432 V(JS_SET_ITERATOR_TYPE) \
433 V(JS_MAP_ITERATOR_TYPE) \
434 V(JS_WEAK_MAP_TYPE) \
435 V(JS_WEAK_SET_TYPE) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000436 V(JS_PROMISE_TYPE) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000437 V(JS_REGEXP_TYPE) \
438 \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000439 V(JS_BOUND_FUNCTION_TYPE) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000440 V(JS_FUNCTION_TYPE) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000441 V(DEBUG_INFO_TYPE) \
Steve Blocka7e24c12009-10-30 11:49:00 +0000442 V(BREAK_POINT_INFO_TYPE)
Steve Blocka7e24c12009-10-30 11:49:00 +0000443
Steve Blocka7e24c12009-10-30 11:49:00 +0000444// Since string types are not consecutive, this macro is used to
445// iterate over them.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000446#define STRING_TYPE_LIST(V) \
447 V(STRING_TYPE, kVariableSizeSentinel, string, String) \
448 V(ONE_BYTE_STRING_TYPE, kVariableSizeSentinel, one_byte_string, \
449 OneByteString) \
450 V(CONS_STRING_TYPE, ConsString::kSize, cons_string, ConsString) \
451 V(CONS_ONE_BYTE_STRING_TYPE, ConsString::kSize, cons_one_byte_string, \
452 ConsOneByteString) \
453 V(SLICED_STRING_TYPE, SlicedString::kSize, sliced_string, SlicedString) \
454 V(SLICED_ONE_BYTE_STRING_TYPE, SlicedString::kSize, sliced_one_byte_string, \
455 SlicedOneByteString) \
456 V(EXTERNAL_STRING_TYPE, ExternalTwoByteString::kSize, external_string, \
457 ExternalString) \
458 V(EXTERNAL_ONE_BYTE_STRING_TYPE, ExternalOneByteString::kSize, \
459 external_one_byte_string, ExternalOneByteString) \
460 V(EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE, ExternalTwoByteString::kSize, \
461 external_string_with_one_byte_data, ExternalStringWithOneByteData) \
462 V(SHORT_EXTERNAL_STRING_TYPE, ExternalTwoByteString::kShortSize, \
463 short_external_string, ShortExternalString) \
464 V(SHORT_EXTERNAL_ONE_BYTE_STRING_TYPE, ExternalOneByteString::kShortSize, \
465 short_external_one_byte_string, ShortExternalOneByteString) \
466 V(SHORT_EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE, \
467 ExternalTwoByteString::kShortSize, \
468 short_external_string_with_one_byte_data, \
469 ShortExternalStringWithOneByteData) \
470 \
471 V(INTERNALIZED_STRING_TYPE, kVariableSizeSentinel, internalized_string, \
472 InternalizedString) \
473 V(ONE_BYTE_INTERNALIZED_STRING_TYPE, kVariableSizeSentinel, \
474 one_byte_internalized_string, OneByteInternalizedString) \
475 V(EXTERNAL_INTERNALIZED_STRING_TYPE, ExternalTwoByteString::kSize, \
476 external_internalized_string, ExternalInternalizedString) \
477 V(EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE, ExternalOneByteString::kSize, \
478 external_one_byte_internalized_string, ExternalOneByteInternalizedString) \
479 V(EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE, \
480 ExternalTwoByteString::kSize, \
481 external_internalized_string_with_one_byte_data, \
482 ExternalInternalizedStringWithOneByteData) \
483 V(SHORT_EXTERNAL_INTERNALIZED_STRING_TYPE, \
484 ExternalTwoByteString::kShortSize, short_external_internalized_string, \
485 ShortExternalInternalizedString) \
486 V(SHORT_EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE, \
487 ExternalOneByteString::kShortSize, \
488 short_external_one_byte_internalized_string, \
489 ShortExternalOneByteInternalizedString) \
490 V(SHORT_EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE, \
491 ExternalTwoByteString::kShortSize, \
492 short_external_internalized_string_with_one_byte_data, \
493 ShortExternalInternalizedStringWithOneByteData)
Steve Blocka7e24c12009-10-30 11:49:00 +0000494
495// A struct is a simple object a set of object-valued fields. Including an
496// object type in this causes the compiler to generate most of the boilerplate
497// code for the class including allocation and garbage collection routines,
498// casts and predicates. All you need to define is the class, methods and
499// object verification routines. Easy, no?
500//
501// Note that for subtle reasons related to the ordering or numerical values of
502// type tags, elements in this list have to be added to the INSTANCE_TYPE_LIST
503// manually.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000504#define STRUCT_LIST(V) \
505 V(BOX, Box, box) \
Ben Murdoch097c5b22016-05-18 11:27:45 +0100506 V(ACCESSOR_INFO, AccessorInfo, accessor_info) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000507 V(ACCESSOR_PAIR, AccessorPair, accessor_pair) \
508 V(ACCESS_CHECK_INFO, AccessCheckInfo, access_check_info) \
509 V(INTERCEPTOR_INFO, InterceptorInfo, interceptor_info) \
510 V(CALL_HANDLER_INFO, CallHandlerInfo, call_handler_info) \
511 V(FUNCTION_TEMPLATE_INFO, FunctionTemplateInfo, function_template_info) \
512 V(OBJECT_TEMPLATE_INFO, ObjectTemplateInfo, object_template_info) \
513 V(SCRIPT, Script, script) \
514 V(ALLOCATION_SITE, AllocationSite, allocation_site) \
515 V(ALLOCATION_MEMENTO, AllocationMemento, allocation_memento) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000516 V(TYPE_FEEDBACK_INFO, TypeFeedbackInfo, type_feedback_info) \
517 V(ALIASED_ARGUMENTS_ENTRY, AliasedArgumentsEntry, aliased_arguments_entry) \
518 V(DEBUG_INFO, DebugInfo, debug_info) \
519 V(BREAK_POINT_INFO, BreakPointInfo, break_point_info) \
520 V(PROTOTYPE_INFO, PrototypeInfo, prototype_info) \
521 V(SLOPPY_BLOCK_WITH_EVAL_CONTEXT_EXTENSION, \
522 SloppyBlockWithEvalContextExtension, \
523 sloppy_block_with_eval_context_extension)
Steve Blocka7e24c12009-10-30 11:49:00 +0000524
525// We use the full 8 bits of the instance_type field to encode heap object
526// instance types. The high-order bit (bit 7) is set if the object is not a
527// string, and cleared if it is a string.
528const uint32_t kIsNotStringMask = 0x80;
529const uint32_t kStringTag = 0x0;
530const uint32_t kNotStringTag = 0x80;
531
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000532// Bit 6 indicates that the object is an internalized string (if set) or not.
533// Bit 7 has to be clear as well.
534const uint32_t kIsNotInternalizedMask = 0x40;
535const uint32_t kNotInternalizedTag = 0x40;
536const uint32_t kInternalizedTag = 0x0;
Steve Blocka7e24c12009-10-30 11:49:00 +0000537
Steve Blocka7e24c12009-10-30 11:49:00 +0000538// If bit 7 is clear then bit 2 indicates whether the string consists of
539// two-byte characters or one-byte characters.
540const uint32_t kStringEncodingMask = 0x4;
541const uint32_t kTwoByteStringTag = 0x0;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000542const uint32_t kOneByteStringTag = 0x4;
Steve Blocka7e24c12009-10-30 11:49:00 +0000543
544// If bit 7 is clear, the low-order 2 bits indicate the representation
545// of the string.
546const uint32_t kStringRepresentationMask = 0x03;
547enum StringRepresentationTag {
548 kSeqStringTag = 0x0,
549 kConsStringTag = 0x1,
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000550 kExternalStringTag = 0x2,
551 kSlicedStringTag = 0x3
Steve Blocka7e24c12009-10-30 11:49:00 +0000552};
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000553const uint32_t kIsIndirectStringMask = 0x1;
554const uint32_t kIsIndirectStringTag = 0x1;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000555STATIC_ASSERT((kSeqStringTag & kIsIndirectStringMask) == 0); // NOLINT
556STATIC_ASSERT((kExternalStringTag & kIsIndirectStringMask) == 0); // NOLINT
557STATIC_ASSERT((kConsStringTag &
558 kIsIndirectStringMask) == kIsIndirectStringTag); // NOLINT
559STATIC_ASSERT((kSlicedStringTag &
560 kIsIndirectStringMask) == kIsIndirectStringTag); // NOLINT
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000561
562// Use this mask to distinguish between cons and slice only after making
563// sure that the string is one of the two (an indirect string).
564const uint32_t kSlicedNotConsMask = kSlicedStringTag & ~kConsStringTag;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000565STATIC_ASSERT(IS_POWER_OF_TWO(kSlicedNotConsMask));
Steve Blocka7e24c12009-10-30 11:49:00 +0000566
Kristian Monsen9dcf7e22010-06-28 14:14:28 +0100567// If bit 7 is clear, then bit 3 indicates whether this two-byte
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000568// string actually contains one byte data.
569const uint32_t kOneByteDataHintMask = 0x08;
570const uint32_t kOneByteDataHintTag = 0x08;
Kristian Monsen9dcf7e22010-06-28 14:14:28 +0100571
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100572// If bit 7 is clear and string representation indicates an external string,
573// then bit 4 indicates whether the data pointer is cached.
574const uint32_t kShortExternalStringMask = 0x10;
575const uint32_t kShortExternalStringTag = 0x10;
576
Steve Blocka7e24c12009-10-30 11:49:00 +0000577
578// A ConsString with an empty string as the right side is a candidate
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000579// for being shortcut by the garbage collector. We don't allocate any
580// non-flat internalized strings, so we do not shortcut them thereby
581// avoiding turning internalized strings into strings. The bit-masks
582// below contain the internalized bit as additional safety.
583// See heap.cc, mark-compact.cc and objects-visiting.cc.
Steve Blocka7e24c12009-10-30 11:49:00 +0000584const uint32_t kShortcutTypeMask =
585 kIsNotStringMask |
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000586 kIsNotInternalizedMask |
Steve Blocka7e24c12009-10-30 11:49:00 +0000587 kStringRepresentationMask;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000588const uint32_t kShortcutTypeTag = kConsStringTag | kNotInternalizedTag;
589
590static inline bool IsShortcutCandidate(int type) {
591 return ((type & kShortcutTypeMask) == kShortcutTypeTag);
592}
Steve Blocka7e24c12009-10-30 11:49:00 +0000593
Steve Blocka7e24c12009-10-30 11:49:00 +0000594enum InstanceType {
Leon Clarkee46be812010-01-19 14:06:41 +0000595 // String types.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000596 INTERNALIZED_STRING_TYPE = kTwoByteStringTag | kSeqStringTag |
597 kInternalizedTag, // FIRST_PRIMITIVE_TYPE
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000598 ONE_BYTE_INTERNALIZED_STRING_TYPE =
599 kOneByteStringTag | kSeqStringTag | kInternalizedTag,
600 EXTERNAL_INTERNALIZED_STRING_TYPE =
601 kTwoByteStringTag | kExternalStringTag | kInternalizedTag,
602 EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE =
603 kOneByteStringTag | kExternalStringTag | kInternalizedTag,
604 EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE =
605 EXTERNAL_INTERNALIZED_STRING_TYPE | kOneByteDataHintTag |
606 kInternalizedTag,
607 SHORT_EXTERNAL_INTERNALIZED_STRING_TYPE = EXTERNAL_INTERNALIZED_STRING_TYPE |
608 kShortExternalStringTag |
609 kInternalizedTag,
610 SHORT_EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE =
611 EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE | kShortExternalStringTag |
612 kInternalizedTag,
613 SHORT_EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE =
614 EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE |
615 kShortExternalStringTag | kInternalizedTag,
616 STRING_TYPE = INTERNALIZED_STRING_TYPE | kNotInternalizedTag,
617 ONE_BYTE_STRING_TYPE =
618 ONE_BYTE_INTERNALIZED_STRING_TYPE | kNotInternalizedTag,
619 CONS_STRING_TYPE = kTwoByteStringTag | kConsStringTag | kNotInternalizedTag,
620 CONS_ONE_BYTE_STRING_TYPE =
621 kOneByteStringTag | kConsStringTag | kNotInternalizedTag,
622 SLICED_STRING_TYPE =
623 kTwoByteStringTag | kSlicedStringTag | kNotInternalizedTag,
624 SLICED_ONE_BYTE_STRING_TYPE =
625 kOneByteStringTag | kSlicedStringTag | kNotInternalizedTag,
626 EXTERNAL_STRING_TYPE =
627 EXTERNAL_INTERNALIZED_STRING_TYPE | kNotInternalizedTag,
628 EXTERNAL_ONE_BYTE_STRING_TYPE =
629 EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE | kNotInternalizedTag,
630 EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE =
631 EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE |
632 kNotInternalizedTag,
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100633 SHORT_EXTERNAL_STRING_TYPE =
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000634 SHORT_EXTERNAL_INTERNALIZED_STRING_TYPE | kNotInternalizedTag,
635 SHORT_EXTERNAL_ONE_BYTE_STRING_TYPE =
636 SHORT_EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE | kNotInternalizedTag,
637 SHORT_EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE =
638 SHORT_EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE |
639 kNotInternalizedTag,
640
641 // Non-string names
642 SYMBOL_TYPE = kNotStringTag, // FIRST_NONSTRING_TYPE, LAST_NAME_TYPE
Steve Blocka7e24c12009-10-30 11:49:00 +0000643
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000644 // Other primitives (cannot contain non-map-word pointers to heap objects).
645 HEAP_NUMBER_TYPE,
646 SIMD128_VALUE_TYPE,
647 ODDBALL_TYPE, // LAST_PRIMITIVE_TYPE
648
Leon Clarkee46be812010-01-19 14:06:41 +0000649 // Objects allocated in their own spaces (never in new space).
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000650 MAP_TYPE,
Steve Blocka7e24c12009-10-30 11:49:00 +0000651 CODE_TYPE,
Leon Clarkee46be812010-01-19 14:06:41 +0000652
653 // "Data", objects that cannot contain non-map-word pointers to heap
654 // objects.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000655 MUTABLE_HEAP_NUMBER_TYPE,
Ben Murdoch257744e2011-11-30 15:57:28 +0000656 FOREIGN_TYPE,
Steve Blocka7e24c12009-10-30 11:49:00 +0000657 BYTE_ARRAY_TYPE,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000658 BYTECODE_ARRAY_TYPE,
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100659 FREE_SPACE_TYPE,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000660 FIXED_INT8_ARRAY_TYPE, // FIRST_FIXED_TYPED_ARRAY_TYPE
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000661 FIXED_UINT8_ARRAY_TYPE,
662 FIXED_INT16_ARRAY_TYPE,
663 FIXED_UINT16_ARRAY_TYPE,
664 FIXED_INT32_ARRAY_TYPE,
665 FIXED_UINT32_ARRAY_TYPE,
666 FIXED_FLOAT32_ARRAY_TYPE,
667 FIXED_FLOAT64_ARRAY_TYPE,
668 FIXED_UINT8_CLAMPED_ARRAY_TYPE, // LAST_FIXED_TYPED_ARRAY_TYPE
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000669 FIXED_DOUBLE_ARRAY_TYPE,
Leon Clarkee46be812010-01-19 14:06:41 +0000670 FILLER_TYPE, // LAST_DATA_TYPE
Steve Blocka7e24c12009-10-30 11:49:00 +0000671
Leon Clarkee46be812010-01-19 14:06:41 +0000672 // Structs.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100673 ACCESSOR_INFO_TYPE,
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100674 ACCESSOR_PAIR_TYPE,
Steve Blocka7e24c12009-10-30 11:49:00 +0000675 ACCESS_CHECK_INFO_TYPE,
676 INTERCEPTOR_INFO_TYPE,
Steve Blocka7e24c12009-10-30 11:49:00 +0000677 CALL_HANDLER_INFO_TYPE,
678 FUNCTION_TEMPLATE_INFO_TYPE,
679 OBJECT_TEMPLATE_INFO_TYPE,
680 SIGNATURE_INFO_TYPE,
681 TYPE_SWITCH_INFO_TYPE,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000682 ALLOCATION_SITE_TYPE,
683 ALLOCATION_MEMENTO_TYPE,
Leon Clarkee46be812010-01-19 14:06:41 +0000684 SCRIPT_TYPE,
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100685 TYPE_FEEDBACK_INFO_TYPE,
686 ALIASED_ARGUMENTS_ENTRY_TYPE,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000687 BOX_TYPE,
Steve Blocka7e24c12009-10-30 11:49:00 +0000688 DEBUG_INFO_TYPE,
689 BREAK_POINT_INFO_TYPE,
Leon Clarkee46be812010-01-19 14:06:41 +0000690 FIXED_ARRAY_TYPE,
691 SHARED_FUNCTION_INFO_TYPE,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000692 CELL_TYPE,
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400693 WEAK_CELL_TYPE,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000694 TRANSITION_ARRAY_TYPE,
695 PROPERTY_CELL_TYPE,
696 PROTOTYPE_INFO_TYPE,
697 SLOPPY_BLOCK_WITH_EVAL_CONTEXT_EXTENSION_TYPE,
Leon Clarkee46be812010-01-19 14:06:41 +0000698
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100699 // All the following types are subtypes of JSReceiver, which corresponds to
700 // objects in the JS sense. The first and the last type in this range are
701 // the two forms of function. This organization enables using the same
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000702 // compares for checking the JS_RECEIVER and the NONCALLABLE_JS_OBJECT range.
Ben Murdochda12d292016-06-02 14:46:10 +0100703 JS_PROXY_TYPE, // FIRST_JS_RECEIVER_TYPE
704 JS_GLOBAL_OBJECT_TYPE, // FIRST_JS_OBJECT_TYPE
705 JS_GLOBAL_PROXY_TYPE,
Ben Murdochc5610432016-08-08 18:44:38 +0100706 // Like JS_API_OBJECT_TYPE, but requires access checks and/or has
707 // interceptors.
Ben Murdochda12d292016-06-02 14:46:10 +0100708 JS_SPECIAL_API_OBJECT_TYPE, // LAST_SPECIAL_RECEIVER_TYPE
709 JS_VALUE_TYPE, // LAST_CUSTOM_ELEMENTS_RECEIVER
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000710 JS_MESSAGE_OBJECT_TYPE,
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100711 JS_DATE_TYPE,
Ben Murdochc5610432016-08-08 18:44:38 +0100712 // Like JS_OBJECT_TYPE, but created from API function.
713 JS_API_OBJECT_TYPE,
Steve Blocka7e24c12009-10-30 11:49:00 +0000714 JS_OBJECT_TYPE,
715 JS_CONTEXT_EXTENSION_OBJECT_TYPE,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000716 JS_GENERATOR_OBJECT_TYPE,
717 JS_MODULE_TYPE,
Steve Blocka7e24c12009-10-30 11:49:00 +0000718 JS_ARRAY_TYPE,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000719 JS_ARRAY_BUFFER_TYPE,
720 JS_TYPED_ARRAY_TYPE,
721 JS_DATA_VIEW_TYPE,
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100722 JS_SET_TYPE,
723 JS_MAP_TYPE,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000724 JS_SET_ITERATOR_TYPE,
725 JS_MAP_ITERATOR_TYPE,
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000726 JS_WEAK_MAP_TYPE,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000727 JS_WEAK_SET_TYPE,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000728 JS_PROMISE_TYPE,
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100729 JS_REGEXP_TYPE,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000730 JS_BOUND_FUNCTION_TYPE,
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100731 JS_FUNCTION_TYPE, // LAST_JS_OBJECT_TYPE, LAST_JS_RECEIVER_TYPE
Steve Blocka7e24c12009-10-30 11:49:00 +0000732
733 // Pseudo-types
Steve Blocka7e24c12009-10-30 11:49:00 +0000734 FIRST_TYPE = 0x0,
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100735 LAST_TYPE = JS_FUNCTION_TYPE,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000736 FIRST_NAME_TYPE = FIRST_TYPE,
737 LAST_NAME_TYPE = SYMBOL_TYPE,
738 FIRST_UNIQUE_NAME_TYPE = INTERNALIZED_STRING_TYPE,
739 LAST_UNIQUE_NAME_TYPE = SYMBOL_TYPE,
740 FIRST_NONSTRING_TYPE = SYMBOL_TYPE,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000741 FIRST_PRIMITIVE_TYPE = FIRST_NAME_TYPE,
742 LAST_PRIMITIVE_TYPE = ODDBALL_TYPE,
743 FIRST_FUNCTION_TYPE = JS_BOUND_FUNCTION_TYPE,
744 LAST_FUNCTION_TYPE = JS_FUNCTION_TYPE,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000745 // Boundaries for testing for a fixed typed array.
746 FIRST_FIXED_TYPED_ARRAY_TYPE = FIXED_INT8_ARRAY_TYPE,
747 LAST_FIXED_TYPED_ARRAY_TYPE = FIXED_UINT8_CLAMPED_ARRAY_TYPE,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000748 // Boundary for promotion to old space.
Leon Clarkee46be812010-01-19 14:06:41 +0000749 LAST_DATA_TYPE = FILLER_TYPE,
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000750 // Boundary for objects represented as JSReceiver (i.e. JSObject or JSProxy).
751 // Note that there is no range for JSObject or JSProxy, since their subtypes
752 // are not continuous in this enum! The enum ranges instead reflect the
753 // external class names, where proxies are treated as either ordinary objects,
754 // or functions.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000755 FIRST_JS_RECEIVER_TYPE = JS_PROXY_TYPE,
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000756 LAST_JS_RECEIVER_TYPE = LAST_TYPE,
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100757 // Boundaries for testing the types represented as JSObject
Ben Murdochda12d292016-06-02 14:46:10 +0100758 FIRST_JS_OBJECT_TYPE = JS_GLOBAL_OBJECT_TYPE,
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100759 LAST_JS_OBJECT_TYPE = LAST_TYPE,
Ben Murdochda12d292016-06-02 14:46:10 +0100760 // Boundary for testing JSReceivers that need special property lookup handling
761 LAST_SPECIAL_RECEIVER_TYPE = JS_SPECIAL_API_OBJECT_TYPE,
762 // Boundary case for testing JSReceivers that may have elements while having
763 // an empty fixed array as elements backing store. This is true for string
764 // wrappers.
765 LAST_CUSTOM_ELEMENTS_RECEIVER = JS_VALUE_TYPE,
Steve Blocka7e24c12009-10-30 11:49:00 +0000766};
767
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000768STATIC_ASSERT(JS_OBJECT_TYPE == Internals::kJSObjectType);
Ben Murdochc5610432016-08-08 18:44:38 +0100769STATIC_ASSERT(JS_API_OBJECT_TYPE == Internals::kJSApiObjectType);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000770STATIC_ASSERT(FIRST_NONSTRING_TYPE == Internals::kFirstNonstringType);
771STATIC_ASSERT(ODDBALL_TYPE == Internals::kOddballType);
772STATIC_ASSERT(FOREIGN_TYPE == Internals::kForeignType);
773
774
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000775std::ostream& operator<<(std::ostream& os, InstanceType instance_type);
776
777
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000778#define FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(V) \
779 V(FAST_ELEMENTS_SUB_TYPE) \
780 V(DICTIONARY_ELEMENTS_SUB_TYPE) \
781 V(FAST_PROPERTIES_SUB_TYPE) \
782 V(DICTIONARY_PROPERTIES_SUB_TYPE) \
783 V(MAP_CODE_CACHE_SUB_TYPE) \
784 V(SCOPE_INFO_SUB_TYPE) \
785 V(STRING_TABLE_SUB_TYPE) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000786 V(DESCRIPTOR_ARRAY_SUB_TYPE)
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000787
788enum FixedArraySubInstanceType {
789#define DEFINE_FIXED_ARRAY_SUB_INSTANCE_TYPE(name) name,
790 FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(DEFINE_FIXED_ARRAY_SUB_INSTANCE_TYPE)
791#undef DEFINE_FIXED_ARRAY_SUB_INSTANCE_TYPE
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000792 LAST_FIXED_ARRAY_SUB_TYPE = DESCRIPTOR_ARRAY_SUB_TYPE
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000793};
Kristian Monsen9dcf7e22010-06-28 14:14:28 +0100794
795
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000796// TODO(bmeurer): Remove this in favor of the ComparisonResult below.
Steve Blocka7e24c12009-10-30 11:49:00 +0000797enum CompareResult {
798 LESS = -1,
799 EQUAL = 0,
800 GREATER = 1,
801
802 NOT_EQUAL = GREATER
803};
804
805
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000806// Result of an abstract relational comparison of x and y, implemented according
807// to ES6 section 7.2.11 Abstract Relational Comparison.
808enum class ComparisonResult {
809 kLessThan, // x < y
810 kEqual, // x = y
811 kGreaterThan, // x > y
812 kUndefined // at least one of x or y was undefined or NaN
813};
814
815
816#define DECL_BOOLEAN_ACCESSORS(name) \
817 inline bool name() const; \
818 inline void set_##name(bool value);
819
820#define DECL_INT_ACCESSORS(name) \
821 inline int name() const; \
822 inline void set_##name(int value);
Steve Blocka7e24c12009-10-30 11:49:00 +0000823
824
825#define DECL_ACCESSORS(name, type) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000826 inline type* name() const; \
Steve Blocka7e24c12009-10-30 11:49:00 +0000827 inline void set_##name(type* value, \
828 WriteBarrierMode mode = UPDATE_WRITE_BARRIER); \
829
830
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000831#define DECLARE_CAST(type) \
832 INLINE(static type* cast(Object* object)); \
833 INLINE(static const type* cast(const Object* object));
834
835
836class AccessorPair;
837class AllocationSite;
838class AllocationSiteCreationContext;
839class AllocationSiteUsageContext;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000840class Cell;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400841class ConsString;
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000842class ElementsAccessor;
843class FixedArrayBase;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000844class FunctionLiteral;
845class JSGlobalObject;
846class KeyAccumulator;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400847class LayoutDescriptor;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000848class LiteralsArray;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000849class LookupIterator;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100850class FieldType;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000851class ObjectHashTable;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400852class ObjectVisitor;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000853class PropertyCell;
854class PropertyDescriptor;
855class SafepointEntry;
856class SharedFunctionInfo;
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000857class StringStream;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000858class TypeFeedbackInfo;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000859class TypeFeedbackVector;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400860class WeakCell;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000861class TransitionArray;
862
Steve Blocka7e24c12009-10-30 11:49:00 +0000863
864// A template-ized version of the IsXXX functions.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000865template <class C> inline bool Is(Object* obj);
Steve Blocka7e24c12009-10-30 11:49:00 +0000866
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000867#ifdef VERIFY_HEAP
868#define DECLARE_VERIFIER(Name) void Name##Verify();
869#else
870#define DECLARE_VERIFIER(Name)
871#endif
Steve Block053d10c2011-06-13 19:13:29 +0100872
Ben Murdochb0fe1622011-05-05 13:52:32 +0100873#ifdef OBJECT_PRINT
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400874#define DECLARE_PRINTER(Name) void Name##Print(std::ostream& os); // NOLINT
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000875#else
876#define DECLARE_PRINTER(Name)
Ben Murdochb0fe1622011-05-05 13:52:32 +0100877#endif
Steve Blocka7e24c12009-10-30 11:49:00 +0000878
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000879#define OBJECT_TYPE_LIST(V) \
880 V(Smi) \
Ben Murdoch097c5b22016-05-18 11:27:45 +0100881 V(LayoutDescriptor) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000882 V(HeapObject) \
Ben Murdoch097c5b22016-05-18 11:27:45 +0100883 V(Primitive) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000884 V(Number)
Ben Murdochb8e0da22011-05-16 14:20:40 +0100885
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000886#define HEAP_OBJECT_TYPE_LIST(V) \
887 V(HeapNumber) \
888 V(MutableHeapNumber) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000889 V(Simd128Value) \
890 V(Float32x4) \
891 V(Int32x4) \
892 V(Uint32x4) \
893 V(Bool32x4) \
894 V(Int16x8) \
895 V(Uint16x8) \
896 V(Bool16x8) \
897 V(Int8x16) \
898 V(Uint8x16) \
899 V(Bool8x16) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000900 V(Name) \
901 V(UniqueName) \
902 V(String) \
903 V(SeqString) \
904 V(ExternalString) \
905 V(ConsString) \
906 V(SlicedString) \
907 V(ExternalTwoByteString) \
908 V(ExternalOneByteString) \
909 V(SeqTwoByteString) \
910 V(SeqOneByteString) \
911 V(InternalizedString) \
912 V(Symbol) \
913 \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000914 V(FixedTypedArrayBase) \
915 V(FixedUint8Array) \
916 V(FixedInt8Array) \
917 V(FixedUint16Array) \
918 V(FixedInt16Array) \
919 V(FixedUint32Array) \
920 V(FixedInt32Array) \
921 V(FixedFloat32Array) \
922 V(FixedFloat64Array) \
923 V(FixedUint8ClampedArray) \
924 V(ByteArray) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000925 V(BytecodeArray) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000926 V(FreeSpace) \
927 V(JSReceiver) \
928 V(JSObject) \
929 V(JSContextExtensionObject) \
930 V(JSGeneratorObject) \
931 V(JSModule) \
932 V(Map) \
933 V(DescriptorArray) \
934 V(TransitionArray) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000935 V(LiteralsArray) \
936 V(TypeFeedbackMetadata) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000937 V(TypeFeedbackVector) \
938 V(DeoptimizationInputData) \
939 V(DeoptimizationOutputData) \
940 V(DependentCode) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000941 V(HandlerTable) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000942 V(FixedArray) \
943 V(FixedDoubleArray) \
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400944 V(WeakFixedArray) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000945 V(ArrayList) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000946 V(Context) \
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400947 V(ScriptContextTable) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000948 V(NativeContext) \
949 V(ScopeInfo) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000950 V(JSBoundFunction) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000951 V(JSFunction) \
952 V(Code) \
Ben Murdoch097c5b22016-05-18 11:27:45 +0100953 V(AbstractCode) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000954 V(Oddball) \
955 V(SharedFunctionInfo) \
956 V(JSValue) \
957 V(JSDate) \
958 V(JSMessageObject) \
959 V(StringWrapper) \
960 V(Foreign) \
961 V(Boolean) \
962 V(JSArray) \
963 V(JSArrayBuffer) \
964 V(JSArrayBufferView) \
965 V(JSTypedArray) \
966 V(JSDataView) \
967 V(JSProxy) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000968 V(JSSet) \
969 V(JSMap) \
970 V(JSSetIterator) \
971 V(JSMapIterator) \
972 V(JSWeakCollection) \
973 V(JSWeakMap) \
974 V(JSWeakSet) \
975 V(JSRegExp) \
976 V(HashTable) \
977 V(Dictionary) \
978 V(StringTable) \
Ben Murdochda12d292016-06-02 14:46:10 +0100979 V(StringSet) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000980 V(NormalizedMapCache) \
981 V(CompilationCacheTable) \
982 V(CodeCacheHashTable) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000983 V(MapCache) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000984 V(JSGlobalObject) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000985 V(JSGlobalProxy) \
Ben Murdochda12d292016-06-02 14:46:10 +0100986 V(Undetectable) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000987 V(AccessCheckNeeded) \
Ben Murdoch097c5b22016-05-18 11:27:45 +0100988 V(Callable) \
989 V(Function) \
990 V(Constructor) \
991 V(TemplateInfo) \
992 V(Filler) \
993 V(FixedArrayBase) \
994 V(External) \
995 V(Struct) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000996 V(Cell) \
997 V(PropertyCell) \
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400998 V(WeakCell) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000999 V(ObjectHashTable) \
1000 V(WeakHashTable) \
1001 V(OrderedHashTable)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001002
Ben Murdoch097c5b22016-05-18 11:27:45 +01001003#define ODDBALL_LIST(V) \
1004 V(Undefined) \
1005 V(Null) \
1006 V(TheHole) \
1007 V(Exception) \
1008 V(Uninitialized) \
1009 V(True) \
1010 V(False) \
Ben Murdochda12d292016-06-02 14:46:10 +01001011 V(ArgumentsMarker) \
Ben Murdochc5610432016-08-08 18:44:38 +01001012 V(OptimizedOut) \
1013 V(StaleRegister)
Ben Murdoch097c5b22016-05-18 11:27:45 +01001014
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001015// The element types selection for CreateListFromArrayLike.
1016enum class ElementTypes { kAll, kStringAndSymbol };
1017
Steve Blocka7e24c12009-10-30 11:49:00 +00001018// Object is the abstract superclass for all classes in the
1019// object hierarchy.
1020// Object does not use any virtual functions to avoid the
1021// allocation of the C++ vtable.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001022// Since both Smi and HeapObject are subclasses of Object no
Steve Blocka7e24c12009-10-30 11:49:00 +00001023// data members can be present in Object.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001024class Object {
Steve Blocka7e24c12009-10-30 11:49:00 +00001025 public:
1026 // Type testing.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001027 bool IsObject() const { return true; }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001028
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001029#define IS_TYPE_FUNCTION_DECL(type_) INLINE(bool Is##type_() const);
Ben Murdochb8e0da22011-05-16 14:20:40 +01001030 OBJECT_TYPE_LIST(IS_TYPE_FUNCTION_DECL)
1031 HEAP_OBJECT_TYPE_LIST(IS_TYPE_FUNCTION_DECL)
Ben Murdoch097c5b22016-05-18 11:27:45 +01001032 ODDBALL_LIST(IS_TYPE_FUNCTION_DECL)
Ben Murdochb8e0da22011-05-16 14:20:40 +01001033#undef IS_TYPE_FUNCTION_DECL
Steve Blocka7e24c12009-10-30 11:49:00 +00001034
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001035 // A non-keyed store is of the form a.x = foo or a["x"] = foo whereas
1036 // a keyed store is of the form a[expression] = foo.
1037 enum StoreFromKeyed {
1038 MAY_BE_STORE_FROM_KEYED,
1039 CERTAINLY_NOT_STORE_FROM_KEYED
1040 };
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001041
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001042 enum ShouldThrow { THROW_ON_ERROR, DONT_THROW };
1043
1044#define RETURN_FAILURE(isolate, should_throw, call) \
1045 do { \
1046 if ((should_throw) == DONT_THROW) { \
1047 return Just(false); \
1048 } else { \
1049 isolate->Throw(*isolate->factory()->call); \
1050 return Nothing<bool>(); \
1051 } \
1052 } while (false)
1053
1054#define MAYBE_RETURN(call, value) \
1055 do { \
1056 if ((call).IsNothing()) return value; \
1057 } while (false)
1058
1059#define MAYBE_RETURN_NULL(call) MAYBE_RETURN(call, MaybeHandle<Object>())
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001060
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001061#define DECLARE_STRUCT_PREDICATE(NAME, Name, name) \
1062 INLINE(bool Is##Name() const);
Steve Blocka7e24c12009-10-30 11:49:00 +00001063 STRUCT_LIST(DECLARE_STRUCT_PREDICATE)
1064#undef DECLARE_STRUCT_PREDICATE
1065
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001066 // ES6, section 7.2.2 IsArray. NOT to be confused with %_IsArray.
1067 MUST_USE_RESULT static Maybe<bool> IsArray(Handle<Object> object);
1068
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001069 INLINE(bool IsNameDictionary() const);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001070 INLINE(bool IsGlobalDictionary() const);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001071 INLINE(bool IsSeededNumberDictionary() const);
1072 INLINE(bool IsUnseededNumberDictionary() const);
1073 INLINE(bool IsOrderedHashSet() const);
1074 INLINE(bool IsOrderedHashMap() const);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001075 static bool IsPromise(Handle<Object> object);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001076
Steve Blocka7e24c12009-10-30 11:49:00 +00001077 // Extract the number.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001078 inline double Number() const;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001079 INLINE(bool IsNaN() const);
1080 INLINE(bool IsMinusZero() const);
1081 bool ToInt32(int32_t* value);
Ben Murdochda12d292016-06-02 14:46:10 +01001082 inline bool ToUint32(uint32_t* value);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001083
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001084 inline Representation OptimalRepresentation();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001085
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001086 inline ElementsKind OptimalElementsKind();
1087
1088 inline bool FitsRepresentation(Representation representation);
1089
1090 // Checks whether two valid primitive encodings of a property name resolve to
1091 // the same logical property. E.g., the smi 1, the string "1" and the double
1092 // 1 all refer to the same property, so this helper will return true.
1093 inline bool KeyEquals(Object* other);
1094
1095 inline bool FilterKey(PropertyFilter filter);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001096
Ben Murdoch097c5b22016-05-18 11:27:45 +01001097 Handle<FieldType> OptimalType(Isolate* isolate,
1098 Representation representation);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001099
1100 inline static Handle<Object> NewStorageFor(Isolate* isolate,
1101 Handle<Object> object,
1102 Representation representation);
1103
1104 inline static Handle<Object> WrapForRead(Isolate* isolate,
1105 Handle<Object> object,
1106 Representation representation);
Steve Blocka7e24c12009-10-30 11:49:00 +00001107
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001108 // Returns true if the object is of the correct type to be used as a
1109 // implementation of a JSObject's elements.
1110 inline bool HasValidElements();
1111
Steve Blocka7e24c12009-10-30 11:49:00 +00001112 inline bool HasSpecificClassOf(String* name);
1113
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001114 bool BooleanValue(); // ECMA-262 9.2.
Steve Blocka7e24c12009-10-30 11:49:00 +00001115
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001116 // ES6 section 7.2.11 Abstract Relational Comparison
Ben Murdoch097c5b22016-05-18 11:27:45 +01001117 MUST_USE_RESULT static Maybe<ComparisonResult> Compare(Handle<Object> x,
1118 Handle<Object> y);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001119
1120 // ES6 section 7.2.12 Abstract Equality Comparison
1121 MUST_USE_RESULT static Maybe<bool> Equals(Handle<Object> x, Handle<Object> y);
1122
1123 // ES6 section 7.2.13 Strict Equality Comparison
1124 bool StrictEquals(Object* that);
1125
Steve Blocka7e24c12009-10-30 11:49:00 +00001126 // Convert to a JSObject if needed.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001127 // native_context is used when creating wrapper object.
Ben Murdoch097c5b22016-05-18 11:27:45 +01001128 MUST_USE_RESULT static inline MaybeHandle<JSReceiver> ToObject(
1129 Isolate* isolate, Handle<Object> object);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001130 MUST_USE_RESULT static MaybeHandle<JSReceiver> ToObject(
1131 Isolate* isolate, Handle<Object> object, Handle<Context> context);
Steve Blocka7e24c12009-10-30 11:49:00 +00001132
Ben Murdochda12d292016-06-02 14:46:10 +01001133 // ES6 section 9.2.1.2, OrdinaryCallBindThis for sloppy callee.
1134 MUST_USE_RESULT static MaybeHandle<JSReceiver> ConvertReceiver(
1135 Isolate* isolate, Handle<Object> object);
1136
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001137 // ES6 section 7.1.14 ToPropertyKey
Ben Murdochda12d292016-06-02 14:46:10 +01001138 MUST_USE_RESULT static inline MaybeHandle<Name> ToName(Isolate* isolate,
1139 Handle<Object> input);
Steve Blocka7e24c12009-10-30 11:49:00 +00001140
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001141 // ES6 section 7.1.1 ToPrimitive
1142 MUST_USE_RESULT static inline MaybeHandle<Object> ToPrimitive(
1143 Handle<Object> input, ToPrimitiveHint hint = ToPrimitiveHint::kDefault);
Steve Blocka7e24c12009-10-30 11:49:00 +00001144
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001145 // ES6 section 7.1.3 ToNumber
1146 MUST_USE_RESULT static MaybeHandle<Object> ToNumber(Handle<Object> input);
1147
1148 // ES6 section 7.1.4 ToInteger
1149 MUST_USE_RESULT static MaybeHandle<Object> ToInteger(Isolate* isolate,
1150 Handle<Object> input);
1151
1152 // ES6 section 7.1.5 ToInt32
1153 MUST_USE_RESULT static MaybeHandle<Object> ToInt32(Isolate* isolate,
1154 Handle<Object> input);
1155
1156 // ES6 section 7.1.6 ToUint32
1157 MUST_USE_RESULT static MaybeHandle<Object> ToUint32(Isolate* isolate,
1158 Handle<Object> input);
1159
1160 // ES6 section 7.1.12 ToString
1161 MUST_USE_RESULT static MaybeHandle<String> ToString(Isolate* isolate,
1162 Handle<Object> input);
1163
Ben Murdochc5610432016-08-08 18:44:38 +01001164 // ES6 section 7.1.14 ToPropertyKey
1165 MUST_USE_RESULT static MaybeHandle<Object> ToPropertyKey(
1166 Isolate* isolate, Handle<Object> value);
1167
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001168 // ES6 section 7.1.15 ToLength
1169 MUST_USE_RESULT static MaybeHandle<Object> ToLength(Isolate* isolate,
1170 Handle<Object> input);
1171
1172 // ES6 section 7.3.9 GetMethod
1173 MUST_USE_RESULT static MaybeHandle<Object> GetMethod(
1174 Handle<JSReceiver> receiver, Handle<Name> name);
1175
1176 // ES6 section 7.3.17 CreateListFromArrayLike
1177 MUST_USE_RESULT static MaybeHandle<FixedArray> CreateListFromArrayLike(
1178 Isolate* isolate, Handle<Object> object, ElementTypes element_types);
1179
1180 // Check whether |object| is an instance of Error or NativeError.
1181 static bool IsErrorObject(Isolate* isolate, Handle<Object> object);
1182
1183 // ES6 section 12.5.6 The typeof Operator
1184 static Handle<String> TypeOf(Isolate* isolate, Handle<Object> object);
1185
1186 // ES6 section 12.6 Multiplicative Operators
Ben Murdoch097c5b22016-05-18 11:27:45 +01001187 MUST_USE_RESULT static MaybeHandle<Object> Multiply(Isolate* isolate,
1188 Handle<Object> lhs,
1189 Handle<Object> rhs);
1190 MUST_USE_RESULT static MaybeHandle<Object> Divide(Isolate* isolate,
1191 Handle<Object> lhs,
1192 Handle<Object> rhs);
1193 MUST_USE_RESULT static MaybeHandle<Object> Modulus(Isolate* isolate,
1194 Handle<Object> lhs,
1195 Handle<Object> rhs);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001196
1197 // ES6 section 12.7 Additive Operators
Ben Murdoch097c5b22016-05-18 11:27:45 +01001198 MUST_USE_RESULT static MaybeHandle<Object> Add(Isolate* isolate,
1199 Handle<Object> lhs,
1200 Handle<Object> rhs);
1201 MUST_USE_RESULT static MaybeHandle<Object> Subtract(Isolate* isolate,
1202 Handle<Object> lhs,
1203 Handle<Object> rhs);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001204
1205 // ES6 section 12.8 Bitwise Shift Operators
Ben Murdoch097c5b22016-05-18 11:27:45 +01001206 MUST_USE_RESULT static MaybeHandle<Object> ShiftLeft(Isolate* isolate,
1207 Handle<Object> lhs,
1208 Handle<Object> rhs);
1209 MUST_USE_RESULT static MaybeHandle<Object> ShiftRight(Isolate* isolate,
1210 Handle<Object> lhs,
1211 Handle<Object> rhs);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001212 MUST_USE_RESULT static MaybeHandle<Object> ShiftRightLogical(
Ben Murdoch097c5b22016-05-18 11:27:45 +01001213 Isolate* isolate, Handle<Object> lhs, Handle<Object> rhs);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001214
1215 // ES6 section 12.9 Relational Operators
Ben Murdoch097c5b22016-05-18 11:27:45 +01001216 MUST_USE_RESULT static inline Maybe<bool> GreaterThan(Handle<Object> x,
1217 Handle<Object> y);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001218 MUST_USE_RESULT static inline Maybe<bool> GreaterThanOrEqual(
Ben Murdoch097c5b22016-05-18 11:27:45 +01001219 Handle<Object> x, Handle<Object> y);
1220 MUST_USE_RESULT static inline Maybe<bool> LessThan(Handle<Object> x,
1221 Handle<Object> y);
1222 MUST_USE_RESULT static inline Maybe<bool> LessThanOrEqual(Handle<Object> x,
1223 Handle<Object> y);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001224
1225 // ES6 section 12.11 Binary Bitwise Operators
Ben Murdoch097c5b22016-05-18 11:27:45 +01001226 MUST_USE_RESULT static MaybeHandle<Object> BitwiseAnd(Isolate* isolate,
1227 Handle<Object> lhs,
1228 Handle<Object> rhs);
1229 MUST_USE_RESULT static MaybeHandle<Object> BitwiseOr(Isolate* isolate,
1230 Handle<Object> lhs,
1231 Handle<Object> rhs);
1232 MUST_USE_RESULT static MaybeHandle<Object> BitwiseXor(Isolate* isolate,
1233 Handle<Object> lhs,
1234 Handle<Object> rhs);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001235
Ben Murdochc5610432016-08-08 18:44:38 +01001236 // ES6 section 7.3.19 OrdinaryHasInstance (C, O).
1237 MUST_USE_RESULT static MaybeHandle<Object> OrdinaryHasInstance(
1238 Isolate* isolate, Handle<Object> callable, Handle<Object> object);
1239
1240 // ES6 section 12.10.4 Runtime Semantics: InstanceofOperator(O, C)
1241 MUST_USE_RESULT static MaybeHandle<Object> InstanceOf(
1242 Isolate* isolate, Handle<Object> object, Handle<Object> callable);
1243
Ben Murdoch097c5b22016-05-18 11:27:45 +01001244 MUST_USE_RESULT static MaybeHandle<Object> GetProperty(LookupIterator* it);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001245
1246 // ES6 [[Set]] (when passed DONT_THROW)
1247 // Invariants for this and related functions (unless stated otherwise):
1248 // 1) When the result is Nothing, an exception is pending.
1249 // 2) When passed THROW_ON_ERROR, the result is never Just(false).
1250 // In some cases, an exception is thrown regardless of the ShouldThrow
1251 // argument. These cases are either in accordance with the spec or not
1252 // covered by it (eg., concerning API callbacks).
1253 MUST_USE_RESULT static Maybe<bool> SetProperty(LookupIterator* it,
1254 Handle<Object> value,
1255 LanguageMode language_mode,
1256 StoreFromKeyed store_mode);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001257 MUST_USE_RESULT static MaybeHandle<Object> SetProperty(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001258 Handle<Object> object, Handle<Name> name, Handle<Object> value,
1259 LanguageMode language_mode,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001260 StoreFromKeyed store_mode = MAY_BE_STORE_FROM_KEYED);
Ben Murdochda12d292016-06-02 14:46:10 +01001261 MUST_USE_RESULT static inline MaybeHandle<Object> SetPropertyOrElement(
1262 Handle<Object> object, Handle<Name> name, Handle<Object> value,
1263 LanguageMode language_mode,
1264 StoreFromKeyed store_mode = MAY_BE_STORE_FROM_KEYED);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001265
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001266 MUST_USE_RESULT static Maybe<bool> SetSuperProperty(
1267 LookupIterator* it, Handle<Object> value, LanguageMode language_mode,
1268 StoreFromKeyed store_mode);
1269
1270 MUST_USE_RESULT static MaybeHandle<Object> ReadAbsentProperty(
Ben Murdoch097c5b22016-05-18 11:27:45 +01001271 LookupIterator* it);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001272 MUST_USE_RESULT static MaybeHandle<Object> ReadAbsentProperty(
Ben Murdoch097c5b22016-05-18 11:27:45 +01001273 Isolate* isolate, Handle<Object> receiver, Handle<Object> name);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001274 MUST_USE_RESULT static Maybe<bool> CannotCreateProperty(
1275 Isolate* isolate, Handle<Object> receiver, Handle<Object> name,
1276 Handle<Object> value, ShouldThrow should_throw);
1277 MUST_USE_RESULT static Maybe<bool> WriteToReadOnlyProperty(
1278 LookupIterator* it, Handle<Object> value, ShouldThrow should_throw);
1279 MUST_USE_RESULT static Maybe<bool> WriteToReadOnlyProperty(
1280 Isolate* isolate, Handle<Object> receiver, Handle<Object> name,
1281 Handle<Object> value, ShouldThrow should_throw);
1282 MUST_USE_RESULT static Maybe<bool> RedefineIncompatibleProperty(
1283 Isolate* isolate, Handle<Object> name, Handle<Object> value,
1284 ShouldThrow should_throw);
1285 MUST_USE_RESULT static Maybe<bool> SetDataProperty(LookupIterator* it,
1286 Handle<Object> value);
1287 MUST_USE_RESULT static Maybe<bool> AddDataProperty(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001288 LookupIterator* it, Handle<Object> value, PropertyAttributes attributes,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001289 ShouldThrow should_throw, StoreFromKeyed store_mode);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001290 MUST_USE_RESULT static inline MaybeHandle<Object> GetPropertyOrElement(
Ben Murdoch097c5b22016-05-18 11:27:45 +01001291 Handle<Object> object, Handle<Name> name);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001292 MUST_USE_RESULT static inline MaybeHandle<Object> GetPropertyOrElement(
Ben Murdoch097c5b22016-05-18 11:27:45 +01001293 Handle<Object> receiver, Handle<Name> name, Handle<JSReceiver> holder);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001294 MUST_USE_RESULT static inline MaybeHandle<Object> GetProperty(
Ben Murdoch097c5b22016-05-18 11:27:45 +01001295 Handle<Object> object, Handle<Name> name);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001296
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001297 MUST_USE_RESULT static MaybeHandle<Object> GetPropertyWithAccessor(
Ben Murdoch097c5b22016-05-18 11:27:45 +01001298 LookupIterator* it);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001299 MUST_USE_RESULT static Maybe<bool> SetPropertyWithAccessor(
1300 LookupIterator* it, Handle<Object> value, ShouldThrow should_throw);
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001301
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001302 MUST_USE_RESULT static MaybeHandle<Object> GetPropertyWithDefinedGetter(
1303 Handle<Object> receiver,
1304 Handle<JSReceiver> getter);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001305 MUST_USE_RESULT static Maybe<bool> SetPropertyWithDefinedSetter(
1306 Handle<Object> receiver, Handle<JSReceiver> setter, Handle<Object> value,
1307 ShouldThrow should_throw);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001308
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001309 MUST_USE_RESULT static inline MaybeHandle<Object> GetElement(
Ben Murdoch097c5b22016-05-18 11:27:45 +01001310 Isolate* isolate, Handle<Object> object, uint32_t index);
Steve Blocka7e24c12009-10-30 11:49:00 +00001311
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001312 MUST_USE_RESULT static inline MaybeHandle<Object> SetElement(
1313 Isolate* isolate, Handle<Object> object, uint32_t index,
1314 Handle<Object> value, LanguageMode language_mode);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001315
1316 // Returns the permanent hash code associated with this object. May return
1317 // undefined if not yet created.
1318 Object* GetHash();
Steve Blocka7e24c12009-10-30 11:49:00 +00001319
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001320 // Returns undefined for JSObjects, but returns the hash code for simple
1321 // objects. This avoids a double lookup in the cases where we know we will
1322 // add the hash to the JSObject if it does not already exist.
1323 Object* GetSimpleHash();
1324
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001325 // Returns the permanent hash code associated with this object depending on
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001326 // the actual object type. May create and store a hash code if needed and none
1327 // exists.
1328 static Handle<Smi> GetOrCreateHash(Isolate* isolate, Handle<Object> object);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001329
1330 // Checks whether this object has the same value as the given one. This
1331 // function is implemented according to ES5, section 9.12 and can be used
1332 // to implement the Harmony "egal" function.
1333 bool SameValue(Object* other);
1334
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001335 // Checks whether this object has the same value as the given one.
1336 // +0 and -0 are treated equal. Everything else is the same as SameValue.
1337 // This function is implemented according to ES6, section 7.2.4 and is used
1338 // by ES6 Map and Set.
1339 bool SameValueZero(Object* other);
1340
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001341 // ES6 section 9.4.2.3 ArraySpeciesCreate (part of it)
1342 MUST_USE_RESULT static MaybeHandle<Object> ArraySpeciesConstructor(
1343 Isolate* isolate, Handle<Object> original_array);
1344
1345 // Tries to convert an object to an array length. Returns true and sets the
1346 // output parameter if it succeeds.
1347 inline bool ToArrayLength(uint32_t* index);
1348
1349 // Tries to convert an object to an array index. Returns true and sets the
1350 // output parameter if it succeeds. Equivalent to ToArrayLength, but does not
1351 // allow kMaxUInt32.
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01001352 inline bool ToArrayIndex(uint32_t* index);
1353
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001354 DECLARE_VERIFIER(Object)
1355#ifdef VERIFY_HEAP
Steve Blocka7e24c12009-10-30 11:49:00 +00001356 // Verify a pointer is a valid object pointer.
1357 static void VerifyPointer(Object* p);
1358#endif
1359
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001360 inline void VerifyApiCallResultType();
1361
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001362 // ES6 19.1.3.6 Object.prototype.toString
1363 MUST_USE_RESULT static MaybeHandle<String> ObjectProtoToString(
1364 Isolate* isolate, Handle<Object> object);
1365
Steve Blocka7e24c12009-10-30 11:49:00 +00001366 // Prints this object without details.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001367 void ShortPrint(FILE* out = stdout);
Steve Blocka7e24c12009-10-30 11:49:00 +00001368
1369 // Prints this object without details to a message accumulator.
1370 void ShortPrint(StringStream* accumulator);
1371
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001372 void ShortPrint(std::ostream& os); // NOLINT
1373
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001374 DECLARE_CAST(Object)
Steve Blocka7e24c12009-10-30 11:49:00 +00001375
1376 // Layout description.
1377 static const int kHeaderSize = 0; // Object does not take up any space.
1378
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001379#ifdef OBJECT_PRINT
1380 // For our gdb macros, we should perhaps change these in the future.
1381 void Print();
1382
1383 // Prints this object with details.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001384 void Print(std::ostream& os); // NOLINT
1385#else
1386 void Print() { ShortPrint(); }
1387 void Print(std::ostream& os) { ShortPrint(os); } // NOLINT
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001388#endif
1389
Steve Blocka7e24c12009-10-30 11:49:00 +00001390 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001391 friend class LookupIterator;
Ben Murdoch097c5b22016-05-18 11:27:45 +01001392 friend class StringStream;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001393
1394 // Return the map of the root of object's prototype chain.
1395 Map* GetRootMap(Isolate* isolate);
1396
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001397 // Helper for SetProperty and SetSuperProperty.
1398 // Return value is only meaningful if [found] is set to true on return.
1399 MUST_USE_RESULT static Maybe<bool> SetPropertyInternal(
1400 LookupIterator* it, Handle<Object> value, LanguageMode language_mode,
1401 StoreFromKeyed store_mode, bool* found);
1402
Ben Murdochda12d292016-06-02 14:46:10 +01001403 MUST_USE_RESULT static MaybeHandle<Name> ConvertToName(Isolate* isolate,
1404 Handle<Object> input);
1405
Steve Blocka7e24c12009-10-30 11:49:00 +00001406 DISALLOW_IMPLICIT_CONSTRUCTORS(Object);
1407};
1408
1409
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001410// In objects.h to be usable without objects-inl.h inclusion.
1411bool Object::IsSmi() const { return HAS_SMI_TAG(this); }
1412bool Object::IsHeapObject() const { return Internals::HasHeapObjectTag(this); }
1413
1414
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001415struct Brief {
1416 explicit Brief(const Object* const v) : value(v) {}
1417 const Object* value;
1418};
1419
1420
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001421std::ostream& operator<<(std::ostream& os, const Brief& v);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001422
1423
Steve Blocka7e24c12009-10-30 11:49:00 +00001424// Smi represents integer Numbers that can be stored in 31 bits.
1425// Smis are immediate which means they are NOT allocated in the heap.
Steve Blocka7e24c12009-10-30 11:49:00 +00001426// The this pointer has the following format: [31 bit signed int] 0
Steve Block3ce2e202009-11-05 08:53:23 +00001427// For long smis it has the following format:
1428// [32 bit signed int] [31 bits zero padding] 0
1429// Smi stands for small integer.
Steve Blocka7e24c12009-10-30 11:49:00 +00001430class Smi: public Object {
1431 public:
1432 // Returns the integer value.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001433 inline int value() const { return Internals::SmiValue(this); }
Steve Blocka7e24c12009-10-30 11:49:00 +00001434
1435 // Convert a value to a Smi object.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001436 static inline Smi* FromInt(int value) {
1437 DCHECK(Smi::IsValid(value));
1438 return reinterpret_cast<Smi*>(Internals::IntToSmi(value));
1439 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001440
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001441 static inline Smi* FromIntptr(intptr_t value) {
1442 DCHECK(Smi::IsValid(value));
1443 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
1444 return reinterpret_cast<Smi*>((value << smi_shift_bits) | kSmiTag);
1445 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001446
1447 // Returns whether value can be represented in a Smi.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001448 static inline bool IsValid(intptr_t value) {
1449 bool result = Internals::IsValidSmi(value);
1450 DCHECK_EQ(result, value >= kMinValue && value <= kMaxValue);
1451 return result;
1452 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001453
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001454 DECLARE_CAST(Smi)
Steve Blocka7e24c12009-10-30 11:49:00 +00001455
1456 // Dispatched behavior.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001457 void SmiPrint(std::ostream& os) const; // NOLINT
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001458 DECLARE_VERIFIER(Smi)
Steve Blocka7e24c12009-10-30 11:49:00 +00001459
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001460 static const int kMinValue =
1461 (static_cast<unsigned int>(-1)) << (kSmiValueSize - 1);
Steve Block3ce2e202009-11-05 08:53:23 +00001462 static const int kMaxValue = -(kMinValue + 1);
Steve Blocka7e24c12009-10-30 11:49:00 +00001463
1464 private:
1465 DISALLOW_IMPLICIT_CONSTRUCTORS(Smi);
1466};
1467
1468
Steve Blocka7e24c12009-10-30 11:49:00 +00001469// Heap objects typically have a map pointer in their first word. However,
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001470// during GC other data (e.g. mark bits, forwarding addresses) is sometimes
Steve Blocka7e24c12009-10-30 11:49:00 +00001471// encoded in the first word. The class MapWord is an abstraction of the
1472// value in a heap object's first word.
1473class MapWord BASE_EMBEDDED {
1474 public:
1475 // Normal state: the map word contains a map pointer.
1476
1477 // Create a map word from a map pointer.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001478 static inline MapWord FromMap(const Map* map);
Steve Blocka7e24c12009-10-30 11:49:00 +00001479
1480 // View this map word as a map pointer.
1481 inline Map* ToMap();
1482
1483
1484 // Scavenge collection: the map word of live objects in the from space
1485 // contains a forwarding address (a heap object pointer in the to space).
1486
1487 // True if this map word is a forwarding address for a scavenge
1488 // collection. Only valid during a scavenge collection (specifically,
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001489 // when all map words are heap object pointers, i.e. not during a full GC).
Ben Murdochc5610432016-08-08 18:44:38 +01001490 inline bool IsForwardingAddress() const;
Steve Blocka7e24c12009-10-30 11:49:00 +00001491
1492 // Create a map word from a forwarding address.
1493 static inline MapWord FromForwardingAddress(HeapObject* object);
1494
1495 // View this map word as a forwarding address.
1496 inline HeapObject* ToForwardingAddress();
1497
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001498 static inline MapWord FromRawValue(uintptr_t value) {
1499 return MapWord(value);
1500 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001501
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001502 inline uintptr_t ToRawValue() {
1503 return value_;
1504 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001505
1506 private:
1507 // HeapObject calls the private constructor and directly reads the value.
1508 friend class HeapObject;
1509
1510 explicit MapWord(uintptr_t value) : value_(value) {}
1511
1512 uintptr_t value_;
1513};
1514
1515
1516// HeapObject is the superclass for all classes describing heap allocated
1517// objects.
1518class HeapObject: public Object {
1519 public:
1520 // [map]: Contains a map which contains the object's reflective
1521 // information.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001522 inline Map* map() const;
Steve Blocka7e24c12009-10-30 11:49:00 +00001523 inline void set_map(Map* value);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001524 // The no-write-barrier version. This is OK if the object is white and in
1525 // new space, or if the value is an immortal immutable object, like the maps
1526 // of primitive (non-JS) objects like strings, heap numbers etc.
1527 inline void set_map_no_write_barrier(Map* value);
Steve Blocka7e24c12009-10-30 11:49:00 +00001528
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001529 // Get the map using acquire load.
1530 inline Map* synchronized_map();
1531 inline MapWord synchronized_map_word() const;
1532
1533 // Set the map using release store
1534 inline void synchronized_set_map(Map* value);
1535 inline void synchronized_set_map_no_write_barrier(Map* value);
1536 inline void synchronized_set_map_word(MapWord map_word);
1537
Steve Blocka7e24c12009-10-30 11:49:00 +00001538 // During garbage collection, the map word of a heap object does not
1539 // necessarily contain a map pointer.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001540 inline MapWord map_word() const;
Steve Blocka7e24c12009-10-30 11:49:00 +00001541 inline void set_map_word(MapWord map_word);
1542
Steve Block44f0eee2011-05-26 01:26:41 +01001543 // The Heap the object was allocated in. Used also to access Isolate.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001544 inline Heap* GetHeap() const;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001545
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001546 // Convenience method to get current isolate.
1547 inline Isolate* GetIsolate() const;
Steve Block44f0eee2011-05-26 01:26:41 +01001548
Ben Murdoch097c5b22016-05-18 11:27:45 +01001549#define IS_TYPE_FUNCTION_DECL(type_) INLINE(bool Is##type_() const);
1550 HEAP_OBJECT_TYPE_LIST(IS_TYPE_FUNCTION_DECL)
1551 ODDBALL_LIST(IS_TYPE_FUNCTION_DECL)
1552#undef IS_TYPE_FUNCTION_DECL
1553#define DECLARE_STRUCT_PREDICATE(NAME, Name, name) \
1554 INLINE(bool Is##Name() const);
1555 STRUCT_LIST(DECLARE_STRUCT_PREDICATE)
1556#undef DECLARE_STRUCT_PREDICATE
1557
Steve Blocka7e24c12009-10-30 11:49:00 +00001558 // Converts an address to a HeapObject pointer.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001559 static inline HeapObject* FromAddress(Address address) {
1560 DCHECK_TAG_ALIGNED(address);
1561 return reinterpret_cast<HeapObject*>(address + kHeapObjectTag);
1562 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001563
1564 // Returns the address of this HeapObject.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001565 inline Address address() {
1566 return reinterpret_cast<Address>(this) - kHeapObjectTag;
1567 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001568
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001569 // Iterates over pointers contained in the object (including the Map).
1570 // If it's not performance critical iteration use the non-templatized
1571 // version.
Steve Blocka7e24c12009-10-30 11:49:00 +00001572 void Iterate(ObjectVisitor* v);
1573
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001574 template <typename ObjectVisitor>
1575 inline void IterateFast(ObjectVisitor* v);
1576
Steve Blocka7e24c12009-10-30 11:49:00 +00001577 // Iterates over all pointers contained in the object except the
1578 // first map pointer. The object type is given in the first
1579 // parameter. This function does not access the map pointer in the
1580 // object, and so is safe to call while the map pointer is modified.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001581 // If it's not performance critical iteration use the non-templatized
1582 // version.
1583 void IterateBody(ObjectVisitor* v);
Steve Blocka7e24c12009-10-30 11:49:00 +00001584 void IterateBody(InstanceType type, int object_size, ObjectVisitor* v);
1585
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001586 template <typename ObjectVisitor>
1587 inline void IterateBodyFast(ObjectVisitor* v);
1588
1589 template <typename ObjectVisitor>
1590 inline void IterateBodyFast(InstanceType type, int object_size,
1591 ObjectVisitor* v);
1592
1593 // Returns true if the object contains a tagged value at given offset.
1594 // It is used for invalid slots filtering. If the offset points outside
1595 // of the object or to the map word, the result is UNDEFINED (!!!).
1596 bool IsValidSlot(int offset);
1597
Steve Blocka7e24c12009-10-30 11:49:00 +00001598 // Returns the heap object's size in bytes
1599 inline int Size();
1600
1601 // Given a heap object's map pointer, returns the heap size in bytes
1602 // Useful when the map pointer field is used for other purposes.
1603 // GC internal.
1604 inline int SizeFromMap(Map* map);
1605
Steve Blocka7e24c12009-10-30 11:49:00 +00001606 // Returns the field at offset in obj, as a read/write Object* reference.
1607 // Does no checking, and is safe to use during GC, while maps are invalid.
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01001608 // Does not invoke write barrier, so should only be assigned to
Steve Blocka7e24c12009-10-30 11:49:00 +00001609 // during marking GC.
1610 static inline Object** RawField(HeapObject* obj, int offset);
1611
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001612 // Adds the |code| object related to |name| to the code cache of this map. If
1613 // this map is a dictionary map that is shared, the map copied and installed
1614 // onto the object.
1615 static void UpdateMapCodeCache(Handle<HeapObject> object,
1616 Handle<Name> name,
1617 Handle<Code> code);
1618
1619 DECLARE_CAST(HeapObject)
Steve Blocka7e24c12009-10-30 11:49:00 +00001620
Leon Clarke4515c472010-02-03 11:58:03 +00001621 // Return the write barrier mode for this. Callers of this function
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001622 // must be able to present a reference to an DisallowHeapAllocation
Leon Clarke4515c472010-02-03 11:58:03 +00001623 // object as a sign that they are not going to use this function
1624 // from code that allocates and thus invalidates the returned write
1625 // barrier mode.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001626 inline WriteBarrierMode GetWriteBarrierMode(
1627 const DisallowHeapAllocation& promise);
Steve Blocka7e24c12009-10-30 11:49:00 +00001628
1629 // Dispatched behavior.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001630 void HeapObjectShortPrint(std::ostream& os); // NOLINT
Ben Murdochb0fe1622011-05-05 13:52:32 +01001631#ifdef OBJECT_PRINT
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001632 void PrintHeader(std::ostream& os, const char* id); // NOLINT
Ben Murdoch85b71792012-04-11 18:30:58 +01001633#endif
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001634 DECLARE_PRINTER(HeapObject)
1635 DECLARE_VERIFIER(HeapObject)
1636#ifdef VERIFY_HEAP
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001637 inline void VerifyObjectField(int offset);
1638 inline void VerifySmiField(int offset);
1639
Steve Blocka7e24c12009-10-30 11:49:00 +00001640 // Verify a pointer is a valid HeapObject pointer that points to object
1641 // areas in the heap.
1642 static void VerifyHeapPointer(Object* p);
1643#endif
1644
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001645 inline AllocationAlignment RequiredAlignment();
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001646
Steve Blocka7e24c12009-10-30 11:49:00 +00001647 // Layout description.
1648 // First field in a heap object is map.
1649 static const int kMapOffset = Object::kHeaderSize;
1650 static const int kHeaderSize = kMapOffset + kPointerSize;
1651
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001652 STATIC_ASSERT(kMapOffset == Internals::kHeapObjectMapOffset);
Steve Blocka7e24c12009-10-30 11:49:00 +00001653
Steve Blocka7e24c12009-10-30 11:49:00 +00001654 private:
1655 DISALLOW_IMPLICIT_CONSTRUCTORS(HeapObject);
1656};
1657
1658
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001659template <int start_offset, int end_offset, int size>
1660class FixedBodyDescriptor;
Iain Merrick75681382010-08-19 15:07:18 +01001661
1662
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001663template <int start_offset>
1664class FlexibleBodyDescriptor;
Iain Merrick75681382010-08-19 15:07:18 +01001665
Iain Merrick75681382010-08-19 15:07:18 +01001666
Steve Blocka7e24c12009-10-30 11:49:00 +00001667// The HeapNumber class describes heap allocated numbers that cannot be
1668// represented in a Smi (small integer)
1669class HeapNumber: public HeapObject {
1670 public:
1671 // [value]: number value.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001672 inline double value() const;
Steve Blocka7e24c12009-10-30 11:49:00 +00001673 inline void set_value(double value);
1674
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001675 DECLARE_CAST(HeapNumber)
Steve Blocka7e24c12009-10-30 11:49:00 +00001676
1677 // Dispatched behavior.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001678 bool HeapNumberBooleanValue();
1679
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001680 void HeapNumberPrint(std::ostream& os); // NOLINT
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001681 DECLARE_VERIFIER(HeapNumber)
Steve Blocka7e24c12009-10-30 11:49:00 +00001682
Steve Block6ded16b2010-05-10 14:33:55 +01001683 inline int get_exponent();
1684 inline int get_sign();
1685
Steve Blocka7e24c12009-10-30 11:49:00 +00001686 // Layout description.
1687 static const int kValueOffset = HeapObject::kHeaderSize;
1688 // IEEE doubles are two 32 bit words. The first is just mantissa, the second
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001689 // is a mixture of sign, exponent and mantissa. The offsets of two 32 bit
1690 // words within double numbers are endian dependent and they are set
1691 // accordingly.
1692#if defined(V8_TARGET_LITTLE_ENDIAN)
Steve Blocka7e24c12009-10-30 11:49:00 +00001693 static const int kMantissaOffset = kValueOffset;
1694 static const int kExponentOffset = kValueOffset + 4;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001695#elif defined(V8_TARGET_BIG_ENDIAN)
1696 static const int kMantissaOffset = kValueOffset + 4;
1697 static const int kExponentOffset = kValueOffset;
1698#else
1699#error Unknown byte ordering
1700#endif
Ben Murdoch8b112d22011-06-08 16:22:53 +01001701
Steve Blocka7e24c12009-10-30 11:49:00 +00001702 static const int kSize = kValueOffset + kDoubleSize;
Steve Blocka7e24c12009-10-30 11:49:00 +00001703 static const uint32_t kSignMask = 0x80000000u;
1704 static const uint32_t kExponentMask = 0x7ff00000u;
1705 static const uint32_t kMantissaMask = 0xfffffu;
Steve Block6ded16b2010-05-10 14:33:55 +01001706 static const int kMantissaBits = 52;
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01001707 static const int kExponentBits = 11;
Steve Blocka7e24c12009-10-30 11:49:00 +00001708 static const int kExponentBias = 1023;
1709 static const int kExponentShift = 20;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001710 static const int kInfinityOrNanExponent =
1711 (kExponentMask >> kExponentShift) - kExponentBias;
Steve Blocka7e24c12009-10-30 11:49:00 +00001712 static const int kMantissaBitsInTopWord = 20;
1713 static const int kNonMantissaBitsInTopWord = 12;
1714
1715 private:
1716 DISALLOW_IMPLICIT_CONSTRUCTORS(HeapNumber);
1717};
1718
1719
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001720// The Simd128Value class describes heap allocated 128 bit SIMD values.
1721class Simd128Value : public HeapObject {
1722 public:
1723 DECLARE_CAST(Simd128Value)
1724
1725 DECLARE_PRINTER(Simd128Value)
1726 DECLARE_VERIFIER(Simd128Value)
1727
1728 static Handle<String> ToString(Handle<Simd128Value> input);
1729
1730 // Equality operations.
1731 inline bool Equals(Simd128Value* that);
1732 static inline bool Equals(Handle<Simd128Value> one, Handle<Simd128Value> two);
1733
1734 // Checks that another instance is bit-wise equal.
1735 bool BitwiseEquals(const Simd128Value* other) const;
1736 // Computes a hash from the 128 bit value, viewed as 4 32-bit integers.
1737 uint32_t Hash() const;
1738 // Copies the 16 bytes of SIMD data to the destination address.
1739 void CopyBits(void* destination) const;
1740
1741 // Layout description.
1742 static const int kValueOffset = HeapObject::kHeaderSize;
1743 static const int kSize = kValueOffset + kSimd128Size;
1744
1745 private:
1746 DISALLOW_IMPLICIT_CONSTRUCTORS(Simd128Value);
1747};
1748
1749
1750// V has parameters (TYPE, Type, type, lane count, lane type)
1751#define SIMD128_TYPES(V) \
1752 V(FLOAT32X4, Float32x4, float32x4, 4, float) \
1753 V(INT32X4, Int32x4, int32x4, 4, int32_t) \
1754 V(UINT32X4, Uint32x4, uint32x4, 4, uint32_t) \
1755 V(BOOL32X4, Bool32x4, bool32x4, 4, bool) \
1756 V(INT16X8, Int16x8, int16x8, 8, int16_t) \
1757 V(UINT16X8, Uint16x8, uint16x8, 8, uint16_t) \
1758 V(BOOL16X8, Bool16x8, bool16x8, 8, bool) \
1759 V(INT8X16, Int8x16, int8x16, 16, int8_t) \
1760 V(UINT8X16, Uint8x16, uint8x16, 16, uint8_t) \
1761 V(BOOL8X16, Bool8x16, bool8x16, 16, bool)
1762
1763#define SIMD128_VALUE_CLASS(TYPE, Type, type, lane_count, lane_type) \
1764 class Type final : public Simd128Value { \
1765 public: \
1766 inline lane_type get_lane(int lane) const; \
1767 inline void set_lane(int lane, lane_type value); \
1768 \
1769 DECLARE_CAST(Type) \
1770 \
1771 DECLARE_PRINTER(Type) \
1772 \
1773 static Handle<String> ToString(Handle<Type> input); \
1774 \
1775 inline bool Equals(Type* that); \
1776 \
1777 private: \
1778 DISALLOW_IMPLICIT_CONSTRUCTORS(Type); \
1779 };
1780SIMD128_TYPES(SIMD128_VALUE_CLASS)
1781#undef SIMD128_VALUE_CLASS
1782
1783
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001784enum EnsureElementsMode {
1785 DONT_ALLOW_DOUBLE_ELEMENTS,
1786 ALLOW_COPIED_DOUBLE_ELEMENTS,
1787 ALLOW_CONVERTED_DOUBLE_ELEMENTS
1788};
1789
1790
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001791// Indicator for one component of an AccessorPair.
1792enum AccessorComponent {
1793 ACCESSOR_GETTER,
1794 ACCESSOR_SETTER
1795};
1796
1797
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001798enum GetKeysConversion { KEEP_NUMBERS, CONVERT_TO_STRING };
1799
Ben Murdoch097c5b22016-05-18 11:27:45 +01001800enum KeyCollectionType { OWN_ONLY, INCLUDE_PROTOS };
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001801
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001802// JSReceiver includes types on which properties can be defined, i.e.,
1803// JSObject and JSProxy.
1804class JSReceiver: public HeapObject {
Steve Blocka7e24c12009-10-30 11:49:00 +00001805 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001806 // [properties]: Backing storage for properties.
1807 // properties is a FixedArray in the fast case and a Dictionary in the
1808 // slow case.
1809 DECL_ACCESSORS(properties, FixedArray) // Get and set fast properties.
1810 inline void initialize_properties();
1811 inline bool HasFastProperties();
1812 // Gets slow properties for non-global objects.
1813 inline NameDictionary* property_dictionary();
1814
1815 // Deletes an existing named property in a normalized object.
1816 static void DeleteNormalizedProperty(Handle<JSReceiver> object,
1817 Handle<Name> name, int entry);
Ben Murdoche0cee9b2011-05-25 10:26:03 +01001818
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001819 DECLARE_CAST(JSReceiver)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001820
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001821 // ES6 section 7.1.1 ToPrimitive
1822 MUST_USE_RESULT static MaybeHandle<Object> ToPrimitive(
1823 Handle<JSReceiver> receiver,
1824 ToPrimitiveHint hint = ToPrimitiveHint::kDefault);
1825 MUST_USE_RESULT static MaybeHandle<Object> OrdinaryToPrimitive(
1826 Handle<JSReceiver> receiver, OrdinaryToPrimitiveHint hint);
1827
1828 static MaybeHandle<Context> GetFunctionRealm(Handle<JSReceiver> receiver);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001829
Ben Murdoch097c5b22016-05-18 11:27:45 +01001830 // Get the first non-hidden prototype.
1831 static inline MaybeHandle<Object> GetPrototype(Isolate* isolate,
1832 Handle<JSReceiver> receiver);
1833
1834 MUST_USE_RESULT static Maybe<bool> HasInPrototypeChain(
1835 Isolate* isolate, Handle<JSReceiver> object, Handle<Object> proto);
1836
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001837 // Implementation of [[HasProperty]], ECMA-262 5th edition, section 8.12.6.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001838 MUST_USE_RESULT static Maybe<bool> HasProperty(LookupIterator* it);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001839 MUST_USE_RESULT static inline Maybe<bool> HasProperty(
1840 Handle<JSReceiver> object, Handle<Name> name);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001841 MUST_USE_RESULT static inline Maybe<bool> HasElement(
1842 Handle<JSReceiver> object, uint32_t index);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001843
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001844 MUST_USE_RESULT static inline Maybe<bool> HasOwnProperty(
1845 Handle<JSReceiver> object, Handle<Name> name);
Ben Murdochc5610432016-08-08 18:44:38 +01001846 MUST_USE_RESULT static inline Maybe<bool> HasOwnProperty(
1847 Handle<JSReceiver> object, uint32_t index);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001848
Ben Murdochda12d292016-06-02 14:46:10 +01001849 MUST_USE_RESULT static inline MaybeHandle<Object> GetProperty(
1850 Isolate* isolate, Handle<JSReceiver> receiver, const char* key);
1851 MUST_USE_RESULT static inline MaybeHandle<Object> GetProperty(
1852 Handle<JSReceiver> receiver, Handle<Name> name);
1853 MUST_USE_RESULT static inline MaybeHandle<Object> GetElement(
1854 Isolate* isolate, Handle<JSReceiver> receiver, uint32_t index);
1855
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001856 // Implementation of ES6 [[Delete]]
1857 MUST_USE_RESULT static Maybe<bool> DeletePropertyOrElement(
1858 Handle<JSReceiver> object, Handle<Name> name,
1859 LanguageMode language_mode = SLOPPY);
1860 MUST_USE_RESULT static Maybe<bool> DeleteProperty(
1861 Handle<JSReceiver> object, Handle<Name> name,
1862 LanguageMode language_mode = SLOPPY);
1863 MUST_USE_RESULT static Maybe<bool> DeleteProperty(LookupIterator* it,
1864 LanguageMode language_mode);
1865 MUST_USE_RESULT static Maybe<bool> DeleteElement(
1866 Handle<JSReceiver> object, uint32_t index,
1867 LanguageMode language_mode = SLOPPY);
1868
1869 MUST_USE_RESULT static Object* DefineProperty(Isolate* isolate,
1870 Handle<Object> object,
1871 Handle<Object> name,
1872 Handle<Object> attributes);
1873 MUST_USE_RESULT static MaybeHandle<Object> DefineProperties(
1874 Isolate* isolate, Handle<Object> object, Handle<Object> properties);
1875
1876 // "virtual" dispatcher to the correct [[DefineOwnProperty]] implementation.
1877 MUST_USE_RESULT static Maybe<bool> DefineOwnProperty(
1878 Isolate* isolate, Handle<JSReceiver> object, Handle<Object> key,
1879 PropertyDescriptor* desc, ShouldThrow should_throw);
1880
1881 // ES6 7.3.4 (when passed DONT_THROW)
1882 MUST_USE_RESULT static Maybe<bool> CreateDataProperty(
1883 LookupIterator* it, Handle<Object> value, ShouldThrow should_throw);
1884
1885 // ES6 9.1.6.1
1886 MUST_USE_RESULT static Maybe<bool> OrdinaryDefineOwnProperty(
1887 Isolate* isolate, Handle<JSObject> object, Handle<Object> key,
1888 PropertyDescriptor* desc, ShouldThrow should_throw);
1889 MUST_USE_RESULT static Maybe<bool> OrdinaryDefineOwnProperty(
1890 LookupIterator* it, PropertyDescriptor* desc, ShouldThrow should_throw);
1891 // ES6 9.1.6.2
1892 MUST_USE_RESULT static Maybe<bool> IsCompatiblePropertyDescriptor(
1893 Isolate* isolate, bool extensible, PropertyDescriptor* desc,
1894 PropertyDescriptor* current, Handle<Name> property_name,
1895 ShouldThrow should_throw);
1896 // ES6 9.1.6.3
1897 // |it| can be NULL in cases where the ES spec passes |undefined| as the
1898 // receiver. Exactly one of |it| and |property_name| must be provided.
1899 MUST_USE_RESULT static Maybe<bool> ValidateAndApplyPropertyDescriptor(
1900 Isolate* isolate, LookupIterator* it, bool extensible,
1901 PropertyDescriptor* desc, PropertyDescriptor* current,
1902 ShouldThrow should_throw, Handle<Name> property_name = Handle<Name>());
1903
1904 MUST_USE_RESULT static Maybe<bool> GetOwnPropertyDescriptor(
1905 Isolate* isolate, Handle<JSReceiver> object, Handle<Object> key,
1906 PropertyDescriptor* desc);
1907 MUST_USE_RESULT static Maybe<bool> GetOwnPropertyDescriptor(
1908 LookupIterator* it, PropertyDescriptor* desc);
1909
1910 typedef PropertyAttributes IntegrityLevel;
1911
1912 // ES6 7.3.14 (when passed DONT_THROW)
1913 // 'level' must be SEALED or FROZEN.
1914 MUST_USE_RESULT static Maybe<bool> SetIntegrityLevel(
1915 Handle<JSReceiver> object, IntegrityLevel lvl, ShouldThrow should_throw);
1916
1917 // ES6 7.3.15
1918 // 'level' must be SEALED or FROZEN.
1919 MUST_USE_RESULT static Maybe<bool> TestIntegrityLevel(
1920 Handle<JSReceiver> object, IntegrityLevel lvl);
1921
1922 // ES6 [[PreventExtensions]] (when passed DONT_THROW)
1923 MUST_USE_RESULT static Maybe<bool> PreventExtensions(
1924 Handle<JSReceiver> object, ShouldThrow should_throw);
1925
1926 MUST_USE_RESULT static Maybe<bool> IsExtensible(Handle<JSReceiver> object);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001927
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001928 // Returns the class name ([[Class]] property in the specification).
1929 String* class_name();
1930
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001931 // Returns the builtin string tag used in Object.prototype.toString.
1932 MUST_USE_RESULT static MaybeHandle<String> BuiltinStringTag(
1933 Handle<JSReceiver> object);
1934
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001935 // Returns the constructor name (the name (possibly, inferred name) of the
1936 // function that was used to instantiate the object).
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001937 static Handle<String> GetConstructorName(Handle<JSReceiver> receiver);
1938
1939 Context* GetCreationContext();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001940
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001941 MUST_USE_RESULT static inline Maybe<PropertyAttributes> GetPropertyAttributes(
1942 Handle<JSReceiver> object, Handle<Name> name);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001943 MUST_USE_RESULT static inline Maybe<PropertyAttributes>
1944 GetOwnPropertyAttributes(Handle<JSReceiver> object, Handle<Name> name);
Ben Murdochc5610432016-08-08 18:44:38 +01001945 MUST_USE_RESULT static inline Maybe<PropertyAttributes>
1946 GetOwnPropertyAttributes(Handle<JSReceiver> object, uint32_t index);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001947
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001948 MUST_USE_RESULT static inline Maybe<PropertyAttributes> GetElementAttributes(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001949 Handle<JSReceiver> object, uint32_t index);
1950 MUST_USE_RESULT static inline Maybe<PropertyAttributes>
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001951 GetOwnElementAttributes(Handle<JSReceiver> object, uint32_t index);
1952
1953 MUST_USE_RESULT static Maybe<PropertyAttributes> GetPropertyAttributes(
1954 LookupIterator* it);
1955
1956 // Set the object's prototype (only JSReceiver and null are allowed values).
1957 MUST_USE_RESULT static Maybe<bool> SetPrototype(Handle<JSReceiver> object,
1958 Handle<Object> value,
1959 bool from_javascript,
1960 ShouldThrow should_throw);
1961
Ben Murdochda12d292016-06-02 14:46:10 +01001962 inline static Handle<Object> GetDataProperty(Handle<JSReceiver> object,
1963 Handle<Name> name);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001964 static Handle<Object> GetDataProperty(LookupIterator* it);
1965
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001966
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001967 // Retrieves a permanent object identity hash code. The undefined value might
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001968 // be returned in case no hash was created yet.
Ben Murdochda12d292016-06-02 14:46:10 +01001969 static inline Handle<Object> GetIdentityHash(Isolate* isolate,
1970 Handle<JSReceiver> object);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001971
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001972 // Retrieves a permanent object identity hash code. May create and store a
1973 // hash code if needed and none exists.
1974 inline static Handle<Smi> GetOrCreateIdentityHash(
1975 Handle<JSReceiver> object);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001976
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001977 // ES6 [[OwnPropertyKeys]] (modulo return type)
1978 MUST_USE_RESULT static MaybeHandle<FixedArray> OwnPropertyKeys(
1979 Handle<JSReceiver> object) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001980 return GetKeys(object, OWN_ONLY, ALL_PROPERTIES, CONVERT_TO_STRING);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001981 }
1982
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001983 // Computes the enumerable keys for a JSObject. Used for implementing
1984 // "for (n in object) { }".
1985 MUST_USE_RESULT static MaybeHandle<FixedArray> GetKeys(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001986 Handle<JSReceiver> object, KeyCollectionType type, PropertyFilter filter,
Ben Murdochda12d292016-06-02 14:46:10 +01001987 GetKeysConversion keys_conversion = KEEP_NUMBERS,
1988 bool filter_proxy_keys_ = true);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001989
Ben Murdoch097c5b22016-05-18 11:27:45 +01001990 MUST_USE_RESULT static MaybeHandle<FixedArray> GetOwnValues(
1991 Handle<JSReceiver> object, PropertyFilter filter);
1992
1993 MUST_USE_RESULT static MaybeHandle<FixedArray> GetOwnEntries(
1994 Handle<JSReceiver> object, PropertyFilter filter);
1995
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001996 // Layout description.
1997 static const int kPropertiesOffset = HeapObject::kHeaderSize;
1998 static const int kHeaderSize = HeapObject::kHeaderSize + kPointerSize;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001999
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002000 private:
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002001 DISALLOW_IMPLICIT_CONSTRUCTORS(JSReceiver);
2002};
2003
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002004
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002005// The JSObject describes real heap allocated JavaScript objects with
2006// properties.
2007// Note that the map of JSObject changes during execution to enable inline
2008// caching.
2009class JSObject: public JSReceiver {
2010 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002011 static MUST_USE_RESULT MaybeHandle<JSObject> New(
2012 Handle<JSFunction> constructor, Handle<JSReceiver> new_target,
2013 Handle<AllocationSite> site = Handle<AllocationSite>::null());
2014
2015 // Gets global object properties.
2016 inline GlobalDictionary* global_dictionary();
2017
2018 static MaybeHandle<Context> GetFunctionRealm(Handle<JSObject> object);
Steve Blocka7e24c12009-10-30 11:49:00 +00002019
2020 // [elements]: The elements (properties with names that are integers).
Iain Merrick75681382010-08-19 15:07:18 +01002021 //
2022 // Elements can be in two general modes: fast and slow. Each mode
2023 // corrensponds to a set of object representations of elements that
2024 // have something in common.
2025 //
2026 // In the fast mode elements is a FixedArray and so each element can
2027 // be quickly accessed. This fact is used in the generated code. The
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002028 // elements array can have one of three maps in this mode:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002029 // fixed_array_map, sloppy_arguments_elements_map or
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002030 // fixed_cow_array_map (for copy-on-write arrays). In the latter case
2031 // the elements array may be shared by a few objects and so before
2032 // writing to any element the array must be copied. Use
2033 // EnsureWritableFastElements in this case.
Iain Merrick75681382010-08-19 15:07:18 +01002034 //
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002035 // In the slow mode the elements is either a NumberDictionary, a
2036 // FixedArray parameter map for a (sloppy) arguments object.
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002037 DECL_ACCESSORS(elements, FixedArrayBase)
Steve Blocka7e24c12009-10-30 11:49:00 +00002038 inline void initialize_elements();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002039 static void ResetElements(Handle<JSObject> object);
2040 static inline void SetMapAndElements(Handle<JSObject> object,
2041 Handle<Map> map,
2042 Handle<FixedArrayBase> elements);
Steve Blocka7e24c12009-10-30 11:49:00 +00002043 inline ElementsKind GetElementsKind();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002044 ElementsAccessor* GetElementsAccessor();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002045 // Returns true if an object has elements of FAST_SMI_ELEMENTS ElementsKind.
2046 inline bool HasFastSmiElements();
2047 // Returns true if an object has elements of FAST_ELEMENTS ElementsKind.
2048 inline bool HasFastObjectElements();
2049 // Returns true if an object has elements of FAST_ELEMENTS or
2050 // FAST_SMI_ONLY_ELEMENTS.
2051 inline bool HasFastSmiOrObjectElements();
2052 // Returns true if an object has any of the fast elements kinds.
Steve Blocka7e24c12009-10-30 11:49:00 +00002053 inline bool HasFastElements();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002054 // Returns true if an object has elements of FAST_DOUBLE_ELEMENTS
2055 // ElementsKind.
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002056 inline bool HasFastDoubleElements();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002057 // Returns true if an object has elements of FAST_HOLEY_*_ELEMENTS
2058 // ElementsKind.
2059 inline bool HasFastHoleyElements();
2060 inline bool HasSloppyArgumentsElements();
Ben Murdoch097c5b22016-05-18 11:27:45 +01002061 inline bool HasStringWrapperElements();
Steve Blocka7e24c12009-10-30 11:49:00 +00002062 inline bool HasDictionaryElements();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002063
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002064 inline bool HasFixedTypedArrayElements();
2065
2066 inline bool HasFixedUint8ClampedElements();
2067 inline bool HasFixedArrayElements();
2068 inline bool HasFixedInt8Elements();
2069 inline bool HasFixedUint8Elements();
2070 inline bool HasFixedInt16Elements();
2071 inline bool HasFixedUint16Elements();
2072 inline bool HasFixedInt32Elements();
2073 inline bool HasFixedUint32Elements();
2074 inline bool HasFixedFloat32Elements();
2075 inline bool HasFixedFloat64Elements();
2076
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002077 inline bool HasFastArgumentsElements();
2078 inline bool HasSlowArgumentsElements();
Ben Murdoch097c5b22016-05-18 11:27:45 +01002079 inline bool HasFastStringWrapperElements();
2080 inline bool HasSlowStringWrapperElements();
Ben Murdochda12d292016-06-02 14:46:10 +01002081 bool HasEnumerableElements();
2082
Ben Murdochc7cc0282012-03-05 14:35:55 +00002083 inline SeededNumberDictionary* element_dictionary(); // Gets slow elements.
2084
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002085 // Requires: HasFastElements().
Ben Murdochda12d292016-06-02 14:46:10 +01002086 static void EnsureWritableFastElements(Handle<JSObject> object);
Steve Blocka7e24c12009-10-30 11:49:00 +00002087
2088 // Collects elements starting at index 0.
2089 // Undefined values are placed after non-undefined values.
2090 // Returns the number of non-undefined values.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002091 static Handle<Object> PrepareElementsForSort(Handle<JSObject> object,
2092 uint32_t limit);
Steve Blocka7e24c12009-10-30 11:49:00 +00002093 // As PrepareElementsForSort, but only on objects where elements is
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002094 // a dictionary, and it will stay a dictionary. Collates undefined and
2095 // unexisting elements below limit from position zero of the elements.
2096 static Handle<Object> PrepareSlowElementsForSort(Handle<JSObject> object,
2097 uint32_t limit);
Steve Blocka7e24c12009-10-30 11:49:00 +00002098
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002099 MUST_USE_RESULT static Maybe<bool> SetPropertyWithInterceptor(
Ben Murdoch097c5b22016-05-18 11:27:45 +01002100 LookupIterator* it, ShouldThrow should_throw, Handle<Object> value);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002101
Ben Murdoch097c5b22016-05-18 11:27:45 +01002102 // The API currently still wants DefineOwnPropertyIgnoreAttributes to convert
2103 // AccessorInfo objects to data fields. We allow FORCE_FIELD as an exception
2104 // to the default behavior that calls the setter.
2105 enum AccessorInfoHandling { FORCE_FIELD, DONT_FORCE_FIELD };
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002106
2107 MUST_USE_RESULT static MaybeHandle<Object> DefineOwnPropertyIgnoreAttributes(
2108 LookupIterator* it, Handle<Object> value, PropertyAttributes attributes,
Ben Murdoch097c5b22016-05-18 11:27:45 +01002109 AccessorInfoHandling handling = DONT_FORCE_FIELD);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002110
2111 MUST_USE_RESULT static Maybe<bool> DefineOwnPropertyIgnoreAttributes(
2112 LookupIterator* it, Handle<Object> value, PropertyAttributes attributes,
2113 ShouldThrow should_throw,
Ben Murdoch097c5b22016-05-18 11:27:45 +01002114 AccessorInfoHandling handling = DONT_FORCE_FIELD);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002115
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002116 MUST_USE_RESULT static MaybeHandle<Object> SetOwnPropertyIgnoreAttributes(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002117 Handle<JSObject> object, Handle<Name> name, Handle<Object> value,
Ben Murdoch097c5b22016-05-18 11:27:45 +01002118 PropertyAttributes attributes);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002119
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002120 MUST_USE_RESULT static MaybeHandle<Object> SetOwnElementIgnoreAttributes(
2121 Handle<JSObject> object, uint32_t index, Handle<Object> value,
Ben Murdoch097c5b22016-05-18 11:27:45 +01002122 PropertyAttributes attributes);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002123
2124 // Equivalent to one of the above depending on whether |name| can be converted
2125 // to an array index.
2126 MUST_USE_RESULT static MaybeHandle<Object>
Ben Murdoch097c5b22016-05-18 11:27:45 +01002127 DefinePropertyOrElementIgnoreAttributes(Handle<JSObject> object,
2128 Handle<Name> name,
2129 Handle<Object> value,
2130 PropertyAttributes attributes = NONE);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002131
2132 // Adds or reconfigures a property to attributes NONE. It will fail when it
2133 // cannot.
Ben Murdochda12d292016-06-02 14:46:10 +01002134 MUST_USE_RESULT static Maybe<bool> CreateDataProperty(
2135 LookupIterator* it, Handle<Object> value,
2136 ShouldThrow should_throw = DONT_THROW);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002137
2138 static void AddProperty(Handle<JSObject> object, Handle<Name> name,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002139 Handle<Object> value, PropertyAttributes attributes);
Steve Blocka7e24c12009-10-30 11:49:00 +00002140
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002141 MUST_USE_RESULT static Maybe<bool> AddDataElement(
2142 Handle<JSObject> receiver, uint32_t index, Handle<Object> value,
2143 PropertyAttributes attributes, ShouldThrow should_throw);
2144 MUST_USE_RESULT static MaybeHandle<Object> AddDataElement(
2145 Handle<JSObject> receiver, uint32_t index, Handle<Object> value,
2146 PropertyAttributes attributes);
2147
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002148 // Extend the receiver with a single fast property appeared first in the
2149 // passed map. This also extends the property backing store if necessary.
2150 static void AllocateStorageForMap(Handle<JSObject> object, Handle<Map> map);
Steve Blocka7e24c12009-10-30 11:49:00 +00002151
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002152 // Migrates the given object to a map whose field representations are the
2153 // lowest upper bound of all known representations for that field.
2154 static void MigrateInstance(Handle<JSObject> instance);
2155
2156 // Migrates the given object only if the target map is already available,
2157 // or returns false if such a map is not yet available.
2158 static bool TryMigrateInstance(Handle<JSObject> instance);
Steve Blocka7e24c12009-10-30 11:49:00 +00002159
2160 // Sets the property value in a normalized object given (key, value, details).
2161 // Handles the special representation of JS global objects.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002162 static void SetNormalizedProperty(Handle<JSObject> object, Handle<Name> name,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002163 Handle<Object> value,
2164 PropertyDetails details);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002165 static void SetDictionaryElement(Handle<JSObject> object, uint32_t index,
2166 Handle<Object> value,
2167 PropertyAttributes attributes);
2168 static void SetDictionaryArgumentsElement(Handle<JSObject> object,
2169 uint32_t index,
2170 Handle<Object> value,
2171 PropertyAttributes attributes);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002172
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002173 static void OptimizeAsPrototype(Handle<JSObject> object,
2174 PrototypeOptimizationMode mode);
2175 static void ReoptimizeIfPrototype(Handle<JSObject> object);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002176 static void LazyRegisterPrototypeUser(Handle<Map> user, Isolate* isolate);
2177 static void UpdatePrototypeUserRegistration(Handle<Map> old_map,
2178 Handle<Map> new_map,
2179 Isolate* isolate);
2180 static bool UnregisterPrototypeUser(Handle<Map> user, Isolate* isolate);
2181 static void InvalidatePrototypeChains(Map* map);
2182
2183 // Alternative implementation of WeakFixedArray::NullCallback.
2184 class PrototypeRegistryCompactionCallback {
2185 public:
2186 static void Callback(Object* value, int old_index, int new_index);
2187 };
Steve Blocka7e24c12009-10-30 11:49:00 +00002188
Steve Blocka7e24c12009-10-30 11:49:00 +00002189 // Retrieve interceptors.
Ben Murdochda12d292016-06-02 14:46:10 +01002190 inline InterceptorInfo* GetNamedInterceptor();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002191 inline InterceptorInfo* GetIndexedInterceptor();
Steve Blocka7e24c12009-10-30 11:49:00 +00002192
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002193 // Used from JSReceiver.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002194 MUST_USE_RESULT static Maybe<PropertyAttributes>
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002195 GetPropertyAttributesWithInterceptor(LookupIterator* it);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002196 MUST_USE_RESULT static Maybe<PropertyAttributes>
2197 GetPropertyAttributesWithFailedAccessCheck(LookupIterator* it);
Steve Blocka7e24c12009-10-30 11:49:00 +00002198
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002199 // Defines an AccessorPair property on the given object.
2200 // TODO(mstarzinger): Rename to SetAccessor().
2201 static MaybeHandle<Object> DefineAccessor(Handle<JSObject> object,
2202 Handle<Name> name,
2203 Handle<Object> getter,
2204 Handle<Object> setter,
2205 PropertyAttributes attributes);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002206 static MaybeHandle<Object> DefineAccessor(LookupIterator* it,
2207 Handle<Object> getter,
2208 Handle<Object> setter,
2209 PropertyAttributes attributes);
Leon Clarkef7060e22010-06-03 12:02:55 +01002210
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002211 // Defines an AccessorInfo property on the given object.
2212 MUST_USE_RESULT static MaybeHandle<Object> SetAccessor(
2213 Handle<JSObject> object,
2214 Handle<AccessorInfo> info);
2215
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002216 // The result must be checked first for exceptions. If there's no exception,
2217 // the output parameter |done| indicates whether the interceptor has a result
2218 // or not.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002219 MUST_USE_RESULT static MaybeHandle<Object> GetPropertyWithInterceptor(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002220 LookupIterator* it, bool* done);
Steve Blocka7e24c12009-10-30 11:49:00 +00002221
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002222 static void ValidateElements(Handle<JSObject> object);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002223
2224 // Makes sure that this object can contain HeapObject as elements.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002225 static inline void EnsureCanContainHeapObjectElements(Handle<JSObject> obj);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002226
2227 // Makes sure that this object can contain the specified elements.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002228 static inline void EnsureCanContainElements(
2229 Handle<JSObject> object,
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002230 Object** elements,
2231 uint32_t count,
2232 EnsureElementsMode mode);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002233 static inline void EnsureCanContainElements(
2234 Handle<JSObject> object,
2235 Handle<FixedArrayBase> elements,
2236 uint32_t length,
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002237 EnsureElementsMode mode);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002238 static void EnsureCanContainElements(
2239 Handle<JSObject> object,
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002240 Arguments* arguments,
2241 uint32_t first_arg,
2242 uint32_t arg_count,
2243 EnsureElementsMode mode);
Steve Blocka7e24c12009-10-30 11:49:00 +00002244
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002245 // Would we convert a fast elements array to dictionary mode given
2246 // an access at key?
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002247 bool WouldConvertToSlowElements(uint32_t index);
Andrei Popescu402d9372010-02-26 13:31:12 +00002248
Ben Murdoche0cee9b2011-05-25 10:26:03 +01002249 // Computes the new capacity when expanding the elements of a JSObject.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002250 static uint32_t NewElementsCapacity(uint32_t old_capacity) {
Ben Murdoche0cee9b2011-05-25 10:26:03 +01002251 // (old_capacity + 50%) + 16
2252 return old_capacity + (old_capacity >> 1) + 16;
2253 }
2254
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002255 // These methods do not perform access checks!
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002256 static void UpdateAllocationSite(Handle<JSObject> object,
2257 ElementsKind to_kind);
Steve Blocka7e24c12009-10-30 11:49:00 +00002258
2259 // Lookup interceptors are used for handling properties controlled by host
2260 // objects.
2261 inline bool HasNamedInterceptor();
2262 inline bool HasIndexedInterceptor();
2263
2264 // Support functions for v8 api (needed for correct interceptor behavior).
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002265 MUST_USE_RESULT static Maybe<bool> HasRealNamedProperty(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002266 Handle<JSObject> object, Handle<Name> name);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002267 MUST_USE_RESULT static Maybe<bool> HasRealElementProperty(
2268 Handle<JSObject> object, uint32_t index);
2269 MUST_USE_RESULT static Maybe<bool> HasRealNamedCallbackProperty(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002270 Handle<JSObject> object, Handle<Name> name);
Steve Blocka7e24c12009-10-30 11:49:00 +00002271
Steve Blocka7e24c12009-10-30 11:49:00 +00002272 // Get the header size for a JSObject. Used to compute the index of
2273 // internal fields as well as the number of internal fields.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002274 static inline int GetHeaderSize(InstanceType instance_type);
Steve Blocka7e24c12009-10-30 11:49:00 +00002275 inline int GetHeaderSize();
2276
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002277 static inline int GetInternalFieldCount(Map* map);
Steve Blocka7e24c12009-10-30 11:49:00 +00002278 inline int GetInternalFieldCount();
Steve Block44f0eee2011-05-26 01:26:41 +01002279 inline int GetInternalFieldOffset(int index);
Steve Blocka7e24c12009-10-30 11:49:00 +00002280 inline Object* GetInternalField(int index);
2281 inline void SetInternalField(int index, Object* value);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002282 inline void SetInternalField(int index, Smi* value);
Ben Murdochc5610432016-08-08 18:44:38 +01002283 bool WasConstructedFromApiFunction();
Ben Murdochda12d292016-06-02 14:46:10 +01002284
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002285 // Returns a new map with all transitions dropped from the object's current
2286 // map and the ElementsKind set.
2287 static Handle<Map> GetElementsTransitionMap(Handle<JSObject> object,
2288 ElementsKind to_kind);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002289 static void TransitionElementsKind(Handle<JSObject> object,
2290 ElementsKind to_kind);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002291
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002292 // Always use this to migrate an object to a new map.
2293 // |expected_additional_properties| is only used for fast-to-slow transitions
2294 // and ignored otherwise.
2295 static void MigrateToMap(Handle<JSObject> object, Handle<Map> new_map,
2296 int expected_additional_properties = 0);
Steve Blocka7e24c12009-10-30 11:49:00 +00002297
2298 // Convert the object to use the canonical dictionary
2299 // representation. If the object is expected to have additional properties
2300 // added this number can be indicated to have the backing store allocated to
2301 // an initial capacity for holding these properties.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002302 static void NormalizeProperties(Handle<JSObject> object,
2303 PropertyNormalizationMode mode,
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002304 int expected_additional_properties,
2305 const char* reason);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002306
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002307 // Convert and update the elements backing store to be a
2308 // SeededNumberDictionary dictionary. Returns the backing after conversion.
2309 static Handle<SeededNumberDictionary> NormalizeElements(
2310 Handle<JSObject> object);
2311
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002312 void RequireSlowElements(SeededNumberDictionary* dictionary);
2313
Steve Blocka7e24c12009-10-30 11:49:00 +00002314 // Transform slow named properties to fast variants.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002315 static void MigrateSlowToFast(Handle<JSObject> object,
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002316 int unused_property_fields, const char* reason);
2317
2318 inline bool IsUnboxedDoubleField(FieldIndex index);
Steve Blocka7e24c12009-10-30 11:49:00 +00002319
2320 // Access fast-case object properties at index.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002321 static Handle<Object> FastPropertyAt(Handle<JSObject> object,
2322 Representation representation,
2323 FieldIndex index);
2324 inline Object* RawFastPropertyAt(FieldIndex index);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002325 inline double RawFastDoublePropertyAt(FieldIndex index);
2326
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002327 inline void FastPropertyAtPut(FieldIndex index, Object* value);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002328 inline void RawFastPropertyAtPut(FieldIndex index, Object* value);
2329 inline void RawFastDoublePropertyAtPut(FieldIndex index, double value);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002330 inline void WriteToField(int descriptor, PropertyDetails details,
2331 Object* value);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002332 inline void WriteToField(int descriptor, Object* value);
Steve Blocka7e24c12009-10-30 11:49:00 +00002333
2334 // Access to in object properties.
Steve Block44f0eee2011-05-26 01:26:41 +01002335 inline int GetInObjectPropertyOffset(int index);
Steve Blocka7e24c12009-10-30 11:49:00 +00002336 inline Object* InObjectPropertyAt(int index);
2337 inline Object* InObjectPropertyAtPut(int index,
2338 Object* value,
2339 WriteBarrierMode mode
2340 = UPDATE_WRITE_BARRIER);
2341
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002342 // Set the object's prototype (only JSReceiver and null are allowed values).
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002343 MUST_USE_RESULT static Maybe<bool> SetPrototype(Handle<JSObject> object,
2344 Handle<Object> value,
2345 bool from_javascript,
2346 ShouldThrow should_throw);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002347
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002348 // Initializes the body starting at |start_offset|. It is responsibility of
2349 // the caller to initialize object header. Fill the pre-allocated fields with
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002350 // pre_allocated_value and the rest with filler_value.
2351 // Note: this call does not update write barrier, the caller is responsible
2352 // to ensure that |filler_value| can be collected without WB here.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002353 inline void InitializeBody(Map* map, int start_offset,
2354 Object* pre_allocated_value, Object* filler_value);
Steve Blocka7e24c12009-10-30 11:49:00 +00002355
2356 // Check whether this object references another object
2357 bool ReferencesObject(Object* obj);
2358
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002359 MUST_USE_RESULT static Maybe<bool> PreventExtensions(
2360 Handle<JSObject> object, ShouldThrow should_throw);
Steve Block8defd9f2010-07-08 12:39:36 +01002361
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002362 static bool IsExtensible(Handle<JSObject> object);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002363
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002364 // Copy object.
2365 enum DeepCopyHints { kNoHints = 0, kObjectIsShallow = 1 };
2366
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002367 MUST_USE_RESULT static MaybeHandle<JSObject> DeepCopy(
2368 Handle<JSObject> object,
2369 AllocationSiteUsageContext* site_context,
2370 DeepCopyHints hints = kNoHints);
2371 MUST_USE_RESULT static MaybeHandle<JSObject> DeepWalk(
2372 Handle<JSObject> object,
2373 AllocationSiteCreationContext* site_context);
2374
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002375 DECLARE_CAST(JSObject)
Steve Block8defd9f2010-07-08 12:39:36 +01002376
Steve Blocka7e24c12009-10-30 11:49:00 +00002377 // Dispatched behavior.
Steve Blocka7e24c12009-10-30 11:49:00 +00002378 void JSObjectShortPrint(StringStream* accumulator);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002379 DECLARE_PRINTER(JSObject)
2380 DECLARE_VERIFIER(JSObject)
Ben Murdochb0fe1622011-05-05 13:52:32 +01002381#ifdef OBJECT_PRINT
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002382 void PrintProperties(std::ostream& os); // NOLINT
2383 void PrintElements(std::ostream& os); // NOLINT
2384#endif
2385#if defined(DEBUG) || defined(OBJECT_PRINT)
2386 void PrintTransitions(std::ostream& os); // NOLINT
Ben Murdochb0fe1622011-05-05 13:52:32 +01002387#endif
2388
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002389 static void PrintElementsTransition(
2390 FILE* file, Handle<JSObject> object,
2391 ElementsKind from_kind, Handle<FixedArrayBase> from_elements,
2392 ElementsKind to_kind, Handle<FixedArrayBase> to_elements);
2393
2394 void PrintInstanceMigration(FILE* file, Map* original_map, Map* new_map);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002395
Ben Murdochb0fe1622011-05-05 13:52:32 +01002396#ifdef DEBUG
Steve Blocka7e24c12009-10-30 11:49:00 +00002397 // Structure for collecting spill information about JSObjects.
2398 class SpillInformation {
2399 public:
2400 void Clear();
2401 void Print();
2402 int number_of_objects_;
2403 int number_of_objects_with_fast_properties_;
2404 int number_of_objects_with_fast_elements_;
2405 int number_of_fast_used_fields_;
2406 int number_of_fast_unused_fields_;
2407 int number_of_slow_used_properties_;
2408 int number_of_slow_unused_properties_;
2409 int number_of_fast_used_elements_;
2410 int number_of_fast_unused_elements_;
2411 int number_of_slow_used_elements_;
2412 int number_of_slow_unused_elements_;
2413 };
2414
2415 void IncrementSpillStatistics(SpillInformation* info);
2416#endif
Steve Blocka7e24c12009-10-30 11:49:00 +00002417
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002418#ifdef VERIFY_HEAP
2419 // If a GC was caused while constructing this object, the elements pointer
2420 // may point to a one pointer filler map. The object won't be rooted, but
2421 // our heap verification code could stumble across it.
2422 bool ElementsAreSafeToExamine();
2423#endif
2424
2425 Object* SlowReverseLookup(Object* value);
Steve Block8defd9f2010-07-08 12:39:36 +01002426
Leon Clarkee46be812010-01-19 14:06:41 +00002427 // Maximal number of elements (numbered 0 .. kMaxElementCount - 1).
2428 // Also maximal value of JSArray's length property.
2429 static const uint32_t kMaxElementCount = 0xffffffffu;
2430
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002431 // Constants for heuristics controlling conversion of fast elements
2432 // to slow elements.
2433
2434 // Maximal gap that can be introduced by adding an element beyond
2435 // the current elements length.
Steve Blocka7e24c12009-10-30 11:49:00 +00002436 static const uint32_t kMaxGap = 1024;
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002437
2438 // Maximal length of fast elements array that won't be checked for
2439 // being dense enough on expansion.
2440 static const int kMaxUncheckedFastElementsLength = 5000;
2441
2442 // Same as above but for old arrays. This limit is more strict. We
2443 // don't want to be wasteful with long lived objects.
2444 static const int kMaxUncheckedOldFastElementsLength = 500;
2445
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002446 // This constant applies only to the initial map of "global.Object" and
2447 // not to arbitrary other JSObject maps.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002448 static const int kInitialGlobalObjectUnusedPropertiesCount = 4;
2449
Steve Blocka7e24c12009-10-30 11:49:00 +00002450 static const int kMaxInstanceSize = 255 * kPointerSize;
2451 // When extending the backing storage for property values, we increase
2452 // its size by more than the 1 entry necessary, so sequentially adding fields
2453 // to the same object requires fewer allocations and copies.
2454 static const int kFieldsAdded = 3;
2455
2456 // Layout description.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002457 static const int kElementsOffset = JSReceiver::kHeaderSize;
Steve Blocka7e24c12009-10-30 11:49:00 +00002458 static const int kHeaderSize = kElementsOffset + kPointerSize;
2459
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002460 STATIC_ASSERT(kHeaderSize == Internals::kJSObjectHeaderSize);
Steve Blocka7e24c12009-10-30 11:49:00 +00002461
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002462 typedef FlexibleBodyDescriptor<JSReceiver::kPropertiesOffset> BodyDescriptor;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002463
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002464 // Gets the number of currently used elements.
2465 int GetFastElementsUsage();
2466
2467 static bool AllCanRead(LookupIterator* it);
2468 static bool AllCanWrite(LookupIterator* it);
2469
Steve Blocka7e24c12009-10-30 11:49:00 +00002470 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002471 friend class JSReceiver;
2472 friend class Object;
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002473
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002474 // Used from Object::GetProperty().
2475 MUST_USE_RESULT static MaybeHandle<Object> GetPropertyWithFailedAccessCheck(
2476 LookupIterator* it);
2477
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002478 MUST_USE_RESULT static Maybe<bool> SetPropertyWithFailedAccessCheck(
2479 LookupIterator* it, Handle<Object> value, ShouldThrow should_throw);
Steve Blocka7e24c12009-10-30 11:49:00 +00002480
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002481 // Add a property to a slow-case object.
2482 static void AddSlowProperty(Handle<JSObject> object,
2483 Handle<Name> name,
2484 Handle<Object> value,
2485 PropertyAttributes attributes);
Steve Blocka7e24c12009-10-30 11:49:00 +00002486
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002487 MUST_USE_RESULT static Maybe<bool> DeletePropertyWithInterceptor(
Ben Murdoch097c5b22016-05-18 11:27:45 +01002488 LookupIterator* it, ShouldThrow should_throw);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002489
2490 bool ReferencesObjectFromElements(FixedArray* elements,
2491 ElementsKind kind,
2492 Object* object);
Steve Blocka7e24c12009-10-30 11:49:00 +00002493
Ben Murdochda12d292016-06-02 14:46:10 +01002494 static Handle<Object> GetIdentityHash(Isolate* isolate,
2495 Handle<JSObject> object);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002496
2497 static Handle<Smi> GetOrCreateIdentityHash(Handle<JSObject> object);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002498
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002499 // Helper for fast versions of preventExtensions, seal, and freeze.
2500 // attrs is one of NONE, SEALED, or FROZEN (depending on the operation).
2501 template <PropertyAttributes attrs>
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002502 MUST_USE_RESULT static Maybe<bool> PreventExtensionsWithTransition(
2503 Handle<JSObject> object, ShouldThrow should_throw);
2504
Steve Blocka7e24c12009-10-30 11:49:00 +00002505 DISALLOW_IMPLICIT_CONSTRUCTORS(JSObject);
2506};
2507
2508
Ben Murdoch097c5b22016-05-18 11:27:45 +01002509// JSAccessorPropertyDescriptor is just a JSObject with a specific initial
2510// map. This initial map adds in-object properties for "get", "set",
2511// "enumerable" and "configurable" properties, as assigned by the
2512// FromPropertyDescriptor function for regular accessor properties.
2513class JSAccessorPropertyDescriptor: public JSObject {
2514 public:
2515 // Offsets of object fields.
2516 static const int kGetOffset = JSObject::kHeaderSize;
2517 static const int kSetOffset = kGetOffset + kPointerSize;
2518 static const int kEnumerableOffset = kSetOffset + kPointerSize;
2519 static const int kConfigurableOffset = kEnumerableOffset + kPointerSize;
2520 static const int kSize = kConfigurableOffset + kPointerSize;
2521 // Indices of in-object properties.
2522 static const int kGetIndex = 0;
2523 static const int kSetIndex = 1;
2524 static const int kEnumerableIndex = 2;
2525 static const int kConfigurableIndex = 3;
2526
2527 private:
2528 DISALLOW_IMPLICIT_CONSTRUCTORS(JSAccessorPropertyDescriptor);
2529};
2530
2531
2532// JSDataPropertyDescriptor is just a JSObject with a specific initial map.
2533// This initial map adds in-object properties for "value", "writable",
2534// "enumerable" and "configurable" properties, as assigned by the
2535// FromPropertyDescriptor function for regular data properties.
2536class JSDataPropertyDescriptor: public JSObject {
2537 public:
2538 // Offsets of object fields.
2539 static const int kValueOffset = JSObject::kHeaderSize;
2540 static const int kWritableOffset = kValueOffset + kPointerSize;
2541 static const int kEnumerableOffset = kWritableOffset + kPointerSize;
2542 static const int kConfigurableOffset = kEnumerableOffset + kPointerSize;
2543 static const int kSize = kConfigurableOffset + kPointerSize;
2544 // Indices of in-object properties.
2545 static const int kValueIndex = 0;
2546 static const int kWritableIndex = 1;
2547 static const int kEnumerableIndex = 2;
2548 static const int kConfigurableIndex = 3;
2549
2550 private:
2551 DISALLOW_IMPLICIT_CONSTRUCTORS(JSDataPropertyDescriptor);
2552};
2553
2554
2555// JSIteratorResult is just a JSObject with a specific initial map.
2556// This initial map adds in-object properties for "done" and "value",
2557// as specified by ES6 section 25.1.1.3 The IteratorResult Interface
2558class JSIteratorResult: public JSObject {
2559 public:
2560 // Offsets of object fields.
2561 static const int kValueOffset = JSObject::kHeaderSize;
2562 static const int kDoneOffset = kValueOffset + kPointerSize;
2563 static const int kSize = kDoneOffset + kPointerSize;
2564 // Indices of in-object properties.
2565 static const int kValueIndex = 0;
2566 static const int kDoneIndex = 1;
2567
2568 private:
2569 DISALLOW_IMPLICIT_CONSTRUCTORS(JSIteratorResult);
2570};
2571
2572
2573// Common superclass for JSSloppyArgumentsObject and JSStrictArgumentsObject.
2574class JSArgumentsObject: public JSObject {
2575 public:
2576 // Offsets of object fields.
2577 static const int kLengthOffset = JSObject::kHeaderSize;
2578 static const int kHeaderSize = kLengthOffset + kPointerSize;
2579 // Indices of in-object properties.
2580 static const int kLengthIndex = 0;
2581
2582 private:
2583 DISALLOW_IMPLICIT_CONSTRUCTORS(JSArgumentsObject);
2584};
2585
2586
2587// JSSloppyArgumentsObject is just a JSObject with specific initial map.
2588// This initial map adds in-object properties for "length" and "callee".
2589class JSSloppyArgumentsObject: public JSArgumentsObject {
2590 public:
2591 // Offsets of object fields.
2592 static const int kCalleeOffset = JSArgumentsObject::kHeaderSize;
2593 static const int kSize = kCalleeOffset + kPointerSize;
2594 // Indices of in-object properties.
2595 static const int kCalleeIndex = 1;
2596
2597 private:
2598 DISALLOW_IMPLICIT_CONSTRUCTORS(JSSloppyArgumentsObject);
2599};
2600
2601
2602// JSStrictArgumentsObject is just a JSObject with specific initial map.
2603// This initial map adds an in-object property for "length".
2604class JSStrictArgumentsObject: public JSArgumentsObject {
2605 public:
2606 // Offsets of object fields.
2607 static const int kSize = JSArgumentsObject::kHeaderSize;
2608
2609 private:
2610 DISALLOW_IMPLICIT_CONSTRUCTORS(JSStrictArgumentsObject);
2611};
2612
2613
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002614// Common superclass for FixedArrays that allow implementations to share
2615// common accessors and some code paths.
2616class FixedArrayBase: public HeapObject {
Steve Blocka7e24c12009-10-30 11:49:00 +00002617 public:
2618 // [length]: length of the array.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002619 inline int length() const;
Steve Blocka7e24c12009-10-30 11:49:00 +00002620 inline void set_length(int value);
2621
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002622 // Get and set the length using acquire loads and release stores.
2623 inline int synchronized_length() const;
2624 inline void synchronized_set_length(int value);
2625
2626 DECLARE_CAST(FixedArrayBase)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002627
2628 // Layout description.
2629 // Length is smi tagged when it is stored.
2630 static const int kLengthOffset = HeapObject::kHeaderSize;
2631 static const int kHeaderSize = kLengthOffset + kPointerSize;
2632};
2633
2634
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002635class FixedDoubleArray;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002636class IncrementalMarking;
2637
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002638
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002639// FixedArray describes fixed-sized arrays with element type Object*.
2640class FixedArray: public FixedArrayBase {
2641 public:
Steve Blocka7e24c12009-10-30 11:49:00 +00002642 // Setter and getter for elements.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002643 inline Object* get(int index) const;
Ben Murdoch097c5b22016-05-18 11:27:45 +01002644 static inline Handle<Object> get(FixedArray* array, int index,
2645 Isolate* isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002646 // Setter that uses write barrier.
2647 inline void set(int index, Object* value);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002648 inline bool is_the_hole(int index);
Steve Blocka7e24c12009-10-30 11:49:00 +00002649
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002650 // Setter that doesn't need write barrier.
Steve Blocka7e24c12009-10-30 11:49:00 +00002651 inline void set(int index, Smi* value);
2652 // Setter with explicit barrier mode.
2653 inline void set(int index, Object* value, WriteBarrierMode mode);
2654
2655 // Setters for frequently used oddballs located in old space.
2656 inline void set_undefined(int index);
2657 inline void set_null(int index);
2658 inline void set_the_hole(int index);
2659
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002660 inline Object** GetFirstElementAddress();
2661 inline bool ContainsOnlySmisOrHoles();
2662
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002663 // Gives access to raw memory which stores the array's data.
2664 inline Object** data_start();
2665
2666 inline void FillWithHoles(int from, int to);
2667
2668 // Shrink length and insert filler objects.
2669 void Shrink(int length);
2670
Steve Blocka7e24c12009-10-30 11:49:00 +00002671 // Copy a sub array from the receiver to dest.
2672 void CopyTo(int pos, FixedArray* dest, int dest_pos, int len);
2673
2674 // Garbage collection support.
2675 static int SizeFor(int length) { return kHeaderSize + length * kPointerSize; }
2676
2677 // Code Generation support.
2678 static int OffsetOfElementAt(int index) { return SizeFor(index); }
2679
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002680 // Garbage collection support.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002681 inline Object** RawFieldOfElementAt(int index);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002682
2683 DECLARE_CAST(FixedArray)
Steve Blocka7e24c12009-10-30 11:49:00 +00002684
Leon Clarkee46be812010-01-19 14:06:41 +00002685 // Maximal allowed size, in bytes, of a single FixedArray.
2686 // Prevents overflowing size computations, as well as extreme memory
2687 // consumption.
Ben Murdoch692be652012-01-10 18:47:50 +00002688 static const int kMaxSize = 128 * MB * kPointerSize;
Leon Clarkee46be812010-01-19 14:06:41 +00002689 // Maximally allowed length of a FixedArray.
2690 static const int kMaxLength = (kMaxSize - kHeaderSize) / kPointerSize;
Steve Blocka7e24c12009-10-30 11:49:00 +00002691
2692 // Dispatched behavior.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002693 DECLARE_PRINTER(FixedArray)
2694 DECLARE_VERIFIER(FixedArray)
Steve Blocka7e24c12009-10-30 11:49:00 +00002695#ifdef DEBUG
Steve Blocka7e24c12009-10-30 11:49:00 +00002696 // Checks if two FixedArrays have identical contents.
2697 bool IsEqualTo(FixedArray* other);
2698#endif
2699
2700 // Swap two elements in a pair of arrays. If this array and the
2701 // numbers array are the same object, the elements are only swapped
2702 // once.
2703 void SwapPairs(FixedArray* numbers, int i, int j);
2704
2705 // Sort prefix of this array and the numbers array as pairs wrt. the
2706 // numbers. If the numbers array and the this array are the same
2707 // object, the prefix of this array is sorted.
2708 void SortPairs(FixedArray* numbers, uint32_t len);
2709
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002710 typedef FlexibleBodyDescriptor<kHeaderSize> BodyDescriptor;
Iain Merrick75681382010-08-19 15:07:18 +01002711
Steve Blocka7e24c12009-10-30 11:49:00 +00002712 protected:
Leon Clarke4515c472010-02-03 11:58:03 +00002713 // Set operation on FixedArray without using write barriers. Can
2714 // only be used for storing old space objects or smis.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002715 static inline void NoWriteBarrierSet(FixedArray* array,
2716 int index,
2717 Object* value);
2718
Steve Blocka7e24c12009-10-30 11:49:00 +00002719 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002720 STATIC_ASSERT(kHeaderSize == Internals::kFixedArrayHeaderSize);
2721
Steve Blocka7e24c12009-10-30 11:49:00 +00002722 DISALLOW_IMPLICIT_CONSTRUCTORS(FixedArray);
2723};
2724
2725
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002726// FixedDoubleArray describes fixed-sized arrays with element type double.
2727class FixedDoubleArray: public FixedArrayBase {
2728 public:
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002729 // Setter and getter for elements.
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002730 inline double get_scalar(int index);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002731 inline uint64_t get_representation(int index);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002732 static inline Handle<Object> get(FixedDoubleArray* array, int index,
2733 Isolate* isolate);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002734 inline void set(int index, double value);
2735 inline void set_the_hole(int index);
2736
2737 // Checking for the hole.
2738 inline bool is_the_hole(int index);
2739
2740 // Garbage collection support.
2741 inline static int SizeFor(int length) {
2742 return kHeaderSize + length * kDoubleSize;
2743 }
2744
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002745 // Gives access to raw memory which stores the array's data.
2746 inline double* data_start();
2747
2748 inline void FillWithHoles(int from, int to);
2749
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002750 // Code Generation support.
2751 static int OffsetOfElementAt(int index) { return SizeFor(index); }
2752
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002753 DECLARE_CAST(FixedDoubleArray)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002754
2755 // Maximal allowed size, in bytes, of a single FixedDoubleArray.
2756 // Prevents overflowing size computations, as well as extreme memory
2757 // consumption.
2758 static const int kMaxSize = 512 * MB;
2759 // Maximally allowed length of a FixedArray.
2760 static const int kMaxLength = (kMaxSize - kHeaderSize) / kDoubleSize;
2761
2762 // Dispatched behavior.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002763 DECLARE_PRINTER(FixedDoubleArray)
2764 DECLARE_VERIFIER(FixedDoubleArray)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002765
2766 private:
2767 DISALLOW_IMPLICIT_CONSTRUCTORS(FixedDoubleArray);
2768};
2769
2770
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002771class WeakFixedArray : public FixedArray {
2772 public:
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002773 // If |maybe_array| is not a WeakFixedArray, a fresh one will be allocated.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002774 // This function does not check if the value exists already, callers must
2775 // ensure this themselves if necessary.
2776 static Handle<WeakFixedArray> Add(Handle<Object> maybe_array,
2777 Handle<HeapObject> value,
2778 int* assigned_index = NULL);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002779
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002780 // Returns true if an entry was found and removed.
2781 bool Remove(Handle<HeapObject> value);
2782
2783 class NullCallback {
2784 public:
2785 static void Callback(Object* value, int old_index, int new_index) {}
2786 };
2787
2788 template <class CompactionCallback>
2789 void Compact();
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002790
2791 inline Object* Get(int index) const;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002792 inline void Clear(int index);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002793 inline int Length() const;
2794
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002795 inline bool IsEmptySlot(int index) const;
2796 static Object* Empty() { return Smi::FromInt(0); }
2797
2798 class Iterator {
2799 public:
2800 explicit Iterator(Object* maybe_array) : list_(NULL) { Reset(maybe_array); }
2801 void Reset(Object* maybe_array);
2802
2803 template <class T>
2804 inline T* Next();
2805
2806 private:
2807 int index_;
2808 WeakFixedArray* list_;
2809#ifdef DEBUG
2810 int last_used_index_;
2811 DisallowHeapAllocation no_gc_;
2812#endif // DEBUG
2813 DISALLOW_COPY_AND_ASSIGN(Iterator);
2814 };
2815
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002816 DECLARE_CAST(WeakFixedArray)
2817
2818 private:
2819 static const int kLastUsedIndexIndex = 0;
2820 static const int kFirstIndex = 1;
2821
2822 static Handle<WeakFixedArray> Allocate(
2823 Isolate* isolate, int size, Handle<WeakFixedArray> initialize_from);
2824
2825 static void Set(Handle<WeakFixedArray> array, int index,
2826 Handle<HeapObject> value);
2827 inline void clear(int index);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002828
2829 inline int last_used_index() const;
2830 inline void set_last_used_index(int index);
2831
2832 // Disallow inherited setters.
2833 void set(int index, Smi* value);
2834 void set(int index, Object* value);
2835 void set(int index, Object* value, WriteBarrierMode mode);
2836 DISALLOW_IMPLICIT_CONSTRUCTORS(WeakFixedArray);
2837};
2838
2839
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002840// Generic array grows dynamically with O(1) amortized insertion.
2841class ArrayList : public FixedArray {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002842 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002843 enum AddMode {
2844 kNone,
2845 // Use this if GC can delete elements from the array.
2846 kReloadLengthAfterAllocation,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002847 };
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002848 static Handle<ArrayList> Add(Handle<ArrayList> array, Handle<Object> obj,
2849 AddMode mode = kNone);
2850 static Handle<ArrayList> Add(Handle<ArrayList> array, Handle<Object> obj1,
2851 Handle<Object> obj2, AddMode = kNone);
2852 inline int Length();
2853 inline void SetLength(int length);
2854 inline Object* Get(int index);
2855 inline Object** Slot(int index);
2856 inline void Set(int index, Object* obj);
2857 inline void Clear(int index, Object* undefined);
2858 bool IsFull();
2859 DECLARE_CAST(ArrayList)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002860
2861 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002862 static Handle<ArrayList> EnsureSpace(Handle<ArrayList> array, int length);
2863 static const int kLengthIndex = 0;
2864 static const int kFirstIndex = 1;
2865 DISALLOW_IMPLICIT_CONSTRUCTORS(ArrayList);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002866};
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002867
2868
Steve Blocka7e24c12009-10-30 11:49:00 +00002869// DescriptorArrays are fixed arrays used to hold instance descriptors.
2870// The format of the these objects is:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002871// [0]: Number of descriptors
2872// [1]: Either Smi(0) if uninitialized, or a pointer to small fixed array:
2873// [0]: pointer to fixed array with enum cache
2874// [1]: either Smi(0) or pointer to fixed array with indices
2875// [2]: first key
2876// [2 + number of descriptors * kDescriptorSize]: start of slack
Steve Blocka7e24c12009-10-30 11:49:00 +00002877class DescriptorArray: public FixedArray {
2878 public:
Ben Murdoch257744e2011-11-30 15:57:28 +00002879 // Returns true for both shared empty_descriptor_array and for smis, which the
2880 // map uses to encode additional bit fields when the descriptor array is not
2881 // yet used.
Steve Blocka7e24c12009-10-30 11:49:00 +00002882 inline bool IsEmpty();
Leon Clarkee46be812010-01-19 14:06:41 +00002883
Steve Blocka7e24c12009-10-30 11:49:00 +00002884 // Returns the number of descriptors in the array.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002885 inline int number_of_descriptors();
Steve Blocka7e24c12009-10-30 11:49:00 +00002886
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002887 inline int number_of_descriptors_storage();
Steve Blocka7e24c12009-10-30 11:49:00 +00002888
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002889 inline int NumberOfSlackDescriptors();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002890
2891 inline void SetNumberOfDescriptors(int number_of_descriptors);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002892 inline int number_of_entries();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002893
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002894 inline bool HasEnumCache();
Steve Blocka7e24c12009-10-30 11:49:00 +00002895
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002896 inline void CopyEnumCacheFrom(DescriptorArray* array);
Steve Blocka7e24c12009-10-30 11:49:00 +00002897
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002898 inline FixedArray* GetEnumCache();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002899
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002900 inline bool HasEnumIndicesCache();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002901
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002902 inline FixedArray* GetEnumIndicesCache();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002903
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002904 inline Object** GetEnumCacheSlot();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002905
2906 void ClearEnumCache();
Ben Murdoch257744e2011-11-30 15:57:28 +00002907
Steve Blocka7e24c12009-10-30 11:49:00 +00002908 // Initialize or change the enum cache,
2909 // using the supplied storage for the small "bridge".
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002910 static void SetEnumCache(Handle<DescriptorArray> descriptors,
2911 Isolate* isolate, Handle<FixedArray> new_cache,
2912 Handle<FixedArray> new_index_cache);
Steve Blocka7e24c12009-10-30 11:49:00 +00002913
2914 // Accessors for fetching instance descriptor at descriptor number.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002915 inline Name* GetKey(int descriptor_number);
2916 inline Object** GetKeySlot(int descriptor_number);
Steve Blocka7e24c12009-10-30 11:49:00 +00002917 inline Object* GetValue(int descriptor_number);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002918 inline void SetValue(int descriptor_number, Object* value);
2919 inline Object** GetValueSlot(int descriptor_number);
2920 static inline int GetValueOffset(int descriptor_number);
2921 inline Object** GetDescriptorStartSlot(int descriptor_number);
2922 inline Object** GetDescriptorEndSlot(int descriptor_number);
2923 inline PropertyDetails GetDetails(int descriptor_number);
Steve Blocka7e24c12009-10-30 11:49:00 +00002924 inline PropertyType GetType(int descriptor_number);
2925 inline int GetFieldIndex(int descriptor_number);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002926 FieldType* GetFieldType(int descriptor_number);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002927 inline Object* GetConstant(int descriptor_number);
Steve Blocka7e24c12009-10-30 11:49:00 +00002928 inline Object* GetCallbacksObject(int descriptor_number);
2929 inline AccessorDescriptor* GetCallbacks(int descriptor_number);
Steve Blocka7e24c12009-10-30 11:49:00 +00002930
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002931 inline Name* GetSortedKey(int descriptor_number);
2932 inline int GetSortedKeyIndex(int descriptor_number);
2933 inline void SetSortedKey(int pointer, int descriptor_number);
2934 inline void SetRepresentation(int descriptor_number,
2935 Representation representation);
2936
2937 // Accessor for complete descriptor.
2938 inline void Get(int descriptor_number, Descriptor* desc);
2939 inline void Set(int descriptor_number, Descriptor* desc);
2940 void Replace(int descriptor_number, Descriptor* descriptor);
2941
2942 // Append automatically sets the enumeration index. This should only be used
2943 // to add descriptors in bulk at the end, followed by sorting the descriptor
2944 // array.
2945 inline void Append(Descriptor* desc);
2946
2947 static Handle<DescriptorArray> CopyUpTo(Handle<DescriptorArray> desc,
2948 int enumeration_index,
2949 int slack = 0);
2950
2951 static Handle<DescriptorArray> CopyUpToAddAttributes(
2952 Handle<DescriptorArray> desc,
2953 int enumeration_index,
2954 PropertyAttributes attributes,
2955 int slack = 0);
2956
2957 // Sort the instance descriptors by the hash codes of their keys.
2958 void Sort();
2959
2960 // Search the instance descriptors for given name.
2961 INLINE(int Search(Name* name, int number_of_own_descriptors));
2962
2963 // As the above, but uses DescriptorLookupCache and updates it when
2964 // necessary.
Ben Murdoch097c5b22016-05-18 11:27:45 +01002965 INLINE(int SearchWithCache(Isolate* isolate, Name* name, Map* map));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002966
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002967 bool IsEqualUpTo(DescriptorArray* desc, int nof_descriptors);
2968
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002969 // Allocates a DescriptorArray, but returns the singleton
2970 // empty descriptor array object if number_of_descriptors is 0.
Ben Murdoch097c5b22016-05-18 11:27:45 +01002971 static Handle<DescriptorArray> Allocate(
2972 Isolate* isolate, int number_of_descriptors, int slack,
2973 PretenureFlag pretenure = NOT_TENURED);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002974
2975 DECLARE_CAST(DescriptorArray)
2976
2977 // Constant for denoting key was not found.
2978 static const int kNotFound = -1;
2979
2980 static const int kDescriptorLengthIndex = 0;
2981 static const int kEnumCacheIndex = 1;
2982 static const int kFirstIndex = 2;
2983
2984 // The length of the "bridge" to the enum cache.
2985 static const int kEnumCacheBridgeLength = 2;
2986 static const int kEnumCacheBridgeCacheIndex = 0;
2987 static const int kEnumCacheBridgeIndicesCacheIndex = 1;
2988
2989 // Layout description.
2990 static const int kDescriptorLengthOffset = FixedArray::kHeaderSize;
2991 static const int kEnumCacheOffset = kDescriptorLengthOffset + kPointerSize;
2992 static const int kFirstOffset = kEnumCacheOffset + kPointerSize;
2993
2994 // Layout description for the bridge array.
2995 static const int kEnumCacheBridgeCacheOffset = FixedArray::kHeaderSize;
2996
2997 // Layout of descriptor.
2998 static const int kDescriptorKey = 0;
2999 static const int kDescriptorDetails = 1;
3000 static const int kDescriptorValue = 2;
3001 static const int kDescriptorSize = 3;
3002
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003003#if defined(DEBUG) || defined(OBJECT_PRINT)
3004 // For our gdb macros, we should perhaps change these in the future.
3005 void Print();
3006
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003007 // Print all the descriptors.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003008 void PrintDescriptors(std::ostream& os); // NOLINT
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003009#endif
3010
3011#ifdef DEBUG
3012 // Is the descriptor array sorted and without duplicates?
3013 bool IsSortedNoDuplicates(int valid_descriptors = -1);
3014
3015 // Is the descriptor array consistent with the back pointers in targets?
3016 bool IsConsistentWithBackPointers(Map* current_map);
3017
3018 // Are two DescriptorArrays equal?
3019 bool IsEqualTo(DescriptorArray* other);
3020#endif
3021
3022 // Returns the fixed array length required to hold number_of_descriptors
3023 // descriptors.
3024 static int LengthFor(int number_of_descriptors) {
3025 return ToKeyIndex(number_of_descriptors);
3026 }
3027
Ben Murdochda12d292016-06-02 14:46:10 +01003028 static int ToDetailsIndex(int descriptor_number) {
3029 return kFirstIndex + (descriptor_number * kDescriptorSize) +
3030 kDescriptorDetails;
3031 }
3032
3033 // Conversion from descriptor number to array indices.
3034 static int ToKeyIndex(int descriptor_number) {
3035 return kFirstIndex + (descriptor_number * kDescriptorSize) + kDescriptorKey;
3036 }
3037
Ben Murdochc5610432016-08-08 18:44:38 +01003038 static int ToValueIndex(int descriptor_number) {
3039 return kFirstIndex + (descriptor_number * kDescriptorSize) +
3040 kDescriptorValue;
3041 }
3042
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003043 private:
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003044 // An entry in a DescriptorArray, represented as an (array, index) pair.
3045 class Entry {
3046 public:
3047 inline explicit Entry(DescriptorArray* descs, int index) :
3048 descs_(descs), index_(index) { }
3049
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003050 inline PropertyType type();
3051 inline Object* GetCallbackObject();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003052
3053 private:
3054 DescriptorArray* descs_;
3055 int index_;
3056 };
3057
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003058 // Transfer a complete descriptor from the src descriptor array to this
3059 // descriptor array.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003060 void CopyFrom(int index, DescriptorArray* src);
Steve Blocka7e24c12009-10-30 11:49:00 +00003061
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003062 inline void SetDescriptor(int descriptor_number, Descriptor* desc);
Steve Blocka7e24c12009-10-30 11:49:00 +00003063
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003064 // Swap first and second descriptor.
3065 inline void SwapSortedKeys(int first, int second);
3066
Steve Blocka7e24c12009-10-30 11:49:00 +00003067 DISALLOW_IMPLICIT_CONSTRUCTORS(DescriptorArray);
3068};
3069
3070
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003071enum SearchMode { ALL_ENTRIES, VALID_ENTRIES };
3072
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003073template <SearchMode search_mode, typename T>
3074inline int Search(T* array, Name* name, int valid_entries = 0,
3075 int* out_insertion_index = NULL);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003076
3077
Steve Blocka7e24c12009-10-30 11:49:00 +00003078// HashTable is a subclass of FixedArray that implements a hash table
3079// that uses open addressing and quadratic probing.
3080//
3081// In order for the quadratic probing to work, elements that have not
3082// yet been used and elements that have been deleted are
3083// distinguished. Probing continues when deleted elements are
3084// encountered and stops when unused elements are encountered.
3085//
3086// - Elements with key == undefined have not been used yet.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003087// - Elements with key == the_hole have been deleted.
Steve Blocka7e24c12009-10-30 11:49:00 +00003088//
3089// The hash table class is parameterized with a Shape and a Key.
3090// Shape must be a class with the following interface:
3091// class ExampleShape {
3092// public:
3093// // Tells whether key matches other.
3094// static bool IsMatch(Key key, Object* other);
3095// // Returns the hash value for key.
3096// static uint32_t Hash(Key key);
3097// // Returns the hash value for object.
3098// static uint32_t HashForObject(Key key, Object* object);
3099// // Convert key to an object.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003100// static inline Handle<Object> AsHandle(Isolate* isolate, Key key);
Steve Blocka7e24c12009-10-30 11:49:00 +00003101// // The prefix size indicates number of elements in the beginning
3102// // of the backing storage.
3103// static const int kPrefixSize = ..;
3104// // The Element size indicates number of elements per entry.
3105// static const int kEntrySize = ..;
3106// };
Steve Block3ce2e202009-11-05 08:53:23 +00003107// The prefix size indicates an amount of memory in the
Steve Blocka7e24c12009-10-30 11:49:00 +00003108// beginning of the backing storage that can be used for non-element
3109// information by subclasses.
3110
Ben Murdochc7cc0282012-03-05 14:35:55 +00003111template<typename Key>
3112class BaseShape {
3113 public:
3114 static const bool UsesSeed = false;
3115 static uint32_t Hash(Key key) { return 0; }
3116 static uint32_t SeededHash(Key key, uint32_t seed) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003117 DCHECK(UsesSeed);
Ben Murdochc7cc0282012-03-05 14:35:55 +00003118 return Hash(key);
3119 }
3120 static uint32_t HashForObject(Key key, Object* object) { return 0; }
3121 static uint32_t SeededHashForObject(Key key, uint32_t seed, Object* object) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003122 DCHECK(UsesSeed);
Ben Murdochc7cc0282012-03-05 14:35:55 +00003123 return HashForObject(key, object);
3124 }
3125};
3126
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003127
3128class HashTableBase : public FixedArray {
3129 public:
3130 // Returns the number of elements in the hash table.
3131 inline int NumberOfElements();
3132
3133 // Returns the number of deleted elements in the hash table.
3134 inline int NumberOfDeletedElements();
3135
3136 // Returns the capacity of the hash table.
3137 inline int Capacity();
3138
3139 // ElementAdded should be called whenever an element is added to a
3140 // hash table.
3141 inline void ElementAdded();
3142
3143 // ElementRemoved should be called whenever an element is removed from
3144 // a hash table.
3145 inline void ElementRemoved();
3146 inline void ElementsRemoved(int n);
3147
3148 // Computes the required capacity for a table holding the given
3149 // number of elements. May be more than HashTable::kMaxCapacity.
3150 static inline int ComputeCapacity(int at_least_space_for);
3151
3152 // Tells whether k is a real key. The hole and undefined are not allowed
3153 // as keys and can be used to indicate missing or deleted elements.
3154 inline bool IsKey(Object* k);
Ben Murdochda12d292016-06-02 14:46:10 +01003155 inline bool IsKey(Heap* heap, Object* k);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003156
3157 // Compute the probe offset (quadratic probing).
3158 INLINE(static uint32_t GetProbeOffset(uint32_t n)) {
3159 return (n + n * n) >> 1;
3160 }
3161
3162 static const int kNumberOfElementsIndex = 0;
3163 static const int kNumberOfDeletedElementsIndex = 1;
3164 static const int kCapacityIndex = 2;
3165 static const int kPrefixStartIndex = 3;
3166
3167 // Constant used for denoting a absent entry.
3168 static const int kNotFound = -1;
3169
3170 protected:
3171 // Update the number of elements in the hash table.
3172 inline void SetNumberOfElements(int nof);
3173
3174 // Update the number of deleted elements in the hash table.
3175 inline void SetNumberOfDeletedElements(int nod);
3176
3177 // Returns probe entry.
3178 static uint32_t GetProbe(uint32_t hash, uint32_t number, uint32_t size) {
3179 DCHECK(base::bits::IsPowerOfTwo32(size));
3180 return (hash + GetProbeOffset(number)) & (size - 1);
3181 }
3182
3183 inline static uint32_t FirstProbe(uint32_t hash, uint32_t size) {
3184 return hash & (size - 1);
3185 }
3186
3187 inline static uint32_t NextProbe(
3188 uint32_t last, uint32_t number, uint32_t size) {
3189 return (last + number) & (size - 1);
3190 }
3191};
3192
3193
3194template <typename Derived, typename Shape, typename Key>
3195class HashTable : public HashTableBase {
Steve Blocka7e24c12009-10-30 11:49:00 +00003196 public:
Ben Murdochc7cc0282012-03-05 14:35:55 +00003197 // Wrapper methods
3198 inline uint32_t Hash(Key key) {
3199 if (Shape::UsesSeed) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003200 return Shape::SeededHash(key, GetHeap()->HashSeed());
Ben Murdochc7cc0282012-03-05 14:35:55 +00003201 } else {
3202 return Shape::Hash(key);
3203 }
3204 }
3205
3206 inline uint32_t HashForObject(Key key, Object* object) {
3207 if (Shape::UsesSeed) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003208 return Shape::SeededHashForObject(key, GetHeap()->HashSeed(), object);
Ben Murdochc7cc0282012-03-05 14:35:55 +00003209 } else {
3210 return Shape::HashForObject(key, object);
3211 }
3212 }
3213
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003214 // Returns a new HashTable object.
3215 MUST_USE_RESULT static Handle<Derived> New(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003216 Isolate* isolate, int at_least_space_for,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003217 MinimumCapacity capacity_option = USE_DEFAULT_MINIMUM_CAPACITY,
Kristian Monsen80d68ea2010-09-08 11:05:35 +01003218 PretenureFlag pretenure = NOT_TENURED);
Steve Blocka7e24c12009-10-30 11:49:00 +00003219
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003220 DECLARE_CAST(HashTable)
Steve Blocka7e24c12009-10-30 11:49:00 +00003221
3222 // Garbage collection support.
3223 void IteratePrefix(ObjectVisitor* visitor);
3224 void IterateElements(ObjectVisitor* visitor);
3225
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003226 // Find entry for key otherwise return kNotFound.
3227 inline int FindEntry(Key key);
3228 inline int FindEntry(Isolate* isolate, Key key, int32_t hash);
3229 int FindEntry(Isolate* isolate, Key key);
Steve Blocka7e24c12009-10-30 11:49:00 +00003230
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003231 // Rehashes the table in-place.
3232 void Rehash(Key key);
Steve Blocka7e24c12009-10-30 11:49:00 +00003233
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003234 // Returns the key at entry.
3235 Object* KeyAt(int entry) { return get(EntryToIndex(entry)); }
3236
3237 static const int kElementsStartIndex = kPrefixStartIndex + Shape::kPrefixSize;
Leon Clarkee46be812010-01-19 14:06:41 +00003238 static const int kEntrySize = Shape::kEntrySize;
3239 static const int kElementsStartOffset =
Steve Blocka7e24c12009-10-30 11:49:00 +00003240 kHeaderSize + kElementsStartIndex * kPointerSize;
Steve Block6ded16b2010-05-10 14:33:55 +01003241 static const int kCapacityOffset =
3242 kHeaderSize + kCapacityIndex * kPointerSize;
Steve Blocka7e24c12009-10-30 11:49:00 +00003243
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003244 // Returns the index for an entry (of the key)
3245 static inline int EntryToIndex(int entry) {
3246 return (entry * kEntrySize) + kElementsStartIndex;
3247 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003248
Steve Blocka7e24c12009-10-30 11:49:00 +00003249 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003250 friend class ObjectHashTable;
3251
Steve Blocka7e24c12009-10-30 11:49:00 +00003252 // Find the entry at which to insert element with the given key that
3253 // has the given hash value.
3254 uint32_t FindInsertionEntry(uint32_t hash);
3255
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003256 // Attempt to shrink hash table after removal of key.
3257 MUST_USE_RESULT static Handle<Derived> Shrink(Handle<Derived> table, Key key);
Steve Blocka7e24c12009-10-30 11:49:00 +00003258
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003259 // Ensure enough space for n additional elements.
3260 MUST_USE_RESULT static Handle<Derived> EnsureCapacity(
3261 Handle<Derived> table,
3262 int n,
3263 Key key,
3264 PretenureFlag pretenure = NOT_TENURED);
Steve Blocka7e24c12009-10-30 11:49:00 +00003265
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003266 // Returns true if this table has sufficient capacity for adding n elements.
3267 bool HasSufficientCapacity(int n);
Leon Clarkee46be812010-01-19 14:06:41 +00003268
Steve Blocka7e24c12009-10-30 11:49:00 +00003269 // Sets the capacity of the hash table.
3270 void SetCapacity(int capacity) {
3271 // To scale a computed hash code to fit within the hash table, we
3272 // use bit-wise AND with a mask, so the capacity must be positive
3273 // and non-zero.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003274 DCHECK(capacity > 0);
3275 DCHECK(capacity <= kMaxCapacity);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003276 set(kCapacityIndex, Smi::FromInt(capacity));
Steve Blocka7e24c12009-10-30 11:49:00 +00003277 }
3278
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003279 // Maximal capacity of HashTable. Based on maximal length of underlying
3280 // FixedArray. Staying below kMaxCapacity also ensures that EntryToIndex
3281 // cannot overflow.
3282 static const int kMaxCapacity =
3283 (FixedArray::kMaxLength - kElementsStartOffset) / kEntrySize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003284
3285 private:
3286 // Returns _expected_ if one of entries given by the first _probe_ probes is
3287 // equal to _expected_. Otherwise, returns the entry given by the probe
3288 // number _probe_.
3289 uint32_t EntryForProbe(Key key, Object* k, int probe, uint32_t expected);
3290
3291 void Swap(uint32_t entry1, uint32_t entry2, WriteBarrierMode mode);
3292
3293 // Rehashes this hash-table into the new table.
3294 void Rehash(Handle<Derived> new_table, Key key);
Steve Blocka7e24c12009-10-30 11:49:00 +00003295};
3296
3297
Steve Blocka7e24c12009-10-30 11:49:00 +00003298// HashTableKey is an abstract superclass for virtual key behavior.
3299class HashTableKey {
3300 public:
3301 // Returns whether the other object matches this key.
3302 virtual bool IsMatch(Object* other) = 0;
3303 // Returns the hash value for this key.
3304 virtual uint32_t Hash() = 0;
3305 // Returns the hash value for object.
3306 virtual uint32_t HashForObject(Object* key) = 0;
Steve Block3ce2e202009-11-05 08:53:23 +00003307 // Returns the key object for storing into the hash table.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003308 MUST_USE_RESULT virtual Handle<Object> AsHandle(Isolate* isolate) = 0;
Steve Blocka7e24c12009-10-30 11:49:00 +00003309 // Required.
3310 virtual ~HashTableKey() {}
3311};
3312
Ben Murdochc7cc0282012-03-05 14:35:55 +00003313
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003314class StringTableShape : public BaseShape<HashTableKey*> {
Steve Blocka7e24c12009-10-30 11:49:00 +00003315 public:
Steve Block44f0eee2011-05-26 01:26:41 +01003316 static inline bool IsMatch(HashTableKey* key, Object* value) {
Steve Blocka7e24c12009-10-30 11:49:00 +00003317 return key->IsMatch(value);
3318 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003319
Steve Block44f0eee2011-05-26 01:26:41 +01003320 static inline uint32_t Hash(HashTableKey* key) {
Steve Blocka7e24c12009-10-30 11:49:00 +00003321 return key->Hash();
3322 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003323
Steve Block44f0eee2011-05-26 01:26:41 +01003324 static inline uint32_t HashForObject(HashTableKey* key, Object* object) {
Steve Blocka7e24c12009-10-30 11:49:00 +00003325 return key->HashForObject(object);
3326 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003327
3328 static inline Handle<Object> AsHandle(Isolate* isolate, HashTableKey* key);
Steve Blocka7e24c12009-10-30 11:49:00 +00003329
3330 static const int kPrefixSize = 0;
3331 static const int kEntrySize = 1;
3332};
3333
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003334class SeqOneByteString;
Ben Murdoch257744e2011-11-30 15:57:28 +00003335
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003336// StringTable.
Steve Blocka7e24c12009-10-30 11:49:00 +00003337//
3338// No special elements in the prefix and the element size is 1
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003339// because only the string itself (the key) needs to be stored.
3340class StringTable: public HashTable<StringTable,
3341 StringTableShape,
3342 HashTableKey*> {
Steve Blocka7e24c12009-10-30 11:49:00 +00003343 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003344 // Find string in the string table. If it is not there yet, it is
3345 // added. The return value is the string found.
3346 static Handle<String> LookupString(Isolate* isolate, Handle<String> key);
3347 static Handle<String> LookupKey(Isolate* isolate, HashTableKey* key);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003348 static String* LookupKeyIfExists(Isolate* isolate, HashTableKey* key);
Steve Blocka7e24c12009-10-30 11:49:00 +00003349
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003350 // Tries to internalize given string and returns string handle on success
3351 // or an empty handle otherwise.
3352 MUST_USE_RESULT static MaybeHandle<String> InternalizeStringIfExists(
3353 Isolate* isolate,
3354 Handle<String> string);
Steve Blocka7e24c12009-10-30 11:49:00 +00003355
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003356 // Looks up a string that is equal to the given string and returns
3357 // string handle if it is found, or an empty handle otherwise.
3358 MUST_USE_RESULT static MaybeHandle<String> LookupStringIfExists(
3359 Isolate* isolate,
3360 Handle<String> str);
3361 MUST_USE_RESULT static MaybeHandle<String> LookupTwoCharsStringIfExists(
3362 Isolate* isolate,
3363 uint16_t c1,
3364 uint16_t c2);
3365
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003366 static void EnsureCapacityForDeserialization(Isolate* isolate, int expected);
3367
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003368 DECLARE_CAST(StringTable)
Steve Blocka7e24c12009-10-30 11:49:00 +00003369
3370 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003371 template <bool seq_one_byte>
3372 friend class JsonParser;
Steve Blocka7e24c12009-10-30 11:49:00 +00003373
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003374 DISALLOW_IMPLICIT_CONSTRUCTORS(StringTable);
Steve Blocka7e24c12009-10-30 11:49:00 +00003375};
3376
Ben Murdochda12d292016-06-02 14:46:10 +01003377class StringSetShape : public BaseShape<String*> {
3378 public:
3379 static inline bool IsMatch(String* key, Object* value);
3380 static inline uint32_t Hash(String* key);
3381 static inline uint32_t HashForObject(String* key, Object* object);
3382
3383 static const int kPrefixSize = 0;
3384 static const int kEntrySize = 1;
3385};
3386
3387class StringSet : public HashTable<StringSet, StringSetShape, String*> {
3388 public:
3389 static Handle<StringSet> New(Isolate* isolate);
3390 static Handle<StringSet> Add(Handle<StringSet> blacklist,
3391 Handle<String> name);
3392 bool Has(Handle<String> name);
3393
3394 DECLARE_CAST(StringSet)
3395};
Steve Blocka7e24c12009-10-30 11:49:00 +00003396
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003397template <typename Derived, typename Shape, typename Key>
3398class Dictionary: public HashTable<Derived, Shape, Key> {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003399 typedef HashTable<Derived, Shape, Key> DerivedHashTable;
Steve Blocka7e24c12009-10-30 11:49:00 +00003400
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003401 public:
Steve Blocka7e24c12009-10-30 11:49:00 +00003402 // Returns the value at entry.
3403 Object* ValueAt(int entry) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003404 return this->get(Derived::EntryToIndex(entry) + 1);
Steve Blocka7e24c12009-10-30 11:49:00 +00003405 }
3406
3407 // Set the value for entry.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003408 void ValueAtPut(int entry, Object* value) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003409 this->set(Derived::EntryToIndex(entry) + 1, value);
Steve Blocka7e24c12009-10-30 11:49:00 +00003410 }
3411
3412 // Returns the property details for the property at entry.
3413 PropertyDetails DetailsAt(int entry) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003414 return Shape::DetailsAt(static_cast<Derived*>(this), entry);
Steve Blocka7e24c12009-10-30 11:49:00 +00003415 }
3416
3417 // Set the details for entry.
3418 void DetailsAtPut(int entry, PropertyDetails value) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003419 Shape::DetailsAtPut(static_cast<Derived*>(this), entry, value);
Steve Blocka7e24c12009-10-30 11:49:00 +00003420 }
3421
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003422 // Returns true if property at given entry is deleted.
3423 bool IsDeleted(int entry) {
3424 return Shape::IsDeleted(static_cast<Derived*>(this), entry);
3425 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003426
3427 // Delete a property from the dictionary.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003428 static Handle<Object> DeleteProperty(Handle<Derived> dictionary, int entry);
Steve Blocka7e24c12009-10-30 11:49:00 +00003429
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003430 // Attempt to shrink the dictionary after deletion of key.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003431 MUST_USE_RESULT static inline Handle<Derived> Shrink(
3432 Handle<Derived> dictionary,
3433 Key key) {
3434 return DerivedHashTable::Shrink(dictionary, key);
3435 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003436
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003437 // Sorting support
3438 // TODO(dcarney): templatize or move to SeededNumberDictionary
3439 void CopyValuesTo(FixedArray* elements);
3440
Steve Blocka7e24c12009-10-30 11:49:00 +00003441 // Returns the number of elements in the dictionary filtering out properties
3442 // with the specified attributes.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003443 int NumberOfElementsFilterAttributes(PropertyFilter filter);
Steve Blocka7e24c12009-10-30 11:49:00 +00003444
3445 // Returns the number of enumerable elements in the dictionary.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003446 int NumberOfEnumElements() {
3447 return NumberOfElementsFilterAttributes(ENUMERABLE_STRINGS);
3448 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003449
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003450 enum SortMode { UNSORTED, SORTED };
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003451
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003452 // Collect the keys into the given KeyAccumulator, in ascending chronological
3453 // order of property creation.
3454 static void CollectKeysTo(Handle<Dictionary<Derived, Shape, Key> > dictionary,
3455 KeyAccumulator* keys, PropertyFilter filter);
3456
3457 // Copies enumerable keys to preallocated fixed array.
3458 void CopyEnumKeysTo(FixedArray* storage);
Steve Blocka7e24c12009-10-30 11:49:00 +00003459
3460 // Accessors for next enumeration index.
3461 void SetNextEnumerationIndex(int index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003462 DCHECK(index != 0);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003463 this->set(kNextEnumerationIndexIndex, Smi::FromInt(index));
Steve Blocka7e24c12009-10-30 11:49:00 +00003464 }
3465
3466 int NextEnumerationIndex() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003467 return Smi::cast(this->get(kNextEnumerationIndexIndex))->value();
Steve Blocka7e24c12009-10-30 11:49:00 +00003468 }
3469
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003470 // Creates a new dictionary.
3471 MUST_USE_RESULT static Handle<Derived> New(
3472 Isolate* isolate,
3473 int at_least_space_for,
3474 PretenureFlag pretenure = NOT_TENURED);
Steve Blocka7e24c12009-10-30 11:49:00 +00003475
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003476 // Ensures that a new dictionary is created when the capacity is checked.
3477 void SetRequiresCopyOnCapacityChange();
3478
Steve Blocka7e24c12009-10-30 11:49:00 +00003479 // Ensure enough space for n additional elements.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003480 static Handle<Derived> EnsureCapacity(Handle<Derived> obj, int n, Key key);
Steve Blocka7e24c12009-10-30 11:49:00 +00003481
Ben Murdochb0fe1622011-05-05 13:52:32 +01003482#ifdef OBJECT_PRINT
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003483 void Print(std::ostream& os); // NOLINT
Steve Blocka7e24c12009-10-30 11:49:00 +00003484#endif
3485 // Returns the key (slow).
3486 Object* SlowReverseLookup(Object* value);
3487
3488 // Sets the entry to (key, value) pair.
3489 inline void SetEntry(int entry,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003490 Handle<Object> key,
3491 Handle<Object> value);
Ben Murdoch8b112d22011-06-08 16:22:53 +01003492 inline void SetEntry(int entry,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003493 Handle<Object> key,
3494 Handle<Object> value,
Steve Blocka7e24c12009-10-30 11:49:00 +00003495 PropertyDetails details);
3496
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003497 MUST_USE_RESULT static Handle<Derived> Add(
3498 Handle<Derived> dictionary,
3499 Key key,
3500 Handle<Object> value,
3501 PropertyDetails details);
Steve Blocka7e24c12009-10-30 11:49:00 +00003502
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003503 // Returns iteration indices array for the |dictionary|.
3504 // Values are direct indices in the |HashTable| array.
3505 static Handle<FixedArray> BuildIterationIndicesArray(
3506 Handle<Derived> dictionary);
3507
Steve Blocka7e24c12009-10-30 11:49:00 +00003508 protected:
3509 // Generic at put operation.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003510 MUST_USE_RESULT static Handle<Derived> AtPut(
3511 Handle<Derived> dictionary,
3512 Key key,
3513 Handle<Object> value);
Steve Blocka7e24c12009-10-30 11:49:00 +00003514
3515 // Add entry to dictionary.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003516 static void AddEntry(
3517 Handle<Derived> dictionary,
3518 Key key,
3519 Handle<Object> value,
3520 PropertyDetails details,
3521 uint32_t hash);
Steve Blocka7e24c12009-10-30 11:49:00 +00003522
3523 // Generate new enumeration indices to avoid enumeration index overflow.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003524 // Returns iteration indices array for the |dictionary|.
3525 static Handle<FixedArray> GenerateNewEnumerationIndices(
3526 Handle<Derived> dictionary);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003527 static const int kMaxNumberKeyIndex = DerivedHashTable::kPrefixStartIndex;
Steve Blocka7e24c12009-10-30 11:49:00 +00003528 static const int kNextEnumerationIndexIndex = kMaxNumberKeyIndex + 1;
3529};
3530
3531
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003532template <typename Derived, typename Shape>
3533class NameDictionaryBase : public Dictionary<Derived, Shape, Handle<Name> > {
3534 typedef Dictionary<Derived, Shape, Handle<Name> > DerivedDictionary;
3535
3536 public:
3537 // Find entry for key, otherwise return kNotFound. Optimized version of
3538 // HashTable::FindEntry.
3539 int FindEntry(Handle<Name> key);
3540};
3541
3542
3543template <typename Key>
3544class BaseDictionaryShape : public BaseShape<Key> {
3545 public:
3546 template <typename Dictionary>
3547 static inline PropertyDetails DetailsAt(Dictionary* dict, int entry) {
3548 STATIC_ASSERT(Dictionary::kEntrySize == 3);
3549 DCHECK(entry >= 0); // Not found is -1, which is not caught by get().
3550 return PropertyDetails(
3551 Smi::cast(dict->get(Dictionary::EntryToIndex(entry) + 2)));
3552 }
3553
3554 template <typename Dictionary>
3555 static inline void DetailsAtPut(Dictionary* dict, int entry,
3556 PropertyDetails value) {
3557 STATIC_ASSERT(Dictionary::kEntrySize == 3);
3558 dict->set(Dictionary::EntryToIndex(entry) + 2, value.AsSmi());
3559 }
3560
3561 template <typename Dictionary>
3562 static bool IsDeleted(Dictionary* dict, int entry) {
3563 return false;
3564 }
3565
3566 template <typename Dictionary>
3567 static inline void SetEntry(Dictionary* dict, int entry, Handle<Object> key,
3568 Handle<Object> value, PropertyDetails details);
3569};
3570
3571
3572class NameDictionaryShape : public BaseDictionaryShape<Handle<Name> > {
Steve Blocka7e24c12009-10-30 11:49:00 +00003573 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003574 static inline bool IsMatch(Handle<Name> key, Object* other);
3575 static inline uint32_t Hash(Handle<Name> key);
3576 static inline uint32_t HashForObject(Handle<Name> key, Object* object);
3577 static inline Handle<Object> AsHandle(Isolate* isolate, Handle<Name> key);
Steve Blocka7e24c12009-10-30 11:49:00 +00003578 static const int kPrefixSize = 2;
3579 static const int kEntrySize = 3;
3580 static const bool kIsEnumerable = true;
3581};
3582
3583
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003584class NameDictionary
3585 : public NameDictionaryBase<NameDictionary, NameDictionaryShape> {
3586 typedef NameDictionaryBase<NameDictionary, NameDictionaryShape>
3587 DerivedDictionary;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003588
Steve Blocka7e24c12009-10-30 11:49:00 +00003589 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003590 DECLARE_CAST(NameDictionary)
Steve Blocka7e24c12009-10-30 11:49:00 +00003591
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003592 inline static Handle<FixedArray> DoGenerateNewEnumerationIndices(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003593 Handle<NameDictionary> dictionary);
Steve Blocka7e24c12009-10-30 11:49:00 +00003594};
3595
3596
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003597class GlobalDictionaryShape : public NameDictionaryShape {
3598 public:
3599 static const int kEntrySize = 2; // Overrides NameDictionaryShape::kEntrySize
3600
3601 template <typename Dictionary>
3602 static inline PropertyDetails DetailsAt(Dictionary* dict, int entry);
3603
3604 template <typename Dictionary>
3605 static inline void DetailsAtPut(Dictionary* dict, int entry,
3606 PropertyDetails value);
3607
3608 template <typename Dictionary>
3609 static bool IsDeleted(Dictionary* dict, int entry);
3610
3611 template <typename Dictionary>
3612 static inline void SetEntry(Dictionary* dict, int entry, Handle<Object> key,
3613 Handle<Object> value, PropertyDetails details);
3614};
3615
3616
3617class GlobalDictionary
3618 : public NameDictionaryBase<GlobalDictionary, GlobalDictionaryShape> {
3619 public:
3620 DECLARE_CAST(GlobalDictionary)
3621};
3622
3623
3624class NumberDictionaryShape : public BaseDictionaryShape<uint32_t> {
Steve Blocka7e24c12009-10-30 11:49:00 +00003625 public:
3626 static inline bool IsMatch(uint32_t key, Object* other);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003627 static inline Handle<Object> AsHandle(Isolate* isolate, uint32_t key);
Steve Blocka7e24c12009-10-30 11:49:00 +00003628 static const int kEntrySize = 3;
3629 static const bool kIsEnumerable = false;
3630};
3631
3632
Ben Murdochc7cc0282012-03-05 14:35:55 +00003633class SeededNumberDictionaryShape : public NumberDictionaryShape {
Steve Blocka7e24c12009-10-30 11:49:00 +00003634 public:
Ben Murdochc7cc0282012-03-05 14:35:55 +00003635 static const bool UsesSeed = true;
3636 static const int kPrefixSize = 2;
3637
3638 static inline uint32_t SeededHash(uint32_t key, uint32_t seed);
3639 static inline uint32_t SeededHashForObject(uint32_t key,
3640 uint32_t seed,
3641 Object* object);
3642};
3643
3644
3645class UnseededNumberDictionaryShape : public NumberDictionaryShape {
3646 public:
3647 static const int kPrefixSize = 0;
3648
3649 static inline uint32_t Hash(uint32_t key);
3650 static inline uint32_t HashForObject(uint32_t key, Object* object);
3651};
3652
3653
3654class SeededNumberDictionary
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003655 : public Dictionary<SeededNumberDictionary,
3656 SeededNumberDictionaryShape,
3657 uint32_t> {
Ben Murdochc7cc0282012-03-05 14:35:55 +00003658 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003659 DECLARE_CAST(SeededNumberDictionary)
Steve Blocka7e24c12009-10-30 11:49:00 +00003660
3661 // Type specific at put (default NONE attributes is used when adding).
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003662 MUST_USE_RESULT static Handle<SeededNumberDictionary> AtNumberPut(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003663 Handle<SeededNumberDictionary> dictionary, uint32_t key,
3664 Handle<Object> value, bool used_as_prototype);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003665 MUST_USE_RESULT static Handle<SeededNumberDictionary> AddNumberEntry(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003666 Handle<SeededNumberDictionary> dictionary, uint32_t key,
3667 Handle<Object> value, PropertyDetails details, bool used_as_prototype);
Steve Blocka7e24c12009-10-30 11:49:00 +00003668
3669 // Set an existing entry or add a new one if needed.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003670 // Return the updated dictionary.
3671 MUST_USE_RESULT static Handle<SeededNumberDictionary> Set(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003672 Handle<SeededNumberDictionary> dictionary, uint32_t key,
3673 Handle<Object> value, PropertyDetails details, bool used_as_prototype);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003674
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003675 void UpdateMaxNumberKey(uint32_t key, bool used_as_prototype);
Steve Blocka7e24c12009-10-30 11:49:00 +00003676
Ben Murdochda12d292016-06-02 14:46:10 +01003677 // Returns true if the dictionary contains any elements that are non-writable,
3678 // non-configurable, non-enumerable, or have getters/setters.
3679 bool HasComplexElements();
3680
Steve Blocka7e24c12009-10-30 11:49:00 +00003681 // If slow elements are required we will never go back to fast-case
3682 // for the elements kept in this dictionary. We require slow
3683 // elements if an element has been added at an index larger than
3684 // kRequiresSlowElementsLimit or set_requires_slow_elements() has been called
3685 // when defining a getter or setter with a number key.
3686 inline bool requires_slow_elements();
3687 inline void set_requires_slow_elements();
3688
3689 // Get the value of the max number key that has been added to this
3690 // dictionary. max_number_key can only be called if
3691 // requires_slow_elements returns false.
3692 inline uint32_t max_number_key();
3693
Steve Blocka7e24c12009-10-30 11:49:00 +00003694 // Bit masks.
3695 static const int kRequiresSlowElementsMask = 1;
3696 static const int kRequiresSlowElementsTagSize = 1;
3697 static const uint32_t kRequiresSlowElementsLimit = (1 << 29) - 1;
3698};
3699
3700
Ben Murdochc7cc0282012-03-05 14:35:55 +00003701class UnseededNumberDictionary
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003702 : public Dictionary<UnseededNumberDictionary,
3703 UnseededNumberDictionaryShape,
3704 uint32_t> {
Ben Murdochc7cc0282012-03-05 14:35:55 +00003705 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003706 DECLARE_CAST(UnseededNumberDictionary)
Ben Murdochc7cc0282012-03-05 14:35:55 +00003707
3708 // Type specific at put (default NONE attributes is used when adding).
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003709 MUST_USE_RESULT static Handle<UnseededNumberDictionary> AtNumberPut(
3710 Handle<UnseededNumberDictionary> dictionary,
3711 uint32_t key,
3712 Handle<Object> value);
3713 MUST_USE_RESULT static Handle<UnseededNumberDictionary> AddNumberEntry(
3714 Handle<UnseededNumberDictionary> dictionary,
3715 uint32_t key,
3716 Handle<Object> value);
Ben Murdochc7cc0282012-03-05 14:35:55 +00003717
3718 // Set an existing entry or add a new one if needed.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003719 // Return the updated dictionary.
3720 MUST_USE_RESULT static Handle<UnseededNumberDictionary> Set(
3721 Handle<UnseededNumberDictionary> dictionary,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003722 uint32_t key,
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003723 Handle<Object> value);
Ben Murdochc7cc0282012-03-05 14:35:55 +00003724};
3725
3726
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003727class ObjectHashTableShape : public BaseShape<Handle<Object> > {
Ben Murdoch2b4ba112012-01-20 14:57:15 +00003728 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003729 static inline bool IsMatch(Handle<Object> key, Object* other);
3730 static inline uint32_t Hash(Handle<Object> key);
3731 static inline uint32_t HashForObject(Handle<Object> key, Object* object);
3732 static inline Handle<Object> AsHandle(Isolate* isolate, Handle<Object> key);
Ben Murdoch592a9fc2012-03-05 11:04:45 +00003733 static const int kPrefixSize = 0;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003734 static const int kEntrySize = 2;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003735};
3736
3737
3738// ObjectHashTable maps keys that are arbitrary objects to object values by
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003739// using the identity hash of the key for hashing purposes.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003740class ObjectHashTable: public HashTable<ObjectHashTable,
3741 ObjectHashTableShape,
3742 Handle<Object> > {
3743 typedef HashTable<
3744 ObjectHashTable, ObjectHashTableShape, Handle<Object> > DerivedHashTable;
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003745 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003746 DECLARE_CAST(ObjectHashTable)
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003747
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003748 // Attempt to shrink hash table after removal of key.
3749 MUST_USE_RESULT static inline Handle<ObjectHashTable> Shrink(
3750 Handle<ObjectHashTable> table,
3751 Handle<Object> key);
3752
3753 // Looks up the value associated with the given key. The hole value is
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003754 // returned in case the key is not present.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003755 Object* Lookup(Handle<Object> key);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003756 Object* Lookup(Handle<Object> key, int32_t hash);
3757 Object* Lookup(Isolate* isolate, Handle<Object> key, int32_t hash);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003758
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003759 // Adds (or overwrites) the value associated with the given key.
3760 static Handle<ObjectHashTable> Put(Handle<ObjectHashTable> table,
3761 Handle<Object> key,
3762 Handle<Object> value);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003763 static Handle<ObjectHashTable> Put(Handle<ObjectHashTable> table,
3764 Handle<Object> key, Handle<Object> value,
3765 int32_t hash);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003766
3767 // Returns an ObjectHashTable (possibly |table|) where |key| has been removed.
3768 static Handle<ObjectHashTable> Remove(Handle<ObjectHashTable> table,
3769 Handle<Object> key,
3770 bool* was_present);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003771 static Handle<ObjectHashTable> Remove(Handle<ObjectHashTable> table,
3772 Handle<Object> key, bool* was_present,
3773 int32_t hash);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003774
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003775 protected:
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003776 friend class MarkCompactCollector;
3777
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003778 void AddEntry(int entry, Object* key, Object* value);
3779 void RemoveEntry(int entry);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003780
3781 // Returns the index to the value of an entry.
3782 static inline int EntryToValueIndex(int entry) {
3783 return EntryToIndex(entry) + 1;
3784 }
3785};
3786
3787
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003788// OrderedHashTable is a HashTable with Object keys that preserves
3789// insertion order. There are Map and Set interfaces (OrderedHashMap
3790// and OrderedHashTable, below). It is meant to be used by JSMap/JSSet.
3791//
3792// Only Object* keys are supported, with Object::SameValueZero() used as the
3793// equality operator and Object::GetHash() for the hash function.
3794//
3795// Based on the "Deterministic Hash Table" as described by Jason Orendorff at
3796// https://wiki.mozilla.org/User:Jorend/Deterministic_hash_tables
3797// Originally attributed to Tyler Close.
3798//
3799// Memory layout:
3800// [0]: bucket count
3801// [1]: element count
3802// [2]: deleted element count
3803// [3..(3 + NumberOfBuckets() - 1)]: "hash table", where each item is an
3804// offset into the data table (see below) where the
3805// first item in this bucket is stored.
3806// [3 + NumberOfBuckets()..length]: "data table", an array of length
3807// Capacity() * kEntrySize, where the first entrysize
3808// items are handled by the derived class and the
3809// item at kChainOffset is another entry into the
3810// data table indicating the next entry in this hash
3811// bucket.
3812//
3813// When we transition the table to a new version we obsolete it and reuse parts
3814// of the memory to store information how to transition an iterator to the new
3815// table:
3816//
3817// Memory layout for obsolete table:
3818// [0]: bucket count
3819// [1]: Next newer table
3820// [2]: Number of removed holes or -1 when the table was cleared.
3821// [3..(3 + NumberOfRemovedHoles() - 1)]: The indexes of the removed holes.
3822// [3 + NumberOfRemovedHoles()..length]: Not used
3823//
3824template<class Derived, class Iterator, int entrysize>
3825class OrderedHashTable: public FixedArray {
3826 public:
3827 // Returns an OrderedHashTable with a capacity of at least |capacity|.
3828 static Handle<Derived> Allocate(
3829 Isolate* isolate, int capacity, PretenureFlag pretenure = NOT_TENURED);
3830
3831 // Returns an OrderedHashTable (possibly |table|) with enough space
3832 // to add at least one new element.
3833 static Handle<Derived> EnsureGrowable(Handle<Derived> table);
3834
3835 // Returns an OrderedHashTable (possibly |table|) that's shrunken
3836 // if possible.
3837 static Handle<Derived> Shrink(Handle<Derived> table);
3838
3839 // Returns a new empty OrderedHashTable and records the clearing so that
Ben Murdochc5610432016-08-08 18:44:38 +01003840 // existing iterators can be updated.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003841 static Handle<Derived> Clear(Handle<Derived> table);
3842
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003843 // Returns a true if the OrderedHashTable contains the key
3844 static bool HasKey(Handle<Derived> table, Handle<Object> key);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003845
3846 int NumberOfElements() {
3847 return Smi::cast(get(kNumberOfElementsIndex))->value();
3848 }
3849
3850 int NumberOfDeletedElements() {
3851 return Smi::cast(get(kNumberOfDeletedElementsIndex))->value();
3852 }
3853
Ben Murdochc5610432016-08-08 18:44:38 +01003854 // Returns the number of contiguous entries in the data table, starting at 0,
3855 // that either are real entries or have been deleted.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003856 int UsedCapacity() { return NumberOfElements() + NumberOfDeletedElements(); }
3857
3858 int NumberOfBuckets() {
3859 return Smi::cast(get(kNumberOfBucketsIndex))->value();
3860 }
3861
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003862 // Returns an index into |this| for the given entry.
3863 int EntryToIndex(int entry) {
3864 return kHashTableStartIndex + NumberOfBuckets() + (entry * kEntrySize);
3865 }
3866
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003867 int HashToBucket(int hash) { return hash & (NumberOfBuckets() - 1); }
3868
3869 int HashToEntry(int hash) {
3870 int bucket = HashToBucket(hash);
3871 Object* entry = this->get(kHashTableStartIndex + bucket);
3872 return Smi::cast(entry)->value();
3873 }
3874
3875 int KeyToFirstEntry(Object* key) {
3876 Object* hash = key->GetHash();
3877 // If the object does not have an identity hash, it was never used as a key
3878 if (hash->IsUndefined()) return kNotFound;
3879 return HashToEntry(Smi::cast(hash)->value());
3880 }
3881
3882 int NextChainEntry(int entry) {
3883 Object* next_entry = get(EntryToIndex(entry) + kChainOffset);
3884 return Smi::cast(next_entry)->value();
3885 }
3886
Ben Murdochc5610432016-08-08 18:44:38 +01003887 // use KeyAt(i)->IsTheHole() to determine if this is a deleted entry.
3888 Object* KeyAt(int entry) {
3889 DCHECK_LT(entry, this->UsedCapacity());
3890 return get(EntryToIndex(entry));
3891 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003892
3893 bool IsObsolete() {
3894 return !get(kNextTableIndex)->IsSmi();
3895 }
3896
3897 // The next newer table. This is only valid if the table is obsolete.
3898 Derived* NextTable() {
3899 return Derived::cast(get(kNextTableIndex));
3900 }
3901
3902 // When the table is obsolete we store the indexes of the removed holes.
3903 int RemovedIndexAt(int index) {
3904 return Smi::cast(get(kRemovedHolesIndex + index))->value();
3905 }
3906
3907 static const int kNotFound = -1;
3908 static const int kMinCapacity = 4;
3909
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003910 static const int kNumberOfBucketsIndex = 0;
3911 static const int kNumberOfElementsIndex = kNumberOfBucketsIndex + 1;
3912 static const int kNumberOfDeletedElementsIndex = kNumberOfElementsIndex + 1;
3913 static const int kHashTableStartIndex = kNumberOfDeletedElementsIndex + 1;
3914 static const int kNextTableIndex = kNumberOfElementsIndex;
3915
3916 static const int kNumberOfBucketsOffset =
3917 kHeaderSize + kNumberOfBucketsIndex * kPointerSize;
3918 static const int kNumberOfElementsOffset =
3919 kHeaderSize + kNumberOfElementsIndex * kPointerSize;
3920 static const int kNumberOfDeletedElementsOffset =
3921 kHeaderSize + kNumberOfDeletedElementsIndex * kPointerSize;
3922 static const int kHashTableStartOffset =
3923 kHeaderSize + kHashTableStartIndex * kPointerSize;
3924 static const int kNextTableOffset =
3925 kHeaderSize + kNextTableIndex * kPointerSize;
3926
3927 static const int kEntrySize = entrysize + 1;
3928 static const int kChainOffset = entrysize;
3929
3930 static const int kLoadFactor = 2;
3931
3932 // NumberOfDeletedElements is set to kClearedTableSentinel when
3933 // the table is cleared, which allows iterator transitions to
3934 // optimize that case.
3935 static const int kClearedTableSentinel = -1;
3936
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003937 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003938 static Handle<Derived> Rehash(Handle<Derived> table, int new_capacity);
3939
3940 void SetNumberOfBuckets(int num) {
3941 set(kNumberOfBucketsIndex, Smi::FromInt(num));
3942 }
3943
3944 void SetNumberOfElements(int num) {
3945 set(kNumberOfElementsIndex, Smi::FromInt(num));
3946 }
3947
3948 void SetNumberOfDeletedElements(int num) {
3949 set(kNumberOfDeletedElementsIndex, Smi::FromInt(num));
3950 }
3951
Ben Murdochc5610432016-08-08 18:44:38 +01003952 // Returns the number elements that can fit into the allocated buffer.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003953 int Capacity() {
3954 return NumberOfBuckets() * kLoadFactor;
3955 }
3956
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003957 void SetNextTable(Derived* next_table) {
3958 set(kNextTableIndex, next_table);
3959 }
3960
3961 void SetRemovedIndexAt(int index, int removed_index) {
3962 return set(kRemovedHolesIndex + index, Smi::FromInt(removed_index));
3963 }
3964
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003965 static const int kRemovedHolesIndex = kHashTableStartIndex;
3966
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003967 static const int kMaxCapacity =
3968 (FixedArray::kMaxLength - kHashTableStartIndex)
3969 / (1 + (kEntrySize * kLoadFactor));
3970};
3971
3972
3973class JSSetIterator;
3974
3975
3976class OrderedHashSet: public OrderedHashTable<
3977 OrderedHashSet, JSSetIterator, 1> {
3978 public:
3979 DECLARE_CAST(OrderedHashSet)
3980
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003981 static Handle<OrderedHashSet> Add(Handle<OrderedHashSet> table,
3982 Handle<Object> value);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003983};
3984
3985
3986class JSMapIterator;
3987
3988
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003989class OrderedHashMap
3990 : public OrderedHashTable<OrderedHashMap, JSMapIterator, 2> {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003991 public:
3992 DECLARE_CAST(OrderedHashMap)
3993
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003994 inline Object* ValueAt(int entry);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003995
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003996 static const int kValueOffset = 1;
3997};
3998
3999
4000template <int entrysize>
4001class WeakHashTableShape : public BaseShape<Handle<Object> > {
4002 public:
4003 static inline bool IsMatch(Handle<Object> key, Object* other);
4004 static inline uint32_t Hash(Handle<Object> key);
4005 static inline uint32_t HashForObject(Handle<Object> key, Object* object);
4006 static inline Handle<Object> AsHandle(Isolate* isolate, Handle<Object> key);
4007 static const int kPrefixSize = 0;
4008 static const int kEntrySize = entrysize;
4009};
4010
4011
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004012// WeakHashTable maps keys that are arbitrary heap objects to heap object
4013// values. The table wraps the keys in weak cells and store values directly.
4014// Thus it references keys weakly and values strongly.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004015class WeakHashTable: public HashTable<WeakHashTable,
4016 WeakHashTableShape<2>,
4017 Handle<Object> > {
4018 typedef HashTable<
4019 WeakHashTable, WeakHashTableShape<2>, Handle<Object> > DerivedHashTable;
4020 public:
4021 DECLARE_CAST(WeakHashTable)
4022
4023 // Looks up the value associated with the given key. The hole value is
4024 // returned in case the key is not present.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004025 Object* Lookup(Handle<HeapObject> key);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004026
4027 // Adds (or overwrites) the value associated with the given key. Mapping a
4028 // key to the hole value causes removal of the whole entry.
4029 MUST_USE_RESULT static Handle<WeakHashTable> Put(Handle<WeakHashTable> table,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004030 Handle<HeapObject> key,
4031 Handle<HeapObject> value);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004032
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004033 static Handle<FixedArray> GetValues(Handle<WeakHashTable> table);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004034
4035 private:
4036 friend class MarkCompactCollector;
4037
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004038 void AddEntry(int entry, Handle<WeakCell> key, Handle<HeapObject> value);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004039
4040 // Returns the index to the value of an entry.
4041 static inline int EntryToValueIndex(int entry) {
4042 return EntryToIndex(entry) + 1;
4043 }
4044};
4045
4046
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004047// ScopeInfo represents information about different scopes of a source
4048// program and the allocation of the scope's variables. Scope information
4049// is stored in a compressed form in ScopeInfo objects and is used
4050// at runtime (stack dumps, deoptimization, etc.).
4051
4052// This object provides quick access to scope info details for runtime
4053// routines.
4054class ScopeInfo : public FixedArray {
4055 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004056 DECLARE_CAST(ScopeInfo)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004057
4058 // Return the type of this scope.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004059 ScopeType scope_type();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004060
4061 // Does this scope call eval?
4062 bool CallsEval();
4063
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004064 // Return the language mode of this scope.
4065 LanguageMode language_mode();
4066
4067 // True if this scope is a (var) declaration scope.
4068 bool is_declaration_scope();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004069
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004070 // Does this scope make a sloppy eval call?
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004071 bool CallsSloppyEval() { return CallsEval() && is_sloppy(language_mode()); }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004072
4073 // Return the total number of locals allocated on the stack and in the
4074 // context. This includes the parameters that are allocated in the context.
4075 int LocalCount();
4076
4077 // Return the number of stack slots for code. This number consists of two
4078 // parts:
4079 // 1. One stack slot per stack allocated local.
4080 // 2. One stack slot for the function name if it is stack allocated.
4081 int StackSlotCount();
4082
4083 // Return the number of context slots for code if a context is allocated. This
4084 // number consists of three parts:
4085 // 1. Size of fixed header for every context: Context::MIN_CONTEXT_SLOTS
4086 // 2. One context slot per context allocated local.
4087 // 3. One context slot for the function name if it is context allocated.
4088 // Parameters allocated in the context count as context allocated locals. If
4089 // no contexts are allocated for this scope ContextLength returns 0.
4090 int ContextLength();
4091
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004092 // Does this scope declare a "this" binding?
4093 bool HasReceiver();
4094
4095 // Does this scope declare a "this" binding, and the "this" binding is stack-
4096 // or context-allocated?
4097 bool HasAllocatedReceiver();
4098
4099 // Does this scope declare a "new.target" binding?
4100 bool HasNewTarget();
4101
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004102 // Is this scope the scope of a named function expression?
4103 bool HasFunctionName();
4104
4105 // Return if this has context allocated locals.
4106 bool HasHeapAllocatedLocals();
4107
4108 // Return if contexts are allocated for this scope.
4109 bool HasContext();
4110
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004111 // Return if this is a function scope with "use asm".
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004112 inline bool IsAsmModule();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004113
4114 // Return if this is a nested function within an asm module scope.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004115 inline bool IsAsmFunction();
4116
4117 inline bool HasSimpleParameters();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004118
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004119 // Return the function_name if present.
4120 String* FunctionName();
4121
4122 // Return the name of the given parameter.
4123 String* ParameterName(int var);
4124
4125 // Return the name of the given local.
4126 String* LocalName(int var);
4127
4128 // Return the name of the given stack local.
4129 String* StackLocalName(int var);
4130
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004131 // Return the name of the given stack local.
4132 int StackLocalIndex(int var);
4133
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004134 // Return the name of the given context local.
4135 String* ContextLocalName(int var);
4136
4137 // Return the mode of the given context local.
4138 VariableMode ContextLocalMode(int var);
4139
4140 // Return the initialization flag of the given context local.
4141 InitializationFlag ContextLocalInitFlag(int var);
4142
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004143 // Return the initialization flag of the given context local.
4144 MaybeAssignedFlag ContextLocalMaybeAssignedFlag(int var);
4145
4146 // Return true if this local was introduced by the compiler, and should not be
4147 // exposed to the user in a debugger.
Ben Murdochc5610432016-08-08 18:44:38 +01004148 static bool VariableIsSynthetic(String* name);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004149
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004150 // Lookup support for serialized scope info. Returns the
4151 // the stack slot index for a given slot name if the slot is
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004152 // present; otherwise returns a value < 0. The name must be an internalized
4153 // string.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004154 int StackSlotIndex(String* name);
4155
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004156 // Lookup support for serialized scope info. Returns the local context slot
4157 // index for a given slot name if the slot is present; otherwise
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004158 // returns a value < 0. The name must be an internalized string.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004159 // If the slot is present and mode != NULL, sets *mode to the corresponding
4160 // mode for that variable.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004161 static int ContextSlotIndex(Handle<ScopeInfo> scope_info, Handle<String> name,
4162 VariableMode* mode, InitializationFlag* init_flag,
4163 MaybeAssignedFlag* maybe_assigned_flag);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004164
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004165 // Similar to ContextSlotIndex() but this method searches only among
4166 // global slots of the serialized scope info. Returns the context slot index
4167 // for a given slot name if the slot is present; otherwise returns a
4168 // value < 0. The name must be an internalized string. If the slot is present
4169 // and mode != NULL, sets *mode to the corresponding mode for that variable.
4170 static int ContextGlobalSlotIndex(Handle<ScopeInfo> scope_info,
4171 Handle<String> name, VariableMode* mode,
4172 InitializationFlag* init_flag,
4173 MaybeAssignedFlag* maybe_assigned_flag);
4174
4175 // Lookup the name of a certain context slot by its index.
4176 String* ContextSlotName(int slot_index);
4177
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004178 // Lookup support for serialized scope info. Returns the
4179 // parameter index for a given parameter name if the parameter is present;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004180 // otherwise returns a value < 0. The name must be an internalized string.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004181 int ParameterIndex(String* name);
4182
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004183 // Lookup support for serialized scope info. Returns the function context
4184 // slot index if the function name is present and context-allocated (named
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004185 // function expressions, only), otherwise returns a value < 0. The name
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004186 // must be an internalized string.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004187 int FunctionContextSlotIndex(String* name, VariableMode* mode);
4188
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004189 // Lookup support for serialized scope info. Returns the receiver context
4190 // slot index if scope has a "this" binding, and the binding is
4191 // context-allocated. Otherwise returns a value < 0.
4192 int ReceiverContextSlotIndex();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004193
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004194 FunctionKind function_kind();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004195
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004196 static Handle<ScopeInfo> Create(Isolate* isolate, Zone* zone, Scope* scope);
4197 static Handle<ScopeInfo> CreateGlobalThisBinding(Isolate* isolate);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004198
4199 // Serializes empty scope info.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004200 static ScopeInfo* Empty(Isolate* isolate);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004201
4202#ifdef DEBUG
4203 void Print();
4204#endif
4205
4206 // The layout of the static part of a ScopeInfo is as follows. Each entry is
4207 // numeric and occupies one array slot.
4208 // 1. A set of properties of the scope
4209 // 2. The number of parameters. This only applies to function scopes. For
4210 // non-function scopes this is 0.
4211 // 3. The number of non-parameter variables allocated on the stack.
4212 // 4. The number of non-parameter and parameter variables allocated in the
4213 // context.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004214#define FOR_EACH_SCOPE_INFO_NUMERIC_FIELD(V) \
4215 V(Flags) \
4216 V(ParameterCount) \
4217 V(StackLocalCount) \
4218 V(ContextLocalCount) \
Ben Murdoch097c5b22016-05-18 11:27:45 +01004219 V(ContextGlobalCount)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004220
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004221#define FIELD_ACCESSORS(name) \
4222 inline void Set##name(int value); \
4223 inline int name();
4224 FOR_EACH_SCOPE_INFO_NUMERIC_FIELD(FIELD_ACCESSORS)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004225#undef FIELD_ACCESSORS
4226
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004227 enum {
4228#define DECL_INDEX(name) k##name,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004229 FOR_EACH_SCOPE_INFO_NUMERIC_FIELD(DECL_INDEX)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004230#undef DECL_INDEX
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004231 kVariablePartIndex
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004232 };
4233
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004234 private:
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004235 // The layout of the variable part of a ScopeInfo is as follows:
4236 // 1. ParameterEntries:
4237 // This part stores the names of the parameters for function scopes. One
4238 // slot is used per parameter, so in total this part occupies
4239 // ParameterCount() slots in the array. For other scopes than function
4240 // scopes ParameterCount() is 0.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004241 // 2. StackLocalFirstSlot:
4242 // Index of a first stack slot for stack local. Stack locals belonging to
4243 // this scope are located on a stack at slots starting from this index.
4244 // 3. StackLocalEntries:
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004245 // Contains the names of local variables that are allocated on the stack,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004246 // in increasing order of the stack slot index. First local variable has
4247 // a stack slot index defined in StackLocalFirstSlot (point 2 above).
4248 // One slot is used per stack local, so in total this part occupies
4249 // StackLocalCount() slots in the array.
4250 // 4. ContextLocalNameEntries:
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004251 // Contains the names of local variables and parameters that are allocated
4252 // in the context. They are stored in increasing order of the context slot
4253 // index starting with Context::MIN_CONTEXT_SLOTS. One slot is used per
4254 // context local, so in total this part occupies ContextLocalCount() slots
4255 // in the array.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004256 // 5. ContextLocalInfoEntries:
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004257 // Contains the variable modes and initialization flags corresponding to
4258 // the context locals in ContextLocalNameEntries. One slot is used per
4259 // context local, so in total this part occupies ContextLocalCount()
4260 // slots in the array.
Ben Murdoch097c5b22016-05-18 11:27:45 +01004261 // 6. RecieverEntryIndex:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004262 // If the scope binds a "this" value, one slot is reserved to hold the
4263 // context or stack slot index for the variable.
Ben Murdoch097c5b22016-05-18 11:27:45 +01004264 // 7. FunctionNameEntryIndex:
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004265 // If the scope belongs to a named function expression this part contains
4266 // information about the function variable. It always occupies two array
4267 // slots: a. The name of the function variable.
4268 // b. The context or stack slot index for the variable.
4269 int ParameterEntriesIndex();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004270 int StackLocalFirstSlotIndex();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004271 int StackLocalEntriesIndex();
4272 int ContextLocalNameEntriesIndex();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004273 int ContextGlobalNameEntriesIndex();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004274 int ContextLocalInfoEntriesIndex();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004275 int ContextGlobalInfoEntriesIndex();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004276 int ReceiverEntryIndex();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004277 int FunctionNameEntryIndex();
4278
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004279 int Lookup(Handle<String> name, int start, int end, VariableMode* mode,
4280 VariableLocation* location, InitializationFlag* init_flag,
4281 MaybeAssignedFlag* maybe_assigned_flag);
4282
4283 // Used for the function name variable for named function expressions, and for
4284 // the receiver.
4285 enum VariableAllocationInfo { NONE, STACK, CONTEXT, UNUSED };
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004286
4287 // Properties of scopes.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04004288 class ScopeTypeField : public BitField<ScopeType, 0, 4> {};
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004289 class CallsEvalField : public BitField<bool, ScopeTypeField::kNext, 1> {};
4290 STATIC_ASSERT(LANGUAGE_END == 3);
4291 class LanguageModeField
4292 : public BitField<LanguageMode, CallsEvalField::kNext, 2> {};
4293 class DeclarationScopeField
4294 : public BitField<bool, LanguageModeField::kNext, 1> {};
4295 class ReceiverVariableField
4296 : public BitField<VariableAllocationInfo, DeclarationScopeField::kNext,
4297 2> {};
4298 class HasNewTargetField
4299 : public BitField<bool, ReceiverVariableField::kNext, 1> {};
4300 class FunctionVariableField
4301 : public BitField<VariableAllocationInfo, HasNewTargetField::kNext, 2> {};
4302 class FunctionVariableMode
4303 : public BitField<VariableMode, FunctionVariableField::kNext, 3> {};
4304 class AsmModuleField : public BitField<bool, FunctionVariableMode::kNext, 1> {
4305 };
4306 class AsmFunctionField : public BitField<bool, AsmModuleField::kNext, 1> {};
4307 class HasSimpleParametersField
4308 : public BitField<bool, AsmFunctionField::kNext, 1> {};
4309 class FunctionKindField
Ben Murdochc5610432016-08-08 18:44:38 +01004310 : public BitField<FunctionKind, HasSimpleParametersField::kNext, 9> {};
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004311
4312 // BitFields representing the encoded information for context locals in the
4313 // ContextLocalInfoEntries part.
4314 class ContextLocalMode: public BitField<VariableMode, 0, 3> {};
4315 class ContextLocalInitFlag: public BitField<InitializationFlag, 3, 1> {};
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004316 class ContextLocalMaybeAssignedFlag
4317 : public BitField<MaybeAssignedFlag, 4, 1> {};
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004318
4319 friend class ScopeIterator;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004320};
4321
4322
Kristian Monsen80d68ea2010-09-08 11:05:35 +01004323// The cache for maps used by normalized (dictionary mode) objects.
4324// Such maps do not have property descriptors, so a typical program
4325// needs very limited number of distinct normalized maps.
4326class NormalizedMapCache: public FixedArray {
4327 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004328 static Handle<NormalizedMapCache> New(Isolate* isolate);
Kristian Monsen80d68ea2010-09-08 11:05:35 +01004329
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004330 MUST_USE_RESULT MaybeHandle<Map> Get(Handle<Map> fast_map,
4331 PropertyNormalizationMode mode);
4332 void Set(Handle<Map> fast_map, Handle<Map> normalized_map);
Kristian Monsen80d68ea2010-09-08 11:05:35 +01004333
Kristian Monsen80d68ea2010-09-08 11:05:35 +01004334 void Clear();
4335
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004336 DECLARE_CAST(NormalizedMapCache)
Kristian Monsen80d68ea2010-09-08 11:05:35 +01004337
Ben Murdoch097c5b22016-05-18 11:27:45 +01004338 static inline bool IsNormalizedMapCache(const HeapObject* obj);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004339
4340 DECLARE_VERIFIER(NormalizedMapCache)
4341 private:
4342 static const int kEntries = 64;
4343
4344 static inline int GetIndex(Handle<Map> map);
4345
4346 // The following declarations hide base class methods.
4347 Object* get(int index);
4348 void set(int index, Object* value);
Kristian Monsen80d68ea2010-09-08 11:05:35 +01004349};
4350
4351
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004352// ByteArray represents fixed sized byte arrays. Used for the relocation info
4353// that is attached to code objects.
Ben Murdoch69a99ed2011-11-30 16:03:39 +00004354class ByteArray: public FixedArrayBase {
Steve Blocka7e24c12009-10-30 11:49:00 +00004355 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004356 inline int Size();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004357
Steve Blocka7e24c12009-10-30 11:49:00 +00004358 // Setter and getter.
4359 inline byte get(int index);
4360 inline void set(int index, byte value);
4361
Ben Murdochc5610432016-08-08 18:44:38 +01004362 // Copy in / copy out whole byte slices.
4363 inline void copy_out(int index, byte* buffer, int length);
4364 inline void copy_in(int index, const byte* buffer, int length);
4365
Steve Blocka7e24c12009-10-30 11:49:00 +00004366 // Treat contents as an int array.
4367 inline int get_int(int index);
Ben Murdochc5610432016-08-08 18:44:38 +01004368 inline void set_int(int index, int value);
Steve Blocka7e24c12009-10-30 11:49:00 +00004369
4370 static int SizeFor(int length) {
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01004371 return OBJECT_POINTER_ALIGN(kHeaderSize + length);
Steve Blocka7e24c12009-10-30 11:49:00 +00004372 }
4373 // We use byte arrays for free blocks in the heap. Given a desired size in
4374 // bytes that is a multiple of the word size and big enough to hold a byte
4375 // array, this function returns the number of elements a byte array should
4376 // have.
4377 static int LengthFor(int size_in_bytes) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004378 DCHECK(IsAligned(size_in_bytes, kPointerSize));
4379 DCHECK(size_in_bytes >= kHeaderSize);
Steve Blocka7e24c12009-10-30 11:49:00 +00004380 return size_in_bytes - kHeaderSize;
4381 }
4382
4383 // Returns data start address.
4384 inline Address GetDataStartAddress();
4385
4386 // Returns a pointer to the ByteArray object for a given data start address.
4387 static inline ByteArray* FromDataStartAddress(Address address);
4388
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004389 DECLARE_CAST(ByteArray)
Steve Blocka7e24c12009-10-30 11:49:00 +00004390
4391 // Dispatched behavior.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004392 inline int ByteArraySize();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004393 DECLARE_PRINTER(ByteArray)
4394 DECLARE_VERIFIER(ByteArray)
Steve Blocka7e24c12009-10-30 11:49:00 +00004395
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01004396 // Layout description.
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01004397 static const int kAlignedSize = OBJECT_POINTER_ALIGN(kHeaderSize);
Steve Blocka7e24c12009-10-30 11:49:00 +00004398
Leon Clarkee46be812010-01-19 14:06:41 +00004399 // Maximal memory consumption for a single ByteArray.
4400 static const int kMaxSize = 512 * MB;
4401 // Maximal length of a single ByteArray.
4402 static const int kMaxLength = kMaxSize - kHeaderSize;
4403
Steve Blocka7e24c12009-10-30 11:49:00 +00004404 private:
4405 DISALLOW_IMPLICIT_CONSTRUCTORS(ByteArray);
4406};
4407
4408
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004409// BytecodeArray represents a sequence of interpreter bytecodes.
4410class BytecodeArray : public FixedArrayBase {
4411 public:
4412 static int SizeFor(int length) {
4413 return OBJECT_POINTER_ALIGN(kHeaderSize + length);
4414 }
4415
4416 // Setter and getter
4417 inline byte get(int index);
4418 inline void set(int index, byte value);
4419
4420 // Returns data start address.
4421 inline Address GetFirstBytecodeAddress();
4422
4423 // Accessors for frame size.
4424 inline int frame_size() const;
4425 inline void set_frame_size(int frame_size);
4426
4427 // Accessor for register count (derived from frame_size).
4428 inline int register_count() const;
4429
4430 // Accessors for parameter count (including implicit 'this' receiver).
4431 inline int parameter_count() const;
4432 inline void set_parameter_count(int number_of_parameters);
4433
Ben Murdoch097c5b22016-05-18 11:27:45 +01004434 // Accessors for profiling count.
4435 inline int interrupt_budget() const;
4436 inline void set_interrupt_budget(int interrupt_budget);
4437
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004438 // Accessors for the constant pool.
4439 DECL_ACCESSORS(constant_pool, FixedArray)
4440
Ben Murdoch097c5b22016-05-18 11:27:45 +01004441 // Accessors for handler table containing offsets of exception handlers.
4442 DECL_ACCESSORS(handler_table, FixedArray)
4443
4444 // Accessors for source position table containing mappings between byte code
4445 // offset and source position.
Ben Murdochda12d292016-06-02 14:46:10 +01004446 DECL_ACCESSORS(source_position_table, ByteArray)
Ben Murdoch097c5b22016-05-18 11:27:45 +01004447
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004448 DECLARE_CAST(BytecodeArray)
4449
4450 // Dispatched behavior.
4451 inline int BytecodeArraySize();
4452
Ben Murdoch097c5b22016-05-18 11:27:45 +01004453 inline int instruction_size();
4454
4455 int SourcePosition(int offset);
4456 int SourceStatementPosition(int offset);
4457
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004458 DECLARE_PRINTER(BytecodeArray)
4459 DECLARE_VERIFIER(BytecodeArray)
4460
4461 void Disassemble(std::ostream& os);
4462
Ben Murdoch097c5b22016-05-18 11:27:45 +01004463 void CopyBytecodesTo(BytecodeArray* to);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004464
Ben Murdoch097c5b22016-05-18 11:27:45 +01004465 // Layout description.
4466 static const int kConstantPoolOffset = FixedArrayBase::kHeaderSize;
4467 static const int kHandlerTableOffset = kConstantPoolOffset + kPointerSize;
4468 static const int kSourcePositionTableOffset =
4469 kHandlerTableOffset + kPointerSize;
4470 static const int kFrameSizeOffset = kSourcePositionTableOffset + kPointerSize;
4471 static const int kParameterSizeOffset = kFrameSizeOffset + kIntSize;
4472 static const int kInterruptBudgetOffset = kParameterSizeOffset + kIntSize;
4473 static const int kHeaderSize = kInterruptBudgetOffset + kIntSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004474
4475 // Maximal memory consumption for a single BytecodeArray.
4476 static const int kMaxSize = 512 * MB;
4477 // Maximal length of a single BytecodeArray.
4478 static const int kMaxLength = kMaxSize - kHeaderSize;
4479
4480 class BodyDescriptor;
4481
4482 private:
4483 DISALLOW_IMPLICIT_CONSTRUCTORS(BytecodeArray);
4484};
4485
4486
4487// FreeSpace are fixed-size free memory blocks used by the heap and GC.
4488// They look like heap objects (are heap object tagged and have a map) so that
4489// the heap remains iterable. They have a size and a next pointer.
4490// The next pointer is the raw address of the next FreeSpace object (or NULL)
4491// in the free list.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004492class FreeSpace: public HeapObject {
4493 public:
4494 // [size]: size of the free space including the header.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004495 inline int size() const;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004496 inline void set_size(int value);
4497
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004498 inline int nobarrier_size() const;
4499 inline void nobarrier_set_size(int value);
4500
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004501 inline int Size();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004502
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004503 // Accessors for the next field.
4504 inline FreeSpace* next();
4505 inline void set_next(FreeSpace* next);
4506
4507 inline static FreeSpace* cast(HeapObject* obj);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004508
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004509 // Dispatched behavior.
4510 DECLARE_PRINTER(FreeSpace)
4511 DECLARE_VERIFIER(FreeSpace)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004512
4513 // Layout description.
4514 // Size is smi tagged when it is stored.
4515 static const int kSizeOffset = HeapObject::kHeaderSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004516 static const int kNextOffset = POINTER_SIZE_ALIGN(kSizeOffset + kPointerSize);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004517
4518 private:
4519 DISALLOW_IMPLICIT_CONSTRUCTORS(FreeSpace);
4520};
4521
4522
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004523// V has parameters (Type, type, TYPE, C type, element_size)
4524#define TYPED_ARRAYS(V) \
4525 V(Uint8, uint8, UINT8, uint8_t, 1) \
4526 V(Int8, int8, INT8, int8_t, 1) \
4527 V(Uint16, uint16, UINT16, uint16_t, 2) \
4528 V(Int16, int16, INT16, int16_t, 2) \
4529 V(Uint32, uint32, UINT32, uint32_t, 4) \
4530 V(Int32, int32, INT32, int32_t, 4) \
4531 V(Float32, float32, FLOAT32, float, 4) \
4532 V(Float64, float64, FLOAT64, double, 8) \
4533 V(Uint8Clamped, uint8_clamped, UINT8_CLAMPED, uint8_t, 1)
4534
4535
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004536class FixedTypedArrayBase: public FixedArrayBase {
4537 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004538 // [base_pointer]: Either points to the FixedTypedArrayBase itself or nullptr.
4539 DECL_ACCESSORS(base_pointer, Object)
4540
4541 // [external_pointer]: Contains the offset between base_pointer and the start
4542 // of the data. If the base_pointer is a nullptr, the external_pointer
4543 // therefore points to the actual backing store.
4544 DECL_ACCESSORS(external_pointer, void)
4545
4546 // Dispatched behavior.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004547 DECLARE_CAST(FixedTypedArrayBase)
4548
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004549 static const int kBasePointerOffset = FixedArrayBase::kHeaderSize;
4550 static const int kExternalPointerOffset = kBasePointerOffset + kPointerSize;
4551 static const int kHeaderSize =
4552 DOUBLE_POINTER_ALIGN(kExternalPointerOffset + kPointerSize);
4553
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004554 static const int kDataOffset = kHeaderSize;
4555
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004556 class BodyDescriptor;
4557
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004558 inline int size();
4559
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004560 static inline int TypedArraySize(InstanceType type, int length);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004561 inline int TypedArraySize(InstanceType type);
4562
4563 // Use with care: returns raw pointer into heap.
4564 inline void* DataPtr();
4565
4566 inline int DataSize();
4567
4568 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004569 static inline int ElementSize(InstanceType type);
4570
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004571 inline int DataSize(InstanceType type);
4572
4573 DISALLOW_IMPLICIT_CONSTRUCTORS(FixedTypedArrayBase);
4574};
4575
4576
4577template <class Traits>
4578class FixedTypedArray: public FixedTypedArrayBase {
4579 public:
4580 typedef typename Traits::ElementType ElementType;
4581 static const InstanceType kInstanceType = Traits::kInstanceType;
4582
4583 DECLARE_CAST(FixedTypedArray<Traits>)
4584
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004585 inline ElementType get_scalar(int index);
Ben Murdoch097c5b22016-05-18 11:27:45 +01004586 static inline Handle<Object> get(FixedTypedArray* array, int index);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004587 inline void set(int index, ElementType value);
4588
4589 static inline ElementType from_int(int value);
4590 static inline ElementType from_double(double value);
4591
4592 // This accessor applies the correct conversion from Smi, HeapNumber
4593 // and undefined.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004594 inline void SetValue(uint32_t index, Object* value);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004595
4596 DECLARE_PRINTER(FixedTypedArray)
4597 DECLARE_VERIFIER(FixedTypedArray)
4598
4599 private:
4600 DISALLOW_IMPLICIT_CONSTRUCTORS(FixedTypedArray);
4601};
4602
4603#define FIXED_TYPED_ARRAY_TRAITS(Type, type, TYPE, elementType, size) \
4604 class Type##ArrayTraits { \
4605 public: /* NOLINT */ \
4606 typedef elementType ElementType; \
4607 static const InstanceType kInstanceType = FIXED_##TYPE##_ARRAY_TYPE; \
4608 static const char* Designator() { return #type " array"; } \
4609 static inline Handle<Object> ToHandle(Isolate* isolate, \
4610 elementType scalar); \
4611 static inline elementType defaultValue(); \
4612 }; \
4613 \
4614 typedef FixedTypedArray<Type##ArrayTraits> Fixed##Type##Array;
4615
4616TYPED_ARRAYS(FIXED_TYPED_ARRAY_TRAITS)
4617
4618#undef FIXED_TYPED_ARRAY_TRAITS
4619
Emily Bernierd0a1eb72015-03-24 16:35:39 -04004620
Ben Murdochb0fe1622011-05-05 13:52:32 +01004621// DeoptimizationInputData is a fixed array used to hold the deoptimization
4622// data for code generated by the Hydrogen/Lithium compiler. It also
4623// contains information about functions that were inlined. If N different
4624// functions were inlined then first N elements of the literal array will
4625// contain these functions.
4626//
4627// It can be empty.
4628class DeoptimizationInputData: public FixedArray {
4629 public:
4630 // Layout description. Indices in the array.
4631 static const int kTranslationByteArrayIndex = 0;
4632 static const int kInlinedFunctionCountIndex = 1;
4633 static const int kLiteralArrayIndex = 2;
4634 static const int kOsrAstIdIndex = 3;
4635 static const int kOsrPcOffsetIndex = 4;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004636 static const int kOptimizationIdIndex = 5;
4637 static const int kSharedFunctionInfoIndex = 6;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004638 static const int kWeakCellCacheIndex = 7;
4639 static const int kFirstDeoptEntryIndex = 8;
Ben Murdochb0fe1622011-05-05 13:52:32 +01004640
4641 // Offsets of deopt entry elements relative to the start of the entry.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004642 static const int kAstIdRawOffset = 0;
Ben Murdochb0fe1622011-05-05 13:52:32 +01004643 static const int kTranslationIndexOffset = 1;
4644 static const int kArgumentsStackHeightOffset = 2;
Ben Murdoch2b4ba112012-01-20 14:57:15 +00004645 static const int kPcOffset = 3;
4646 static const int kDeoptEntrySize = 4;
Ben Murdochb0fe1622011-05-05 13:52:32 +01004647
4648 // Simple element accessors.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004649#define DECLARE_ELEMENT_ACCESSORS(name, type) \
4650 inline type* name(); \
4651 inline void Set##name(type* value);
Ben Murdochb0fe1622011-05-05 13:52:32 +01004652
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004653 DECLARE_ELEMENT_ACCESSORS(TranslationByteArray, ByteArray)
4654 DECLARE_ELEMENT_ACCESSORS(InlinedFunctionCount, Smi)
4655 DECLARE_ELEMENT_ACCESSORS(LiteralArray, FixedArray)
4656 DECLARE_ELEMENT_ACCESSORS(OsrAstId, Smi)
4657 DECLARE_ELEMENT_ACCESSORS(OsrPcOffset, Smi)
4658 DECLARE_ELEMENT_ACCESSORS(OptimizationId, Smi)
4659 DECLARE_ELEMENT_ACCESSORS(SharedFunctionInfo, Object)
4660 DECLARE_ELEMENT_ACCESSORS(WeakCellCache, Object)
Ben Murdochb0fe1622011-05-05 13:52:32 +01004661
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004662#undef DECLARE_ELEMENT_ACCESSORS
Ben Murdochb0fe1622011-05-05 13:52:32 +01004663
4664 // Accessors for elements of the ith deoptimization entry.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004665#define DECLARE_ENTRY_ACCESSORS(name, type) \
4666 inline type* name(int i); \
4667 inline void Set##name(int i, type* value);
Ben Murdochb0fe1622011-05-05 13:52:32 +01004668
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004669 DECLARE_ENTRY_ACCESSORS(AstIdRaw, Smi)
4670 DECLARE_ENTRY_ACCESSORS(TranslationIndex, Smi)
4671 DECLARE_ENTRY_ACCESSORS(ArgumentsStackHeight, Smi)
4672 DECLARE_ENTRY_ACCESSORS(Pc, Smi)
Ben Murdochb0fe1622011-05-05 13:52:32 +01004673
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004674#undef DECLARE_ENTRY_ACCESSORS
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004675
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004676 inline BailoutId AstId(int i);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004677
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004678 inline void SetAstId(int i, BailoutId value);
Ben Murdochb0fe1622011-05-05 13:52:32 +01004679
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004680 inline int DeoptCount();
Ben Murdochb0fe1622011-05-05 13:52:32 +01004681
4682 // Allocates a DeoptimizationInputData.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004683 static Handle<DeoptimizationInputData> New(Isolate* isolate,
4684 int deopt_entry_count,
4685 PretenureFlag pretenure);
Ben Murdochb0fe1622011-05-05 13:52:32 +01004686
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004687 DECLARE_CAST(DeoptimizationInputData)
Ben Murdochb0fe1622011-05-05 13:52:32 +01004688
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00004689#ifdef ENABLE_DISASSEMBLER
Emily Bernierd0a1eb72015-03-24 16:35:39 -04004690 void DeoptimizationInputDataPrint(std::ostream& os); // NOLINT
Ben Murdochb0fe1622011-05-05 13:52:32 +01004691#endif
4692
4693 private:
4694 static int IndexForEntry(int i) {
4695 return kFirstDeoptEntryIndex + (i * kDeoptEntrySize);
4696 }
4697
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004698
4699 static int LengthFor(int entry_count) { return IndexForEntry(entry_count); }
Ben Murdochb0fe1622011-05-05 13:52:32 +01004700};
4701
4702
4703// DeoptimizationOutputData is a fixed array used to hold the deoptimization
4704// data for code generated by the full compiler.
4705// The format of the these objects is
4706// [i * 2]: Ast ID for ith deoptimization.
4707// [i * 2 + 1]: PC and state of ith deoptimization
4708class DeoptimizationOutputData: public FixedArray {
4709 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004710 inline int DeoptPoints();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004711
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004712 inline BailoutId AstId(int index);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004713
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004714 inline void SetAstId(int index, BailoutId id);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004715
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004716 inline Smi* PcAndState(int index);
4717 inline void SetPcAndState(int index, Smi* offset);
Ben Murdochb0fe1622011-05-05 13:52:32 +01004718
4719 static int LengthOfFixedArray(int deopt_points) {
4720 return deopt_points * 2;
4721 }
4722
4723 // Allocates a DeoptimizationOutputData.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004724 static Handle<DeoptimizationOutputData> New(Isolate* isolate,
4725 int number_of_deopt_points,
4726 PretenureFlag pretenure);
Ben Murdochb0fe1622011-05-05 13:52:32 +01004727
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004728 DECLARE_CAST(DeoptimizationOutputData)
Ben Murdochb0fe1622011-05-05 13:52:32 +01004729
Ben Murdoch097c5b22016-05-18 11:27:45 +01004730#ifdef ENABLE_DISASSEMBLER
Emily Bernierd0a1eb72015-03-24 16:35:39 -04004731 void DeoptimizationOutputDataPrint(std::ostream& os); // NOLINT
Ben Murdochb0fe1622011-05-05 13:52:32 +01004732#endif
4733};
4734
4735
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004736// A literals array contains the literals for a JSFunction. It also holds
4737// the type feedback vector.
4738class LiteralsArray : public FixedArray {
4739 public:
4740 static const int kVectorIndex = 0;
4741 static const int kFirstLiteralIndex = 1;
4742 static const int kOffsetToFirstLiteral =
4743 FixedArray::kHeaderSize + kPointerSize;
4744
4745 static int OffsetOfLiteralAt(int index) {
4746 return SizeFor(index + kFirstLiteralIndex);
4747 }
4748
4749 inline TypeFeedbackVector* feedback_vector() const;
4750 inline void set_feedback_vector(TypeFeedbackVector* vector);
4751 inline Object* literal(int literal_index) const;
4752 inline void set_literal(int literal_index, Object* literal);
4753 inline int literals_count() const;
4754
4755 static Handle<LiteralsArray> New(Isolate* isolate,
4756 Handle<TypeFeedbackVector> vector,
4757 int number_of_literals,
4758 PretenureFlag pretenure);
4759
4760 DECLARE_CAST(LiteralsArray)
4761
4762 private:
4763 inline Object* get(int index) const;
4764 inline void set(int index, Object* value);
4765 inline void set(int index, Smi* value);
4766 inline void set(int index, Object* value, WriteBarrierMode mode);
4767};
4768
4769
4770// HandlerTable is a fixed array containing entries for exception handlers in
4771// the code object it is associated with. The tables comes in two flavors:
4772// 1) Based on ranges: Used for unoptimized code. Contains one entry per
4773// exception handler and a range representing the try-block covered by that
4774// handler. Layout looks as follows:
Ben Murdoch097c5b22016-05-18 11:27:45 +01004775// [ range-start , range-end , handler-offset , handler-data ]
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004776// 2) Based on return addresses: Used for turbofanned code. Contains one entry
4777// per call-site that could throw an exception. Layout looks as follows:
4778// [ return-address-offset , handler-offset ]
4779class HandlerTable : public FixedArray {
4780 public:
4781 // Conservative prediction whether a given handler will locally catch an
4782 // exception or cause a re-throw to outside the code boundary. Since this is
4783 // undecidable it is merely an approximation (e.g. useful for debugger).
4784 enum CatchPrediction { UNCAUGHT, CAUGHT };
4785
Ben Murdoch097c5b22016-05-18 11:27:45 +01004786 // Getters for handler table based on ranges.
4787 inline int GetRangeStart(int index) const;
4788 inline int GetRangeEnd(int index) const;
4789 inline int GetRangeHandler(int index) const;
4790 inline int GetRangeData(int index) const;
4791
4792 // Setters for handler table based on ranges.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004793 inline void SetRangeStart(int index, int value);
4794 inline void SetRangeEnd(int index, int value);
4795 inline void SetRangeHandler(int index, int offset, CatchPrediction pred);
Ben Murdoch097c5b22016-05-18 11:27:45 +01004796 inline void SetRangeData(int index, int value);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004797
Ben Murdoch097c5b22016-05-18 11:27:45 +01004798 // Setters for handler table based on return addresses.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004799 inline void SetReturnOffset(int index, int value);
4800 inline void SetReturnHandler(int index, int offset, CatchPrediction pred);
4801
4802 // Lookup handler in a table based on ranges.
Ben Murdoch097c5b22016-05-18 11:27:45 +01004803 int LookupRange(int pc_offset, int* data, CatchPrediction* prediction);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004804
4805 // Lookup handler in a table based on return addresses.
4806 int LookupReturn(int pc_offset, CatchPrediction* prediction);
4807
Ben Murdoch097c5b22016-05-18 11:27:45 +01004808 // Returns the conservative catch predication.
4809 inline CatchPrediction GetRangePrediction(int index) const;
4810
4811 // Returns the number of entries in the table.
4812 inline int NumberOfRangeEntries() const;
4813
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004814 // Returns the required length of the underlying fixed array.
4815 static int LengthForRange(int entries) { return entries * kRangeEntrySize; }
4816 static int LengthForReturn(int entries) { return entries * kReturnEntrySize; }
4817
4818 DECLARE_CAST(HandlerTable)
4819
Ben Murdoch097c5b22016-05-18 11:27:45 +01004820#ifdef ENABLE_DISASSEMBLER
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004821 void HandlerTableRangePrint(std::ostream& os); // NOLINT
4822 void HandlerTableReturnPrint(std::ostream& os); // NOLINT
4823#endif
4824
4825 private:
4826 // Layout description for handler table based on ranges.
4827 static const int kRangeStartIndex = 0;
4828 static const int kRangeEndIndex = 1;
4829 static const int kRangeHandlerIndex = 2;
Ben Murdoch097c5b22016-05-18 11:27:45 +01004830 static const int kRangeDataIndex = 3;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004831 static const int kRangeEntrySize = 4;
4832
4833 // Layout description for handler table based on return addresses.
4834 static const int kReturnOffsetIndex = 0;
4835 static const int kReturnHandlerIndex = 1;
4836 static const int kReturnEntrySize = 2;
4837
4838 // Encoding of the {handler} field.
4839 class HandlerPredictionField : public BitField<CatchPrediction, 0, 1> {};
4840 class HandlerOffsetField : public BitField<int, 1, 30> {};
4841};
4842
Ben Murdochb8e0da22011-05-16 14:20:40 +01004843
Steve Blocka7e24c12009-10-30 11:49:00 +00004844// Code describes objects with on-the-fly generated machine code.
4845class Code: public HeapObject {
4846 public:
4847 // Opaque data type for encapsulating code flags like kind, inline
4848 // cache state, and arguments count.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004849 typedef uint32_t Flags;
4850
4851#define NON_IC_KIND_LIST(V) \
4852 V(FUNCTION) \
4853 V(OPTIMIZED_FUNCTION) \
Ben Murdochda12d292016-06-02 14:46:10 +01004854 V(BYTECODE_HANDLER) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004855 V(STUB) \
4856 V(HANDLER) \
4857 V(BUILTIN) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004858 V(REGEXP) \
Ben Murdochda12d292016-06-02 14:46:10 +01004859 V(WASM_FUNCTION) \
4860 V(WASM_TO_JS_FUNCTION) \
4861 V(JS_TO_WASM_FUNCTION)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004862
4863#define IC_KIND_LIST(V) \
4864 V(LOAD_IC) \
4865 V(KEYED_LOAD_IC) \
4866 V(CALL_IC) \
4867 V(STORE_IC) \
4868 V(KEYED_STORE_IC) \
4869 V(BINARY_OP_IC) \
4870 V(COMPARE_IC) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004871 V(TO_BOOLEAN_IC)
4872
4873#define CODE_KIND_LIST(V) \
4874 NON_IC_KIND_LIST(V) \
4875 IC_KIND_LIST(V)
Steve Blocka7e24c12009-10-30 11:49:00 +00004876
4877 enum Kind {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004878#define DEFINE_CODE_KIND_ENUM(name) name,
4879 CODE_KIND_LIST(DEFINE_CODE_KIND_ENUM)
4880#undef DEFINE_CODE_KIND_ENUM
4881 NUMBER_OF_KINDS
Steve Blocka7e24c12009-10-30 11:49:00 +00004882 };
4883
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004884 // No more than 32 kinds. The value is currently encoded in five bits in
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004885 // Flags.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004886 STATIC_ASSERT(NUMBER_OF_KINDS <= 32);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004887
4888 static const char* Kind2String(Kind kind);
4889
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004890 static const int kPrologueOffsetNotSet = -1;
Ben Murdochb8e0da22011-05-16 14:20:40 +01004891
Steve Blocka7e24c12009-10-30 11:49:00 +00004892#ifdef ENABLE_DISASSEMBLER
4893 // Printing
Steve Blocka7e24c12009-10-30 11:49:00 +00004894 static const char* ICState2String(InlineCacheState state);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04004895 static void PrintExtraICState(std::ostream& os, // NOLINT
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004896 Kind kind, ExtraICState extra);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04004897 void Disassemble(const char* name, std::ostream& os); // NOLINT
Steve Blocka7e24c12009-10-30 11:49:00 +00004898#endif // ENABLE_DISASSEMBLER
4899
4900 // [instruction_size]: Size of the native instructions
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004901 inline int instruction_size() const;
Steve Blocka7e24c12009-10-30 11:49:00 +00004902 inline void set_instruction_size(int value);
4903
Leon Clarkeac952652010-07-15 11:15:24 +01004904 // [relocation_info]: Code relocation information
4905 DECL_ACCESSORS(relocation_info, ByteArray)
Ben Murdochb0fe1622011-05-05 13:52:32 +01004906 void InvalidateRelocation();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004907 void InvalidateEmbeddedObjects();
Leon Clarkeac952652010-07-15 11:15:24 +01004908
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004909 // [handler_table]: Fixed array containing offsets of exception handlers.
4910 DECL_ACCESSORS(handler_table, FixedArray)
4911
Ben Murdochb0fe1622011-05-05 13:52:32 +01004912 // [deoptimization_data]: Array containing data for deopt.
4913 DECL_ACCESSORS(deoptimization_data, FixedArray)
4914
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004915 // [raw_type_feedback_info]: This field stores various things, depending on
4916 // the kind of the code object.
4917 // FUNCTION => type feedback information.
4918 // STUB and ICs => major/minor key as Smi.
4919 DECL_ACCESSORS(raw_type_feedback_info, Object)
4920 inline Object* type_feedback_info();
4921 inline void set_type_feedback_info(
4922 Object* value, WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
4923 inline uint32_t stub_key();
4924 inline void set_stub_key(uint32_t key);
4925
4926 // [next_code_link]: Link for lists of optimized or deoptimized code.
4927 // Note that storage for this field is overlapped with typefeedback_info.
4928 DECL_ACCESSORS(next_code_link, Object)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004929
4930 // [gc_metadata]: Field used to hold GC related metadata. The contents of this
Ben Murdoch257744e2011-11-30 15:57:28 +00004931 // field does not have to be traced during garbage collection since
4932 // it is only used by the garbage collector itself.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004933 DECL_ACCESSORS(gc_metadata, Object)
4934
4935 // [ic_age]: Inline caching age: the value of the Heap::global_ic_age
4936 // at the moment when this object was created.
4937 inline void set_ic_age(int count);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004938 inline int ic_age() const;
4939
4940 // [prologue_offset]: Offset of the function prologue, used for aging
4941 // FUNCTIONs and OPTIMIZED_FUNCTIONs.
4942 inline int prologue_offset() const;
4943 inline void set_prologue_offset(int offset);
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01004944
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004945 // [constant_pool offset]: Offset of the constant pool.
4946 // Valid for FLAG_enable_embedded_constant_pool only
4947 inline int constant_pool_offset() const;
4948 inline void set_constant_pool_offset(int offset);
4949
Ben Murdochb0fe1622011-05-05 13:52:32 +01004950 // Unchecked accessors to be used during GC.
Leon Clarkeac952652010-07-15 11:15:24 +01004951 inline ByteArray* unchecked_relocation_info();
4952
Steve Blocka7e24c12009-10-30 11:49:00 +00004953 inline int relocation_size();
Steve Blocka7e24c12009-10-30 11:49:00 +00004954
Steve Blocka7e24c12009-10-30 11:49:00 +00004955 // [flags]: Various code flags.
4956 inline Flags flags();
4957 inline void set_flags(Flags flags);
4958
4959 // [flags]: Access to specific code flags.
4960 inline Kind kind();
4961 inline InlineCacheState ic_state(); // Only valid for IC stubs.
Ben Murdochb8e0da22011-05-16 14:20:40 +01004962 inline ExtraICState extra_ic_state(); // Only valid for IC stubs.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004963
Steve Blocka7e24c12009-10-30 11:49:00 +00004964 // Testers for IC stub kinds.
4965 inline bool is_inline_cache_stub();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004966 inline bool is_debug_stub();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004967 inline bool is_handler();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004968 inline bool is_call_stub();
4969 inline bool is_binary_op_stub();
4970 inline bool is_compare_ic_stub();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004971 inline bool is_to_boolean_ic_stub();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004972 inline bool is_optimized_code();
Ben Murdochda12d292016-06-02 14:46:10 +01004973 inline bool is_wasm_code();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004974 inline bool embeds_maps_weakly();
Ben Murdochb0fe1622011-05-05 13:52:32 +01004975
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004976 inline bool IsCodeStubOrIC();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004977 inline bool IsJavaScriptCode();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004978
4979 inline void set_raw_kind_specific_flags1(int value);
4980 inline void set_raw_kind_specific_flags2(int value);
4981
Ben Murdoch097c5b22016-05-18 11:27:45 +01004982 // Testers for interpreter builtins.
4983 inline bool is_interpreter_entry_trampoline();
4984 inline bool is_interpreter_enter_bytecode_dispatch();
4985
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004986 // [is_crankshafted]: For kind STUB or ICs, tells whether or not a code
4987 // object was generated by either the hydrogen or the TurboFan optimizing
4988 // compiler (but it may not be an optimized function).
4989 inline bool is_crankshafted();
4990 inline bool is_hydrogen_stub(); // Crankshafted, but not a function.
4991 inline void set_is_crankshafted(bool value);
4992
4993 // [is_turbofanned]: For kind STUB or OPTIMIZED_FUNCTION, tells whether the
4994 // code object was generated by the TurboFan optimizing compiler.
4995 inline bool is_turbofanned();
4996 inline void set_is_turbofanned(bool value);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004997
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004998 // [can_have_weak_objects]: For kind OPTIMIZED_FUNCTION, tells whether the
4999 // embedded objects in code should be treated weakly.
5000 inline bool can_have_weak_objects();
5001 inline void set_can_have_weak_objects(bool value);
Ben Murdochb0fe1622011-05-05 13:52:32 +01005002
5003 // [has_deoptimization_support]: For FUNCTION kind, tells if it has
5004 // deoptimization support.
5005 inline bool has_deoptimization_support();
5006 inline void set_has_deoptimization_support(bool value);
5007
Ben Murdoch589d6972011-11-30 16:04:58 +00005008 // [has_debug_break_slots]: For FUNCTION kind, tells if it has
5009 // been compiled with debug break slots.
5010 inline bool has_debug_break_slots();
5011 inline void set_has_debug_break_slots(bool value);
5012
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005013 // [has_reloc_info_for_serialization]: For FUNCTION kind, tells if its
5014 // reloc info includes runtime and external references to support
5015 // serialization/deserialization.
5016 inline bool has_reloc_info_for_serialization();
5017 inline void set_has_reloc_info_for_serialization(bool value);
5018
Ben Murdochb0fe1622011-05-05 13:52:32 +01005019 // [allow_osr_at_loop_nesting_level]: For FUNCTION kind, tells for
5020 // how long the function has been marked for OSR and therefore which
5021 // level of loop nesting we are willing to do on-stack replacement
5022 // for.
5023 inline void set_allow_osr_at_loop_nesting_level(int level);
5024 inline int allow_osr_at_loop_nesting_level();
5025
Ben Murdoch8f9999f2012-04-23 10:39:17 +01005026 // [profiler_ticks]: For FUNCTION kind, tells for how many profiler ticks
5027 // the code object was seen on the stack with no IC patching going on.
5028 inline int profiler_ticks();
5029 inline void set_profiler_ticks(int ticks);
5030
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005031 // [builtin_index]: For BUILTIN kind, tells which builtin index it has.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005032 // For builtins, tells which builtin index it has.
5033 // Note that builtins can have a code kind other than BUILTIN, which means
5034 // that for arbitrary code objects, this index value may be random garbage.
5035 // To verify in that case, compare the code object to the indexed builtin.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005036 inline int builtin_index();
5037 inline void set_builtin_index(int id);
5038
Ben Murdochb0fe1622011-05-05 13:52:32 +01005039 // [stack_slots]: For kind OPTIMIZED_FUNCTION, the number of stack slots
5040 // reserved in the code prologue.
5041 inline unsigned stack_slots();
5042 inline void set_stack_slots(unsigned slots);
5043
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005044 // [safepoint_table_start]: For kind OPTIMIZED_FUNCTION, the offset in
Ben Murdochb0fe1622011-05-05 13:52:32 +01005045 // the instruction stream where the safepoint table starts.
Steve Block1e0659c2011-05-24 12:43:12 +01005046 inline unsigned safepoint_table_offset();
5047 inline void set_safepoint_table_offset(unsigned offset);
Ben Murdochb0fe1622011-05-05 13:52:32 +01005048
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005049 // [back_edge_table_start]: For kind FUNCTION, the offset in the
5050 // instruction stream where the back edge table starts.
5051 inline unsigned back_edge_table_offset();
5052 inline void set_back_edge_table_offset(unsigned offset);
Ben Murdochb0fe1622011-05-05 13:52:32 +01005053
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005054 inline bool back_edges_patched_for_osr();
Ben Murdochb0fe1622011-05-05 13:52:32 +01005055
Ben Murdoch69a99ed2011-11-30 16:03:39 +00005056 // [to_boolean_foo]: For kind TO_BOOLEAN_IC tells what state the stub is in.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005057 inline uint16_t to_boolean_state();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005058
5059 // [marked_for_deoptimization]: For kind OPTIMIZED_FUNCTION tells whether
5060 // the code is going to be deoptimized because of dead embedded maps.
5061 inline bool marked_for_deoptimization();
5062 inline void set_marked_for_deoptimization(bool flag);
5063
5064 // [constant_pool]: The constant pool for this function.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005065 inline Address constant_pool();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005066
Ben Murdochb8e0da22011-05-16 14:20:40 +01005067 // Get the safepoint entry for the given pc.
5068 SafepointEntry GetSafepointEntry(Address pc);
Ben Murdochb0fe1622011-05-05 13:52:32 +01005069
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005070 // Find an object in a stub with a specified map
5071 Object* FindNthObject(int n, Map* match_map);
5072
5073 // Find the first allocation site in an IC stub.
5074 AllocationSite* FindFirstAllocationSite();
Ben Murdochb0fe1622011-05-05 13:52:32 +01005075
5076 // Find the first map in an IC stub.
5077 Map* FindFirstMap();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005078
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005079 class FindAndReplacePattern;
5080 // For each (map-to-find, object-to-replace) pair in the pattern, this
5081 // function replaces the corresponding placeholder in the code with the
5082 // object-to-replace. The function assumes that pairs in the pattern come in
5083 // the same order as the placeholders in the code.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005084 // If the placeholder is a weak cell, then the value of weak cell is matched
5085 // against the map-to-find.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005086 void FindAndReplace(const FindAndReplacePattern& pattern);
5087
5088 // The entire code object including its header is copied verbatim to the
5089 // snapshot so that it can be written in one, fast, memcpy during
5090 // deserialization. The deserializer will overwrite some pointers, rather
5091 // like a runtime linker, but the random allocation addresses used in the
5092 // mksnapshot process would still be present in the unlinked snapshot data,
5093 // which would make snapshot production non-reproducible. This method wipes
5094 // out the to-be-overwritten header data for reproducible snapshots.
5095 inline void WipeOutHeader();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005096
Steve Blocka7e24c12009-10-30 11:49:00 +00005097 // Flags operations.
Ben Murdochb8e0da22011-05-16 14:20:40 +01005098 static inline Flags ComputeFlags(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005099 Kind kind, InlineCacheState ic_state = UNINITIALIZED,
Ben Murdochc5610432016-08-08 18:44:38 +01005100 ExtraICState extra_ic_state = kNoExtraICState,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005101 CacheHolderFlag holder = kCacheOnReceiver);
Steve Blocka7e24c12009-10-30 11:49:00 +00005102
5103 static inline Flags ComputeMonomorphicFlags(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005104 Kind kind, ExtraICState extra_ic_state = kNoExtraICState,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005105 CacheHolderFlag holder = kCacheOnReceiver);
Steve Blocka7e24c12009-10-30 11:49:00 +00005106
Ben Murdochc5610432016-08-08 18:44:38 +01005107 static inline Flags ComputeHandlerFlags(
5108 Kind handler_kind, CacheHolderFlag holder = kCacheOnReceiver);
5109
Steve Blocka7e24c12009-10-30 11:49:00 +00005110 static inline InlineCacheState ExtractICStateFromFlags(Flags flags);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005111 static inline CacheHolderFlag ExtractCacheHolderFromFlags(Flags flags);
Ben Murdoch589d6972011-11-30 16:04:58 +00005112 static inline Kind ExtractKindFromFlags(Flags flags);
Ben Murdoch589d6972011-11-30 16:04:58 +00005113 static inline ExtraICState ExtractExtraICStateFromFlags(Flags flags);
Ben Murdoch589d6972011-11-30 16:04:58 +00005114
Ben Murdochc5610432016-08-08 18:44:38 +01005115 static inline Flags RemoveHolderFromFlags(Flags flags);
Steve Blocka7e24c12009-10-30 11:49:00 +00005116
5117 // Convert a target address into a code object.
5118 static inline Code* GetCodeFromTargetAddress(Address address);
5119
Steve Block791712a2010-08-27 10:21:07 +01005120 // Convert an entry address into an object.
5121 static inline Object* GetObjectFromEntryAddress(Address location_of_address);
5122
Steve Blocka7e24c12009-10-30 11:49:00 +00005123 // Returns the address of the first instruction.
5124 inline byte* instruction_start();
5125
Leon Clarkeac952652010-07-15 11:15:24 +01005126 // Returns the address right after the last instruction.
5127 inline byte* instruction_end();
5128
Steve Blocka7e24c12009-10-30 11:49:00 +00005129 // Returns the size of the instructions, padding, and relocation information.
5130 inline int body_size();
5131
5132 // Returns the address of the first relocation info (read backwards!).
5133 inline byte* relocation_start();
5134
5135 // Code entry point.
5136 inline byte* entry();
5137
5138 // Returns true if pc is inside this object's instructions.
5139 inline bool contains(byte* pc);
5140
Steve Blocka7e24c12009-10-30 11:49:00 +00005141 // Relocate the code by delta bytes. Called to signal that this code
5142 // object has been moved by delta bytes.
Steve Blockd0582a62009-12-15 09:54:21 +00005143 void Relocate(intptr_t delta);
Steve Blocka7e24c12009-10-30 11:49:00 +00005144
5145 // Migrate code described by desc.
5146 void CopyFrom(const CodeDesc& desc);
5147
Ben Murdoch3bec4d22010-07-22 14:51:16 +01005148 // Returns the object size for a given body (used for allocation).
5149 static int SizeFor(int body_size) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005150 DCHECK_SIZE_TAG_ALIGNED(body_size);
Ben Murdoch3bec4d22010-07-22 14:51:16 +01005151 return RoundUp(kHeaderSize + body_size, kCodeAlignment);
Steve Blocka7e24c12009-10-30 11:49:00 +00005152 }
5153
5154 // Calculate the size of the code object to report for log events. This takes
5155 // the layout of the code object into account.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005156 inline int ExecutableSize();
Steve Blocka7e24c12009-10-30 11:49:00 +00005157
5158 // Locating source position.
Ben Murdoch097c5b22016-05-18 11:27:45 +01005159 int SourcePosition(int code_offset);
5160 int SourceStatementPosition(int code_offset);
Steve Blocka7e24c12009-10-30 11:49:00 +00005161
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005162 DECLARE_CAST(Code)
Steve Blocka7e24c12009-10-30 11:49:00 +00005163
5164 // Dispatched behavior.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005165 inline int CodeSize();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005166
5167 DECLARE_PRINTER(Code)
5168 DECLARE_VERIFIER(Code)
5169
Ben Murdoch8f9999f2012-04-23 10:39:17 +01005170 void ClearInlineCaches();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005171
5172 BailoutId TranslatePcOffsetToAstId(uint32_t pc_offset);
5173 uint32_t TranslateAstIdToPcOffset(BailoutId ast_id);
5174
5175#define DECLARE_CODE_AGE_ENUM(X) k##X##CodeAge,
5176 enum Age {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005177 kToBeExecutedOnceCodeAge = -3,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005178 kNotExecutedCodeAge = -2,
5179 kExecutedOnceCodeAge = -1,
5180 kNoAgeCodeAge = 0,
5181 CODE_AGE_LIST(DECLARE_CODE_AGE_ENUM)
5182 kAfterLastCodeAge,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005183 kFirstCodeAge = kToBeExecutedOnceCodeAge,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005184 kLastCodeAge = kAfterLastCodeAge - 1,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005185 kCodeAgeCount = kAfterLastCodeAge - kFirstCodeAge - 1,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005186 kIsOldCodeAge = kSexagenarianCodeAge,
5187 kPreAgedCodeAge = kIsOldCodeAge - 1
5188 };
5189#undef DECLARE_CODE_AGE_ENUM
5190
5191 // Code aging. Indicates how many full GCs this code has survived without
5192 // being entered through the prologue. Used to determine when it is
5193 // relatively safe to flush this code object and replace it with the lazy
5194 // compilation stub.
5195 static void MakeCodeAgeSequenceYoung(byte* sequence, Isolate* isolate);
5196 static void MarkCodeAsExecuted(byte* sequence, Isolate* isolate);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005197 void MakeYoung(Isolate* isolate);
Ben Murdochda12d292016-06-02 14:46:10 +01005198 void PreAge(Isolate* isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005199 void MarkToBeExecutedOnce(Isolate* isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005200 void MakeOlder(MarkingParity);
5201 static bool IsYoungSequence(Isolate* isolate, byte* sequence);
5202 bool IsOld();
5203 Age GetAge();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005204 static inline Code* GetPreAgedCodeAgeStub(Isolate* isolate) {
5205 return GetCodeAgeStub(isolate, kNotExecutedCodeAge, NO_MARKING_PARITY);
5206 }
5207
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005208 void PrintDeoptLocation(FILE* out, Address pc);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005209 bool CanDeoptAt(Address pc);
5210
5211#ifdef VERIFY_HEAP
5212 void VerifyEmbeddedObjectsDependency();
5213#endif
5214
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005215#ifdef DEBUG
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005216 enum VerifyMode { kNoContextSpecificPointers, kNoContextRetainingPointers };
5217 void VerifyEmbeddedObjects(VerifyMode mode = kNoContextRetainingPointers);
5218 static void VerifyRecompiledCode(Code* old_code, Code* new_code);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005219#endif // DEBUG
5220
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005221 inline bool CanContainWeakObjects();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005222
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005223 inline bool IsWeakObject(Object* object);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005224
5225 static inline bool IsWeakObjectInOptimizedCode(Object* object);
Ben Murdochb0fe1622011-05-05 13:52:32 +01005226
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005227 static Handle<WeakCell> WeakCellFor(Handle<Code> code);
5228 WeakCell* CachedWeakCell();
5229
Ben Murdochb0fe1622011-05-05 13:52:32 +01005230 // Max loop nesting marker used to postpose OSR. We don't take loop
5231 // nesting that is deeper than 5 levels into account.
5232 static const int kMaxLoopNestingMarker = 6;
5233
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005234 static const int kConstantPoolSize =
5235 FLAG_enable_embedded_constant_pool ? kIntSize : 0;
5236
Steve Blocka7e24c12009-10-30 11:49:00 +00005237 // Layout description.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005238 static const int kRelocationInfoOffset = HeapObject::kHeaderSize;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005239 static const int kHandlerTableOffset = kRelocationInfoOffset + kPointerSize;
Ben Murdochb0fe1622011-05-05 13:52:32 +01005240 static const int kDeoptimizationDataOffset =
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005241 kHandlerTableOffset + kPointerSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005242 // For FUNCTION kind, we store the type feedback info here.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005243 static const int kTypeFeedbackInfoOffset =
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01005244 kDeoptimizationDataOffset + kPointerSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005245 static const int kNextCodeLinkOffset = kTypeFeedbackInfoOffset + kPointerSize;
5246 static const int kGCMetadataOffset = kNextCodeLinkOffset + kPointerSize;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005247 static const int kInstructionSizeOffset = kGCMetadataOffset + kPointerSize;
5248 static const int kICAgeOffset = kInstructionSizeOffset + kIntSize;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005249 static const int kFlagsOffset = kICAgeOffset + kIntSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005250 static const int kKindSpecificFlags1Offset = kFlagsOffset + kIntSize;
5251 static const int kKindSpecificFlags2Offset =
5252 kKindSpecificFlags1Offset + kIntSize;
5253 // Note: We might be able to squeeze this into the flags above.
5254 static const int kPrologueOffset = kKindSpecificFlags2Offset + kIntSize;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005255 static const int kConstantPoolOffset = kPrologueOffset + kIntSize;
Ben Murdochda12d292016-06-02 14:46:10 +01005256 static const int kBuiltinIndexOffset =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005257 kConstantPoolOffset + kConstantPoolSize;
Ben Murdochda12d292016-06-02 14:46:10 +01005258 static const int kHeaderPaddingStart = kBuiltinIndexOffset + kIntSize;
Ben Murdochb0fe1622011-05-05 13:52:32 +01005259
Steve Blocka7e24c12009-10-30 11:49:00 +00005260 // Add padding to align the instruction start following right after
5261 // the Code object header.
5262 static const int kHeaderSize =
Ben Murdochb0fe1622011-05-05 13:52:32 +01005263 (kHeaderPaddingStart + kCodeAlignmentMask) & ~kCodeAlignmentMask;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005264
5265 class BodyDescriptor;
Steve Blocka7e24c12009-10-30 11:49:00 +00005266
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005267 // Byte offsets within kKindSpecificFlags1Offset.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005268 static const int kFullCodeFlags = kKindSpecificFlags1Offset;
Ben Murdoch589d6972011-11-30 16:04:58 +00005269 class FullCodeFlagsHasDeoptimizationSupportField:
5270 public BitField<bool, 0, 1> {}; // NOLINT
5271 class FullCodeFlagsHasDebugBreakSlotsField: public BitField<bool, 1, 1> {};
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005272 class FullCodeFlagsHasRelocInfoForSerialization
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005273 : public BitField<bool, 2, 1> {};
5274 // Bit 3 in this bitfield is unused.
5275 class ProfilerTicksField : public BitField<int, 4, 28> {};
Steve Blocka7e24c12009-10-30 11:49:00 +00005276
Ben Murdoch589d6972011-11-30 16:04:58 +00005277 // Flags layout. BitField<type, shift, size>.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005278 class ICStateField : public BitField<InlineCacheState, 0, 3> {};
Ben Murdochc5610432016-08-08 18:44:38 +01005279 class CacheHolderField : public BitField<CacheHolderFlag, 3, 2> {};
5280 class KindField : public BitField<Kind, 5, 5> {};
Ben Murdochda12d292016-06-02 14:46:10 +01005281 class ExtraICStateField
Ben Murdochc5610432016-08-08 18:44:38 +01005282 : public BitField<ExtraICState, 10, PlatformSmiTagging::kSmiValueSize -
5283 10 + 1> {}; // NOLINT
Steve Blocka7e24c12009-10-30 11:49:00 +00005284
Ben Murdochda12d292016-06-02 14:46:10 +01005285 // KindSpecificFlags1 layout (STUB, BUILTIN and OPTIMIZED_FUNCTION)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005286 static const int kStackSlotsFirstBit = 0;
5287 static const int kStackSlotsBitCount = 24;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005288 static const int kMarkedForDeoptimizationBit =
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005289 kStackSlotsFirstBit + kStackSlotsBitCount;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005290 static const int kIsTurbofannedBit = kMarkedForDeoptimizationBit + 1;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005291 static const int kCanHaveWeakObjects = kIsTurbofannedBit + 1;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005292
5293 STATIC_ASSERT(kStackSlotsFirstBit + kStackSlotsBitCount <= 32);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005294 STATIC_ASSERT(kCanHaveWeakObjects + 1 <= 32);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005295
5296 class StackSlotsField: public BitField<int,
5297 kStackSlotsFirstBit, kStackSlotsBitCount> {}; // NOLINT
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005298 class MarkedForDeoptimizationField
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005299 : public BitField<bool, kMarkedForDeoptimizationBit, 1> {}; // NOLINT
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005300 class IsTurbofannedField : public BitField<bool, kIsTurbofannedBit, 1> {
5301 }; // NOLINT
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005302 class CanHaveWeakObjectsField
5303 : public BitField<bool, kCanHaveWeakObjects, 1> {}; // NOLINT
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005304
5305 // KindSpecificFlags2 layout (ALL)
5306 static const int kIsCrankshaftedBit = 0;
5307 class IsCrankshaftedField: public BitField<bool,
5308 kIsCrankshaftedBit, 1> {}; // NOLINT
5309
5310 // KindSpecificFlags2 layout (STUB and OPTIMIZED_FUNCTION)
5311 static const int kSafepointTableOffsetFirstBit = kIsCrankshaftedBit + 1;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005312 static const int kSafepointTableOffsetBitCount = 30;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005313
5314 STATIC_ASSERT(kSafepointTableOffsetFirstBit +
5315 kSafepointTableOffsetBitCount <= 32);
5316 STATIC_ASSERT(1 + kSafepointTableOffsetBitCount <= 32);
5317
5318 class SafepointTableOffsetField: public BitField<int,
5319 kSafepointTableOffsetFirstBit,
5320 kSafepointTableOffsetBitCount> {}; // NOLINT
5321
5322 // KindSpecificFlags2 layout (FUNCTION)
5323 class BackEdgeTableOffsetField: public BitField<int,
5324 kIsCrankshaftedBit + 1, 27> {}; // NOLINT
5325 class AllowOSRAtLoopNestingLevelField: public BitField<int,
5326 kIsCrankshaftedBit + 1 + 27, 4> {}; // NOLINT
5327 STATIC_ASSERT(AllowOSRAtLoopNestingLevelField::kMax >= kMaxLoopNestingMarker);
5328
5329 static const int kArgumentsBits = 16;
5330 static const int kMaxArguments = (1 << kArgumentsBits) - 1;
Steve Blocka7e24c12009-10-30 11:49:00 +00005331
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005332 // This constant should be encodable in an ARM instruction.
Ben Murdochc5610432016-08-08 18:44:38 +01005333 static const int kFlagsNotUsedInLookup = CacheHolderField::kMask;
Steve Blocka7e24c12009-10-30 11:49:00 +00005334
5335 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005336 friend class RelocIterator;
5337 friend class Deoptimizer; // For FindCodeAgeSequence.
5338
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005339 // Code aging
5340 byte* FindCodeAgeSequence();
5341 static void GetCodeAgeAndParity(Code* code, Age* age,
5342 MarkingParity* parity);
5343 static void GetCodeAgeAndParity(Isolate* isolate, byte* sequence, Age* age,
5344 MarkingParity* parity);
5345 static Code* GetCodeAgeStub(Isolate* isolate, Age age, MarkingParity parity);
5346
5347 // Code aging -- platform-specific
5348 static void PatchPlatformCodeAge(Isolate* isolate,
5349 byte* sequence, Age age,
5350 MarkingParity parity);
5351
Steve Blocka7e24c12009-10-30 11:49:00 +00005352 DISALLOW_IMPLICIT_CONSTRUCTORS(Code);
5353};
5354
Ben Murdoch097c5b22016-05-18 11:27:45 +01005355class AbstractCode : public HeapObject {
5356 public:
Ben Murdochda12d292016-06-02 14:46:10 +01005357 // All code kinds and INTERPRETED_FUNCTION.
5358 enum Kind {
5359#define DEFINE_CODE_KIND_ENUM(name) name,
5360 CODE_KIND_LIST(DEFINE_CODE_KIND_ENUM)
5361#undef DEFINE_CODE_KIND_ENUM
5362 INTERPRETED_FUNCTION,
5363 };
5364
Ben Murdoch097c5b22016-05-18 11:27:45 +01005365 int SourcePosition(int offset);
5366 int SourceStatementPosition(int offset);
5367
Ben Murdochda12d292016-06-02 14:46:10 +01005368 // Returns the address of the first instruction.
5369 inline Address instruction_start();
5370
5371 // Returns the address right after the last instruction.
5372 inline Address instruction_end();
5373
5374 // Returns the of the code instructions.
5375 inline int instruction_size();
5376
5377 // Returns true if pc is inside this object's instructions.
5378 inline bool contains(byte* pc);
5379
5380 // Returns the AbstractCode::Kind of the code.
5381 inline Kind kind();
5382
5383 // Calculate the size of the code object to report for log events. This takes
5384 // the layout of the code object into account.
5385 inline int ExecutableSize();
5386
Ben Murdoch097c5b22016-05-18 11:27:45 +01005387 DECLARE_CAST(AbstractCode)
Ben Murdoch097c5b22016-05-18 11:27:45 +01005388 inline Code* GetCode();
5389 inline BytecodeArray* GetBytecodeArray();
5390};
Steve Blocka7e24c12009-10-30 11:49:00 +00005391
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005392// Dependent code is a singly linked list of fixed arrays. Each array contains
5393// code objects in weak cells for one dependent group. The suffix of the array
5394// can be filled with the undefined value if the number of codes is less than
5395// the length of the array.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005396//
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005397// +------+-----------------+--------+--------+-----+--------+-----------+-----+
5398// | next | count & group 1 | code 1 | code 2 | ... | code n | undefined | ... |
5399// +------+-----------------+--------+--------+-----+--------+-----------+-----+
5400// |
5401// V
5402// +------+-----------------+--------+--------+-----+--------+-----------+-----+
5403// | next | count & group 2 | code 1 | code 2 | ... | code m | undefined | ... |
5404// +------+-----------------+--------+--------+-----+--------+-----------+-----+
5405// |
5406// V
5407// empty_fixed_array()
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005408//
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005409// The list of fixed arrays is ordered by dependency groups.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005410
5411class DependentCode: public FixedArray {
5412 public:
5413 enum DependencyGroup {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005414 // Group of code that weakly embed this map and depend on being
5415 // deoptimized when the map is garbage collected.
5416 kWeakCodeGroup,
5417 // Group of code that embed a transition to this map, and depend on being
5418 // deoptimized when the transition is replaced by a new version.
5419 kTransitionGroup,
5420 // Group of code that omit run-time prototype checks for prototypes
5421 // described by this map. The group is deoptimized whenever an object
5422 // described by this map changes shape (and transitions to a new map),
5423 // possibly invalidating the assumptions embedded in the code.
5424 kPrototypeCheckGroup,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005425 // Group of code that depends on global property values in property cells
5426 // not being changed.
5427 kPropertyCellChangedGroup,
5428 // Group of code that omit run-time type checks for the field(s) introduced
5429 // by this map.
5430 kFieldTypeGroup,
5431 // Group of code that omit run-time type checks for initial maps of
5432 // constructors.
5433 kInitialMapChangedGroup,
5434 // Group of code that depends on tenuring information in AllocationSites
5435 // not being changed.
5436 kAllocationSiteTenuringChangedGroup,
5437 // Group of code that depends on element transition information in
5438 // AllocationSites not being changed.
5439 kAllocationSiteTransitionChangedGroup
5440 };
5441
5442 static const int kGroupCount = kAllocationSiteTransitionChangedGroup + 1;
5443
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005444 bool Contains(DependencyGroup group, WeakCell* code_cell);
5445 bool IsEmpty(DependencyGroup group);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005446
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005447 static Handle<DependentCode> InsertCompilationDependencies(
5448 Handle<DependentCode> entries, DependencyGroup group,
5449 Handle<Foreign> info);
5450
5451 static Handle<DependentCode> InsertWeakCode(Handle<DependentCode> entries,
5452 DependencyGroup group,
5453 Handle<WeakCell> code_cell);
5454
5455 void UpdateToFinishedCode(DependencyGroup group, Foreign* info,
5456 WeakCell* code_cell);
5457
5458 void RemoveCompilationDependencies(DependentCode::DependencyGroup group,
5459 Foreign* info);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005460
5461 void DeoptimizeDependentCodeGroup(Isolate* isolate,
5462 DependentCode::DependencyGroup group);
5463
5464 bool MarkCodeForDeoptimization(Isolate* isolate,
5465 DependentCode::DependencyGroup group);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005466
5467 // The following low-level accessors should only be used by this class
5468 // and the mark compact collector.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005469 inline DependentCode* next_link();
5470 inline void set_next_link(DependentCode* next);
5471 inline int count();
5472 inline void set_count(int value);
5473 inline DependencyGroup group();
5474 inline void set_group(DependencyGroup group);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005475 inline Object* object_at(int i);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005476 inline void set_object_at(int i, Object* object);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005477 inline void clear_at(int i);
5478 inline void copy(int from, int to);
5479 DECLARE_CAST(DependentCode)
5480
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005481 static const char* DependencyGroupName(DependencyGroup group);
5482 static void SetMarkedForDeoptimization(Code* code, DependencyGroup group);
5483
5484 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005485 static Handle<DependentCode> Insert(Handle<DependentCode> entries,
5486 DependencyGroup group,
5487 Handle<Object> object);
5488 static Handle<DependentCode> New(DependencyGroup group, Handle<Object> object,
5489 Handle<DependentCode> next);
5490 static Handle<DependentCode> EnsureSpace(Handle<DependentCode> entries);
5491 // Compact by removing cleared weak cells and return true if there was
5492 // any cleared weak cell.
5493 bool Compact();
5494 static int Grow(int number_of_entries) {
5495 if (number_of_entries < 5) return number_of_entries + 1;
5496 return number_of_entries * 5 / 4;
5497 }
5498 inline int flags();
5499 inline void set_flags(int flags);
5500 class GroupField : public BitField<int, 0, 3> {};
5501 class CountField : public BitField<int, 3, 27> {};
5502 STATIC_ASSERT(kGroupCount <= GroupField::kMax + 1);
5503 static const int kNextLinkIndex = 0;
5504 static const int kFlagsIndex = 1;
5505 static const int kCodesStartIndex = 2;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005506};
5507
5508
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005509class PrototypeInfo;
5510
5511
Steve Blocka7e24c12009-10-30 11:49:00 +00005512// All heap objects have a Map that describes their structure.
5513// A Map contains information about:
5514// - Size information about the object
5515// - How to iterate over an object (for garbage collection)
5516class Map: public HeapObject {
5517 public:
5518 // Instance size.
Steve Block791712a2010-08-27 10:21:07 +01005519 // Size in bytes or kVariableSizeSentinel if instances do not have
5520 // a fixed size.
Steve Blocka7e24c12009-10-30 11:49:00 +00005521 inline int instance_size();
5522 inline void set_instance_size(int value);
5523
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005524 // Only to clear an unused byte, remove once byte is used.
5525 inline void clear_unused();
Steve Blocka7e24c12009-10-30 11:49:00 +00005526
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005527 // [inobject_properties_or_constructor_function_index]: Provides access
5528 // to the inobject properties in case of JSObject maps, or the constructor
5529 // function index in case of primitive maps.
5530 inline int inobject_properties_or_constructor_function_index();
5531 inline void set_inobject_properties_or_constructor_function_index(int value);
5532 // Count of properties allocated in the object (JSObject only).
5533 inline int GetInObjectProperties();
5534 inline void SetInObjectProperties(int value);
5535 // Index of the constructor function in the native context (primitives only),
5536 // or the special sentinel value to indicate that there is no object wrapper
5537 // for the primitive (i.e. in case of null or undefined).
5538 static const int kNoConstructorFunctionIndex = 0;
5539 inline int GetConstructorFunctionIndex();
5540 inline void SetConstructorFunctionIndex(int value);
5541 static MaybeHandle<JSFunction> GetConstructorFunction(
5542 Handle<Map> map, Handle<Context> native_context);
Steve Blocka7e24c12009-10-30 11:49:00 +00005543
Ben Murdochda12d292016-06-02 14:46:10 +01005544 // Retrieve interceptors.
5545 inline InterceptorInfo* GetNamedInterceptor();
5546 inline InterceptorInfo* GetIndexedInterceptor();
5547
Steve Blocka7e24c12009-10-30 11:49:00 +00005548 // Instance type.
5549 inline InstanceType instance_type();
5550 inline void set_instance_type(InstanceType value);
5551
5552 // Tells how many unused property fields are available in the
5553 // instance (only used for JSObject in fast mode).
5554 inline int unused_property_fields();
5555 inline void set_unused_property_fields(int value);
5556
5557 // Bit field.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005558 inline byte bit_field() const;
Steve Blocka7e24c12009-10-30 11:49:00 +00005559 inline void set_bit_field(byte value);
5560
5561 // Bit field 2.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005562 inline byte bit_field2() const;
Steve Blocka7e24c12009-10-30 11:49:00 +00005563 inline void set_bit_field2(byte value);
5564
Ben Murdoch257744e2011-11-30 15:57:28 +00005565 // Bit field 3.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005566 inline uint32_t bit_field3() const;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005567 inline void set_bit_field3(uint32_t bits);
5568
5569 class EnumLengthBits: public BitField<int,
5570 0, kDescriptorIndexBitCount> {}; // NOLINT
5571 class NumberOfOwnDescriptorsBits: public BitField<int,
5572 kDescriptorIndexBitCount, kDescriptorIndexBitCount> {}; // NOLINT
5573 STATIC_ASSERT(kDescriptorIndexBitCount + kDescriptorIndexBitCount == 20);
5574 class DictionaryMap : public BitField<bool, 20, 1> {};
5575 class OwnsDescriptors : public BitField<bool, 21, 1> {};
Ben Murdoch097c5b22016-05-18 11:27:45 +01005576 class HasHiddenPrototype : public BitField<bool, 22, 1> {};
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005577 class Deprecated : public BitField<bool, 23, 1> {};
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005578 class IsUnstable : public BitField<bool, 24, 1> {};
5579 class IsMigrationTarget : public BitField<bool, 25, 1> {};
Ben Murdochda12d292016-06-02 14:46:10 +01005580 // Bit 26 is free.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005581 class NewTargetIsBase : public BitField<bool, 27, 1> {};
5582 // Bit 28 is free.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005583
5584 // Keep this bit field at the very end for better code in
5585 // Builtins::kJSConstructStubGeneric stub.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005586 // This counter is used for in-object slack tracking.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005587 // The in-object slack tracking is considered enabled when the counter is
Ben Murdoch097c5b22016-05-18 11:27:45 +01005588 // non zero. The counter only has a valid count for initial maps. For
5589 // transitioned maps only kNoSlackTracking has a meaning, namely that inobject
5590 // slack tracking already finished for the transition tree. Any other value
5591 // indicates that either inobject slack tracking is still in progress, or that
5592 // the map isn't part of the transition tree anymore.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005593 class ConstructionCounter : public BitField<int, 29, 3> {};
5594 static const int kSlackTrackingCounterStart = 7;
5595 static const int kSlackTrackingCounterEnd = 1;
5596 static const int kNoSlackTracking = 0;
5597 STATIC_ASSERT(kSlackTrackingCounterStart <= ConstructionCounter::kMax);
5598
5599
5600 // Inobject slack tracking is the way to reclaim unused inobject space.
5601 //
5602 // The instance size is initially determined by adding some slack to
5603 // expected_nof_properties (to allow for a few extra properties added
5604 // after the constructor). There is no guarantee that the extra space
5605 // will not be wasted.
5606 //
5607 // Here is the algorithm to reclaim the unused inobject space:
5608 // - Detect the first constructor call for this JSFunction.
5609 // When it happens enter the "in progress" state: initialize construction
5610 // counter in the initial_map.
5611 // - While the tracking is in progress initialize unused properties of a new
5612 // object with one_pointer_filler_map instead of undefined_value (the "used"
5613 // part is initialized with undefined_value as usual). This way they can
5614 // be resized quickly and safely.
5615 // - Once enough objects have been created compute the 'slack'
5616 // (traverse the map transition tree starting from the
5617 // initial_map and find the lowest value of unused_property_fields).
5618 // - Traverse the transition tree again and decrease the instance size
5619 // of every map. Existing objects will resize automatically (they are
5620 // filled with one_pointer_filler_map). All further allocations will
5621 // use the adjusted instance size.
5622 // - SharedFunctionInfo's expected_nof_properties left unmodified since
5623 // allocations made using different closures could actually create different
5624 // kind of objects (see prototype inheritance pattern).
5625 //
5626 // Important: inobject slack tracking is not attempted during the snapshot
5627 // creation.
5628
5629 static const int kGenerousAllocationCount =
5630 kSlackTrackingCounterStart - kSlackTrackingCounterEnd + 1;
5631
5632 // Starts the tracking by initializing object constructions countdown counter.
5633 void StartInobjectSlackTracking();
5634
5635 // True if the object constructions countdown counter is a range
5636 // [kSlackTrackingCounterEnd, kSlackTrackingCounterStart].
5637 inline bool IsInobjectSlackTrackingInProgress();
5638
5639 // Does the tracking step.
5640 inline void InobjectSlackTrackingStep();
5641
5642 // Completes inobject slack tracking for the transition tree starting at this
5643 // initial map.
5644 void CompleteInobjectSlackTracking();
Ben Murdoch257744e2011-11-30 15:57:28 +00005645
Steve Blocka7e24c12009-10-30 11:49:00 +00005646 // Tells whether the object in the prototype property will be used
5647 // for instances created from this function. If the prototype
5648 // property is set to a value that is not a JSObject, the prototype
5649 // property will not be used to create instances of the function.
5650 // See ECMA-262, 13.2.2.
5651 inline void set_non_instance_prototype(bool value);
5652 inline bool has_non_instance_prototype();
5653
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005654 // Tells whether the instance has a [[Construct]] internal method.
5655 // This property is implemented according to ES6, section 7.2.4.
Ben Murdoch097c5b22016-05-18 11:27:45 +01005656 inline void set_is_constructor(bool value);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005657 inline bool is_constructor() const;
Steve Block6ded16b2010-05-10 14:33:55 +01005658
Ben Murdoch097c5b22016-05-18 11:27:45 +01005659 // Tells whether the instance with this map has a hidden prototype.
5660 inline void set_has_hidden_prototype(bool value);
5661 inline bool has_hidden_prototype() const;
Steve Blocka7e24c12009-10-30 11:49:00 +00005662
5663 // Records and queries whether the instance has a named interceptor.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005664 inline void set_has_named_interceptor();
5665 inline bool has_named_interceptor();
Steve Blocka7e24c12009-10-30 11:49:00 +00005666
5667 // Records and queries whether the instance has an indexed interceptor.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005668 inline void set_has_indexed_interceptor();
5669 inline bool has_indexed_interceptor();
Steve Blocka7e24c12009-10-30 11:49:00 +00005670
5671 // Tells whether the instance is undetectable.
5672 // An undetectable object is a special class of JSObject: 'typeof' operator
5673 // returns undefined, ToBoolean returns false. Otherwise it behaves like
5674 // a normal JS object. It is useful for implementing undetectable
5675 // document.all in Firefox & Safari.
5676 // See https://bugzilla.mozilla.org/show_bug.cgi?id=248549.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005677 inline void set_is_undetectable();
5678 inline bool is_undetectable();
Steve Blocka7e24c12009-10-30 11:49:00 +00005679
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005680 // Tells whether the instance has a [[Call]] internal method.
5681 // This property is implemented according to ES6, section 7.2.3.
5682 inline void set_is_callable();
5683 inline bool is_callable() const;
Steve Blocka7e24c12009-10-30 11:49:00 +00005684
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005685 inline void set_new_target_is_base(bool value);
5686 inline bool new_target_is_base();
Steve Block8defd9f2010-07-08 12:39:36 +01005687 inline void set_is_extensible(bool value);
5688 inline bool is_extensible();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005689 inline void set_is_prototype_map(bool value);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005690 inline bool is_prototype_map() const;
Steve Block8defd9f2010-07-08 12:39:36 +01005691
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005692 inline void set_elements_kind(ElementsKind elements_kind);
5693 inline ElementsKind elements_kind();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005694
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005695 // Tells whether the instance has fast elements that are only Smis.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005696 inline bool has_fast_smi_elements();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005697
Steve Block8defd9f2010-07-08 12:39:36 +01005698 // Tells whether the instance has fast elements.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005699 inline bool has_fast_object_elements();
5700 inline bool has_fast_smi_or_object_elements();
5701 inline bool has_fast_double_elements();
5702 inline bool has_fast_elements();
5703 inline bool has_sloppy_arguments_elements();
Ben Murdoch097c5b22016-05-18 11:27:45 +01005704 inline bool has_fast_string_wrapper_elements();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005705 inline bool has_fixed_typed_array_elements();
5706 inline bool has_dictionary_elements();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005707
5708 static bool IsValidElementsTransition(ElementsKind from_kind,
5709 ElementsKind to_kind);
5710
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005711 // Returns true if the current map doesn't have DICTIONARY_ELEMENTS but if a
5712 // map with DICTIONARY_ELEMENTS was found in the prototype chain.
5713 bool DictionaryElementsInPrototypeChainOnly();
Kristian Monsen0d5e1162010-09-30 15:31:59 +01005714
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005715 inline Map* ElementsTransitionMap();
Kristian Monsen0d5e1162010-09-30 15:31:59 +01005716
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005717 inline FixedArrayBase* GetInitialElements();
Kristian Monsen0d5e1162010-09-30 15:31:59 +01005718
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005719 // [raw_transitions]: Provides access to the transitions storage field.
5720 // Don't call set_raw_transitions() directly to overwrite transitions, use
5721 // the TransitionArray::ReplaceTransitions() wrapper instead!
5722 DECL_ACCESSORS(raw_transitions, Object)
5723 // [prototype_info]: Per-prototype metadata. Aliased with transitions
5724 // (which prototype maps don't have).
5725 DECL_ACCESSORS(prototype_info, Object)
5726 // PrototypeInfo is created lazily using this helper (which installs it on
5727 // the given prototype's map).
5728 static Handle<PrototypeInfo> GetOrCreatePrototypeInfo(
5729 Handle<JSObject> prototype, Isolate* isolate);
5730 static Handle<PrototypeInfo> GetOrCreatePrototypeInfo(
5731 Handle<Map> prototype_map, Isolate* isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005732
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005733 // [prototype chain validity cell]: Associated with a prototype object,
5734 // stored in that object's map's PrototypeInfo, indicates that prototype
5735 // chains through this object are currently valid. The cell will be
5736 // invalidated and replaced when the prototype chain changes.
5737 static Handle<Cell> GetOrCreatePrototypeChainValidityCell(Handle<Map> map,
5738 Isolate* isolate);
5739 static const int kPrototypeChainValid = 0;
5740 static const int kPrototypeChainInvalid = 1;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005741
5742 Map* FindRootMap();
5743 Map* FindFieldOwner(int descriptor);
5744
5745 inline int GetInObjectPropertyOffset(int index);
5746
5747 int NumberOfFields();
5748
5749 // TODO(ishell): candidate with JSObject::MigrateToMap().
Ben Murdochc5610432016-08-08 18:44:38 +01005750 bool InstancesNeedRewriting(Map* target);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005751 bool InstancesNeedRewriting(Map* target, int target_number_of_fields,
5752 int target_inobject, int target_unused,
5753 int* old_number_of_fields);
5754 // TODO(ishell): moveit!
5755 static Handle<Map> GeneralizeAllFieldRepresentations(Handle<Map> map);
Ben Murdoch097c5b22016-05-18 11:27:45 +01005756 MUST_USE_RESULT static Handle<FieldType> GeneralizeFieldType(
5757 Representation rep1, Handle<FieldType> type1, Representation rep2,
5758 Handle<FieldType> type2, Isolate* isolate);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005759 static void GeneralizeFieldType(Handle<Map> map, int modify_index,
5760 Representation new_representation,
Ben Murdoch097c5b22016-05-18 11:27:45 +01005761 Handle<FieldType> new_field_type);
Ben Murdochc5610432016-08-08 18:44:38 +01005762
5763 static inline Handle<Map> ReconfigureProperty(
5764 Handle<Map> map, int modify_index, PropertyKind new_kind,
5765 PropertyAttributes new_attributes, Representation new_representation,
5766 Handle<FieldType> new_field_type, StoreMode store_mode);
5767
5768 static inline Handle<Map> ReconfigureElementsKind(
5769 Handle<Map> map, ElementsKind new_elements_kind);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005770
5771 static Handle<Map> PrepareForDataProperty(Handle<Map> old_map,
5772 int descriptor_number,
5773 Handle<Object> value);
5774
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005775 static Handle<Map> Normalize(Handle<Map> map, PropertyNormalizationMode mode,
5776 const char* reason);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005777
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005778 // Tells whether the map is used for JSObjects in dictionary mode (ie
5779 // normalized objects, ie objects for which HasFastProperties returns false).
5780 // A map can never be used for both dictionary mode and fast mode JSObjects.
5781 // False by default and for HeapObjects that are not JSObjects.
5782 inline void set_dictionary_map(bool value);
5783 inline bool is_dictionary_map();
Kristian Monsen0d5e1162010-09-30 15:31:59 +01005784
Steve Blocka7e24c12009-10-30 11:49:00 +00005785 // Tells whether the instance needs security checks when accessing its
5786 // properties.
5787 inline void set_is_access_check_needed(bool access_check_needed);
5788 inline bool is_access_check_needed();
5789
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005790 // Returns true if map has a non-empty stub code cache.
5791 inline bool has_code_cache();
5792
Steve Blocka7e24c12009-10-30 11:49:00 +00005793 // [prototype]: implicit prototype object.
5794 DECL_ACCESSORS(prototype, Object)
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005795 // TODO(jkummerow): make set_prototype private.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005796 static void SetPrototype(
5797 Handle<Map> map, Handle<Object> prototype,
5798 PrototypeOptimizationMode proto_mode = FAST_PROTOTYPE);
Steve Blocka7e24c12009-10-30 11:49:00 +00005799
5800 // [constructor]: points back to the function responsible for this map.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005801 // The field overlaps with the back pointer. All maps in a transition tree
5802 // have the same constructor, so maps with back pointers can walk the
5803 // back pointer chain until they find the map holding their constructor.
5804 DECL_ACCESSORS(constructor_or_backpointer, Object)
5805 inline Object* GetConstructor() const;
5806 inline void SetConstructor(Object* constructor,
5807 WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
5808 // [back pointer]: points back to the parent map from which a transition
5809 // leads to this map. The field overlaps with the constructor (see above).
5810 inline Object* GetBackPointer();
5811 inline void SetBackPointer(Object* value,
5812 WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
Steve Blocka7e24c12009-10-30 11:49:00 +00005813
5814 // [instance descriptors]: describes the object.
5815 DECL_ACCESSORS(instance_descriptors, DescriptorArray)
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005816
5817 // [layout descriptor]: describes the object layout.
5818 DECL_ACCESSORS(layout_descriptor, LayoutDescriptor)
5819 // |layout descriptor| accessor which can be used from GC.
5820 inline LayoutDescriptor* layout_descriptor_gc_safe();
5821 inline bool HasFastPointerLayout() const;
5822
5823 // |layout descriptor| accessor that is safe to call even when
5824 // FLAG_unbox_double_fields is disabled (in this case Map does not contain
5825 // |layout_descriptor| field at all).
5826 inline LayoutDescriptor* GetLayoutDescriptor();
5827
5828 inline void UpdateDescriptors(DescriptorArray* descriptors,
5829 LayoutDescriptor* layout_descriptor);
5830 inline void InitializeDescriptors(DescriptorArray* descriptors,
5831 LayoutDescriptor* layout_descriptor);
Ben Murdoch257744e2011-11-30 15:57:28 +00005832
Steve Blocka7e24c12009-10-30 11:49:00 +00005833 // [stub cache]: contains stubs compiled for this map.
Steve Block6ded16b2010-05-10 14:33:55 +01005834 DECL_ACCESSORS(code_cache, Object)
Steve Blocka7e24c12009-10-30 11:49:00 +00005835
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005836 // [dependent code]: list of optimized codes that weakly embed this map.
5837 DECL_ACCESSORS(dependent_code, DependentCode)
5838
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005839 // [weak cell cache]: cache that stores a weak cell pointing to this map.
5840 DECL_ACCESSORS(weak_cell_cache, Object)
Kristian Monsen80d68ea2010-09-08 11:05:35 +01005841
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005842 inline PropertyDetails GetLastDescriptorDetails();
5843
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005844 inline int LastAdded();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005845
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005846 inline int NumberOfOwnDescriptors();
5847 inline void SetNumberOfOwnDescriptors(int number);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005848
5849 inline Cell* RetrieveDescriptorsPointer();
5850
Ben Murdoch097c5b22016-05-18 11:27:45 +01005851 // Checks whether all properties are stored either in the map or on the object
5852 // (inobject, properties, or elements backing store), requiring no special
5853 // checks.
5854 bool OnlyHasSimpleProperties();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005855 inline int EnumLength();
5856 inline void SetEnumLength(int length);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005857
5858 inline bool owns_descriptors();
5859 inline void set_owns_descriptors(bool owns_descriptors);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005860 inline void mark_unstable();
5861 inline bool is_stable();
5862 inline void set_migration_target(bool value);
5863 inline bool is_migration_target();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005864 inline void set_construction_counter(int value);
5865 inline int construction_counter();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005866 inline void deprecate();
5867 inline bool is_deprecated();
5868 inline bool CanBeDeprecated();
5869 // Returns a non-deprecated version of the input. If the input was not
5870 // deprecated, it is directly returned. Otherwise, the non-deprecated version
5871 // is found by re-transitioning from the root of the transition tree using the
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005872 // descriptor array of the map. Returns MaybeHandle<Map>() if no updated map
5873 // is found.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005874 static MaybeHandle<Map> TryUpdate(Handle<Map> map) WARN_UNUSED_RESULT;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005875
5876 // Returns a non-deprecated version of the input. This method may deprecate
5877 // existing maps along the way if encodings conflict. Not for use while
5878 // gathering type feedback. Use TryUpdate in those cases instead.
5879 static Handle<Map> Update(Handle<Map> map);
5880
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005881 static inline Handle<Map> CopyInitialMap(Handle<Map> map);
5882 static Handle<Map> CopyInitialMap(Handle<Map> map, int instance_size,
5883 int in_object_properties,
5884 int unused_property_fields);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005885 static Handle<Map> CopyDropDescriptors(Handle<Map> map);
5886 static Handle<Map> CopyInsertDescriptor(Handle<Map> map,
5887 Descriptor* descriptor,
5888 TransitionFlag flag);
5889
5890 MUST_USE_RESULT static MaybeHandle<Map> CopyWithField(
Ben Murdoch097c5b22016-05-18 11:27:45 +01005891 Handle<Map> map, Handle<Name> name, Handle<FieldType> type,
5892 PropertyAttributes attributes, Representation representation,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005893 TransitionFlag flag);
5894
5895 MUST_USE_RESULT static MaybeHandle<Map> CopyWithConstant(
5896 Handle<Map> map,
5897 Handle<Name> name,
5898 Handle<Object> constant,
5899 PropertyAttributes attributes,
5900 TransitionFlag flag);
5901
5902 // Returns a new map with all transitions dropped from the given map and
5903 // the ElementsKind set.
5904 static Handle<Map> TransitionElementsTo(Handle<Map> map,
5905 ElementsKind to_kind);
5906
5907 static Handle<Map> AsElementsKind(Handle<Map> map, ElementsKind kind);
5908
5909 static Handle<Map> CopyAsElementsKind(Handle<Map> map,
5910 ElementsKind kind,
5911 TransitionFlag flag);
5912
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005913 static Handle<Map> AsLanguageMode(Handle<Map> initial_map,
5914 LanguageMode language_mode,
5915 FunctionKind kind);
5916
5917
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005918 static Handle<Map> CopyForPreventExtensions(Handle<Map> map,
5919 PropertyAttributes attrs_to_add,
5920 Handle<Symbol> transition_marker,
5921 const char* reason);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005922
5923 static Handle<Map> FixProxy(Handle<Map> map, InstanceType type, int size);
5924
5925
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005926 // Maximal number of fast properties. Used to restrict the number of map
5927 // transitions to avoid an explosion in the number of maps for objects used as
5928 // dictionaries.
5929 inline bool TooManyFastProperties(StoreFromKeyed store_mode);
5930 static Handle<Map> TransitionToDataProperty(Handle<Map> map,
5931 Handle<Name> name,
5932 Handle<Object> value,
5933 PropertyAttributes attributes,
5934 StoreFromKeyed store_mode);
5935 static Handle<Map> TransitionToAccessorProperty(
Ben Murdochc5610432016-08-08 18:44:38 +01005936 Isolate* isolate, Handle<Map> map, Handle<Name> name, int descriptor,
5937 Handle<Object> getter, Handle<Object> setter,
Ben Murdochda12d292016-06-02 14:46:10 +01005938 PropertyAttributes attributes);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005939 static Handle<Map> ReconfigureExistingProperty(Handle<Map> map,
5940 int descriptor,
5941 PropertyKind kind,
5942 PropertyAttributes attributes);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005943
5944 inline void AppendDescriptor(Descriptor* desc);
Steve Blocka7e24c12009-10-30 11:49:00 +00005945
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005946 // Returns a copy of the map, prepared for inserting into the transition
5947 // tree (if the |map| owns descriptors then the new one will share
5948 // descriptors with |map|).
5949 static Handle<Map> CopyForTransition(Handle<Map> map, const char* reason);
5950
Steve Blocka7e24c12009-10-30 11:49:00 +00005951 // Returns a copy of the map, with all transitions dropped from the
5952 // instance descriptors.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005953 static Handle<Map> Copy(Handle<Map> map, const char* reason);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005954 static Handle<Map> Create(Isolate* isolate, int inobject_properties);
Steve Blocka7e24c12009-10-30 11:49:00 +00005955
5956 // Returns the next free property index (only valid for FAST MODE).
5957 int NextFreePropertyIndex();
5958
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005959 // Returns the number of properties described in instance_descriptors
5960 // filtering out properties with the specified attributes.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005961 int NumberOfDescribedProperties(DescriptorFlag which = OWN_DESCRIPTORS,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005962 PropertyFilter filter = ALL_PROPERTIES);
Steve Blocka7e24c12009-10-30 11:49:00 +00005963
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005964 DECLARE_CAST(Map)
Steve Blocka7e24c12009-10-30 11:49:00 +00005965
5966 // Code cache operations.
5967
5968 // Clears the code cache.
Steve Block44f0eee2011-05-26 01:26:41 +01005969 inline void ClearCodeCache(Heap* heap);
Steve Blocka7e24c12009-10-30 11:49:00 +00005970
5971 // Update code cache.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005972 static void UpdateCodeCache(Handle<Map> map,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005973 Handle<Name> name,
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005974 Handle<Code> code);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005975
5976 // Extend the descriptor array of the map with the list of descriptors.
5977 // In case of duplicates, the latest descriptor is used.
5978 static void AppendCallbackDescriptors(Handle<Map> map,
5979 Handle<Object> descriptors);
5980
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005981 static inline int SlackForArraySize(int old_size, int size_limit);
5982
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005983 static void EnsureDescriptorSlack(Handle<Map> map, int slack);
Steve Blocka7e24c12009-10-30 11:49:00 +00005984
Ben Murdochc5610432016-08-08 18:44:38 +01005985 Code* LookupInCodeCache(Name* name, Code::Flags code);
Steve Blocka7e24c12009-10-30 11:49:00 +00005986
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005987 // Computes a hash value for this map, to be used in HashTables and such.
5988 int Hash();
5989
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005990 // Returns the transitioned map for this map with the most generic
Ben Murdochc5610432016-08-08 18:44:38 +01005991 // elements_kind that's found in |candidates|, or |nullptr| if no match is
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005992 // found at all.
Ben Murdochc5610432016-08-08 18:44:38 +01005993 Map* FindElementsKindTransitionedMap(MapHandleList* candidates);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005994
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005995 inline bool CanTransition();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005996
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005997 inline bool IsBooleanMap();
5998 inline bool IsPrimitiveMap();
5999 inline bool IsJSReceiverMap();
6000 inline bool IsJSObjectMap();
6001 inline bool IsJSArrayMap();
6002 inline bool IsJSFunctionMap();
6003 inline bool IsStringMap();
6004 inline bool IsJSProxyMap();
6005 inline bool IsJSGlobalProxyMap();
6006 inline bool IsJSGlobalObjectMap();
6007 inline bool IsJSTypedArrayMap();
6008 inline bool IsJSDataViewMap();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006009
6010 inline bool CanOmitMapChecks();
6011
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006012 static void AddDependentCode(Handle<Map> map,
6013 DependentCode::DependencyGroup group,
6014 Handle<Code> code);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006015
6016 bool IsMapInArrayPrototypeChain();
Ben Murdoch592a9fc2012-03-05 11:04:45 +00006017
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006018 static Handle<WeakCell> WeakCellForMap(Handle<Map> map);
6019
Steve Blocka7e24c12009-10-30 11:49:00 +00006020 // Dispatched behavior.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006021 DECLARE_PRINTER(Map)
6022 DECLARE_VERIFIER(Map)
6023
6024#ifdef VERIFY_HEAP
6025 void DictionaryMapVerify();
6026 void VerifyOmittedMapChecks();
Steve Blocka7e24c12009-10-30 11:49:00 +00006027#endif
6028
Iain Merrick75681382010-08-19 15:07:18 +01006029 inline int visitor_id();
6030 inline void set_visitor_id(int visitor_id);
Ben Murdoch3bec4d22010-07-22 14:51:16 +01006031
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006032 static Handle<Map> TransitionToPrototype(Handle<Map> map,
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006033 Handle<Object> prototype,
6034 PrototypeOptimizationMode mode);
Steve Block053d10c2011-06-13 19:13:29 +01006035
Steve Blocka7e24c12009-10-30 11:49:00 +00006036 static const int kMaxPreAllocatedPropertyFields = 255;
6037
6038 // Layout description.
6039 static const int kInstanceSizesOffset = HeapObject::kHeaderSize;
6040 static const int kInstanceAttributesOffset = kInstanceSizesOffset + kIntSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006041 static const int kBitField3Offset = kInstanceAttributesOffset + kIntSize;
6042 static const int kPrototypeOffset = kBitField3Offset + kPointerSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006043 static const int kConstructorOrBackPointerOffset =
6044 kPrototypeOffset + kPointerSize;
6045 // When there is only one transition, it is stored directly in this field;
6046 // otherwise a transition array is used.
6047 // For prototype maps, this slot is used to store this map's PrototypeInfo
6048 // struct.
6049 static const int kTransitionsOrPrototypeInfoOffset =
6050 kConstructorOrBackPointerOffset + kPointerSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006051 static const int kDescriptorsOffset =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006052 kTransitionsOrPrototypeInfoOffset + kPointerSize;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006053#if V8_DOUBLE_FIELDS_UNBOXING
6054 static const int kLayoutDecriptorOffset = kDescriptorsOffset + kPointerSize;
6055 static const int kCodeCacheOffset = kLayoutDecriptorOffset + kPointerSize;
6056#else
6057 static const int kLayoutDecriptorOffset = 1; // Must not be ever accessed.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006058 static const int kCodeCacheOffset = kDescriptorsOffset + kPointerSize;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006059#endif
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006060 static const int kDependentCodeOffset = kCodeCacheOffset + kPointerSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006061 static const int kWeakCellCacheOffset = kDependentCodeOffset + kPointerSize;
6062 static const int kSize = kWeakCellCacheOffset + kPointerSize;
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01006063
6064 // Layout of pointer fields. Heap iteration code relies on them
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006065 // being continuously allocated.
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01006066 static const int kPointerFieldsBeginOffset = Map::kPrototypeOffset;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006067 static const int kPointerFieldsEndOffset = kSize;
Steve Blocka7e24c12009-10-30 11:49:00 +00006068
6069 // Byte offsets within kInstanceSizesOffset.
6070 static const int kInstanceSizeOffset = kInstanceSizesOffset + 0;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006071 static const int kInObjectPropertiesOrConstructorFunctionIndexByte = 1;
6072 static const int kInObjectPropertiesOrConstructorFunctionIndexOffset =
6073 kInstanceSizesOffset + kInObjectPropertiesOrConstructorFunctionIndexByte;
6074 // Note there is one byte available for use here.
6075 static const int kUnusedByte = 2;
6076 static const int kUnusedOffset = kInstanceSizesOffset + kUnusedByte;
Iain Merrick9ac36c92010-09-13 15:29:50 +01006077 static const int kVisitorIdByte = 3;
6078 static const int kVisitorIdOffset = kInstanceSizesOffset + kVisitorIdByte;
Steve Blocka7e24c12009-10-30 11:49:00 +00006079
6080 // Byte offsets within kInstanceAttributesOffset attributes.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006081#if V8_TARGET_LITTLE_ENDIAN
6082 // Order instance type and bit field together such that they can be loaded
6083 // together as a 16-bit word with instance type in the lower 8 bits regardless
6084 // of endianess. Also provide endian-independent offset to that 16-bit word.
Steve Blocka7e24c12009-10-30 11:49:00 +00006085 static const int kInstanceTypeOffset = kInstanceAttributesOffset + 0;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006086 static const int kBitFieldOffset = kInstanceAttributesOffset + 1;
6087#else
6088 static const int kBitFieldOffset = kInstanceAttributesOffset + 0;
6089 static const int kInstanceTypeOffset = kInstanceAttributesOffset + 1;
6090#endif
6091 static const int kInstanceTypeAndBitFieldOffset =
6092 kInstanceAttributesOffset + 0;
6093 static const int kBitField2Offset = kInstanceAttributesOffset + 2;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006094 static const int kUnusedPropertyFieldsByte = 3;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006095 static const int kUnusedPropertyFieldsOffset = kInstanceAttributesOffset + 3;
Steve Blocka7e24c12009-10-30 11:49:00 +00006096
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006097 STATIC_ASSERT(kInstanceTypeAndBitFieldOffset ==
6098 Internals::kMapInstanceTypeAndBitFieldOffset);
Steve Blocka7e24c12009-10-30 11:49:00 +00006099
6100 // Bit positions for bit field.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006101 static const int kHasNonInstancePrototype = 0;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006102 static const int kIsCallable = 1;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006103 static const int kHasNamedInterceptor = 2;
6104 static const int kHasIndexedInterceptor = 3;
6105 static const int kIsUndetectable = 4;
Ben Murdochc5610432016-08-08 18:44:38 +01006106 static const int kIsAccessCheckNeeded = 5;
6107 static const int kIsConstructor = 6;
6108 // Bit 7 is free.
Steve Blocka7e24c12009-10-30 11:49:00 +00006109
6110 // Bit positions for bit field 2
Andrei Popescu31002712010-02-23 13:46:05 +00006111 static const int kIsExtensible = 0;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006112 // Bit 1 is free.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006113 class IsPrototypeMapBits : public BitField<bool, 2, 1> {};
6114 class ElementsKindBits: public BitField<ElementsKind, 3, 5> {};
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00006115
6116 // Derived values from bit field 2
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00006117 static const int8_t kMaximumBitField2FastElementValue = static_cast<int8_t>(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006118 (FAST_ELEMENTS + 1) << Map::ElementsKindBits::kShift) - 1;
6119 static const int8_t kMaximumBitField2FastSmiElementValue =
6120 static_cast<int8_t>((FAST_SMI_ELEMENTS + 1) <<
6121 Map::ElementsKindBits::kShift) - 1;
6122 static const int8_t kMaximumBitField2FastHoleyElementValue =
6123 static_cast<int8_t>((FAST_HOLEY_ELEMENTS + 1) <<
6124 Map::ElementsKindBits::kShift) - 1;
6125 static const int8_t kMaximumBitField2FastHoleySmiElementValue =
6126 static_cast<int8_t>((FAST_HOLEY_SMI_ELEMENTS + 1) <<
6127 Map::ElementsKindBits::kShift) - 1;
Steve Blocka7e24c12009-10-30 11:49:00 +00006128
Iain Merrick75681382010-08-19 15:07:18 +01006129 typedef FixedBodyDescriptor<kPointerFieldsBeginOffset,
6130 kPointerFieldsEndOffset,
6131 kSize> BodyDescriptor;
6132
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006133 // Compares this map to another to see if they describe equivalent objects.
6134 // If |mode| is set to CLEAR_INOBJECT_PROPERTIES, |other| is treated as if
6135 // it had exactly zero inobject properties.
6136 // The "shared" flags of both this map and |other| are ignored.
6137 bool EquivalentToForNormalization(Map* other, PropertyNormalizationMode mode);
6138
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006139 // Returns true if given field is unboxed double.
6140 inline bool IsUnboxedDoubleField(FieldIndex index);
6141
6142#if TRACE_MAPS
6143 static void TraceTransition(const char* what, Map* from, Map* to, Name* name);
6144 static void TraceAllTransitions(Map* map);
6145#endif
6146
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006147 static inline Handle<Map> AddMissingTransitionsForTesting(
6148 Handle<Map> split_map, Handle<DescriptorArray> descriptors,
6149 Handle<LayoutDescriptor> full_layout_descriptor);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006150
Steve Blocka7e24c12009-10-30 11:49:00 +00006151 private:
Ben Murdochc5610432016-08-08 18:44:38 +01006152 // Returns the map that this (root) map transitions to if its elements_kind
6153 // is changed to |elements_kind|, or |nullptr| if no such map is cached yet.
6154 Map* LookupElementsTransitionMap(ElementsKind elements_kind);
6155
6156 // Tries to replay property transitions starting from this (root) map using
6157 // the descriptor array of the |map|. The |root_map| is expected to have
6158 // proper elements kind and therefore elements kinds transitions are not
6159 // taken by this function. Returns |nullptr| if matching transition map is
6160 // not found.
6161 Map* TryReplayPropertyTransitions(Map* map);
6162
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006163 static void ConnectTransition(Handle<Map> parent, Handle<Map> child,
6164 Handle<Name> name, SimpleTransitionFlag flag);
6165
6166 bool EquivalentToForTransition(Map* other);
6167 static Handle<Map> RawCopy(Handle<Map> map, int instance_size);
6168 static Handle<Map> ShareDescriptor(Handle<Map> map,
6169 Handle<DescriptorArray> descriptors,
6170 Descriptor* descriptor);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006171 static Handle<Map> AddMissingTransitions(
6172 Handle<Map> map, Handle<DescriptorArray> descriptors,
6173 Handle<LayoutDescriptor> full_layout_descriptor);
6174 static void InstallDescriptors(
6175 Handle<Map> parent_map, Handle<Map> child_map, int new_descriptor,
6176 Handle<DescriptorArray> descriptors,
6177 Handle<LayoutDescriptor> full_layout_descriptor);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006178 static Handle<Map> CopyAddDescriptor(Handle<Map> map,
6179 Descriptor* descriptor,
6180 TransitionFlag flag);
6181 static Handle<Map> CopyReplaceDescriptors(
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006182 Handle<Map> map, Handle<DescriptorArray> descriptors,
6183 Handle<LayoutDescriptor> layout_descriptor, TransitionFlag flag,
6184 MaybeHandle<Name> maybe_name, const char* reason,
6185 SimpleTransitionFlag simple_flag);
6186
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006187 static Handle<Map> CopyReplaceDescriptor(Handle<Map> map,
6188 Handle<DescriptorArray> descriptors,
6189 Descriptor* descriptor,
6190 int index,
6191 TransitionFlag flag);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006192 static MUST_USE_RESULT MaybeHandle<Map> TryReconfigureExistingProperty(
6193 Handle<Map> map, int descriptor, PropertyKind kind,
6194 PropertyAttributes attributes, const char** reason);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006195
6196 static Handle<Map> CopyNormalized(Handle<Map> map,
6197 PropertyNormalizationMode mode);
6198
Ben Murdochc5610432016-08-08 18:44:38 +01006199 static Handle<Map> Reconfigure(Handle<Map> map,
6200 ElementsKind new_elements_kind,
6201 int modify_index, PropertyKind new_kind,
6202 PropertyAttributes new_attributes,
6203 Representation new_representation,
6204 Handle<FieldType> new_field_type,
6205 StoreMode store_mode);
6206
6207 static Handle<Map> CopyGeneralizeAllRepresentations(
6208 Handle<Map> map, ElementsKind elements_kind, int modify_index,
6209 StoreMode store_mode, PropertyKind kind, PropertyAttributes attributes,
6210 const char* reason);
6211
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006212 // Fires when the layout of an object with a leaf map changes.
6213 // This includes adding transitions to the leaf map or changing
6214 // the descriptor array.
6215 inline void NotifyLeafMapLayoutChange();
6216
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006217 void DeprecateTransitionTree();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006218
6219 void ReplaceDescriptors(DescriptorArray* new_descriptors,
6220 LayoutDescriptor* new_layout_descriptor);
6221
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006222
6223 Map* FindLastMatchMap(int verbatim, int length, DescriptorArray* descriptors);
6224
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006225 // Update field type of the given descriptor to new representation and new
6226 // type. The type must be prepared for storing in descriptor array:
6227 // it must be either a simple type or a map wrapped in a weak cell.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006228 void UpdateFieldType(int descriptor_number, Handle<Name> name,
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006229 Representation new_representation,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006230 Handle<Object> new_wrapped_type);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006231
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006232 void PrintReconfiguration(FILE* file, int modify_index, PropertyKind kind,
6233 PropertyAttributes attributes);
Ben Murdoch097c5b22016-05-18 11:27:45 +01006234 void PrintGeneralization(FILE* file, const char* reason, int modify_index,
6235 int split, int descriptors, bool constant_to_field,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006236 Representation old_representation,
6237 Representation new_representation,
Ben Murdoch097c5b22016-05-18 11:27:45 +01006238 MaybeHandle<FieldType> old_field_type,
6239 MaybeHandle<Object> old_value,
6240 MaybeHandle<FieldType> new_field_type,
6241 MaybeHandle<Object> new_value);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006242
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006243 static const int kFastPropertiesSoftLimit = 12;
6244 static const int kMaxFastProperties = 128;
6245
Steve Blocka7e24c12009-10-30 11:49:00 +00006246 DISALLOW_IMPLICIT_CONSTRUCTORS(Map);
6247};
6248
6249
6250// An abstract superclass, a marker class really, for simple structure classes.
Ben Murdoch257744e2011-11-30 15:57:28 +00006251// It doesn't carry much functionality but allows struct classes to be
Steve Blocka7e24c12009-10-30 11:49:00 +00006252// identified in the type system.
6253class Struct: public HeapObject {
6254 public:
6255 inline void InitializeBody(int object_size);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006256 DECLARE_CAST(Struct)
6257};
6258
6259
6260// A simple one-element struct, useful where smis need to be boxed.
6261class Box : public Struct {
6262 public:
6263 // [value]: the boxed contents.
6264 DECL_ACCESSORS(value, Object)
6265
6266 DECLARE_CAST(Box)
6267
6268 // Dispatched behavior.
6269 DECLARE_PRINTER(Box)
6270 DECLARE_VERIFIER(Box)
6271
6272 static const int kValueOffset = HeapObject::kHeaderSize;
6273 static const int kSize = kValueOffset + kPointerSize;
6274
6275 private:
6276 DISALLOW_IMPLICIT_CONSTRUCTORS(Box);
Steve Blocka7e24c12009-10-30 11:49:00 +00006277};
6278
6279
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006280// Container for metadata stored on each prototype map.
6281class PrototypeInfo : public Struct {
6282 public:
6283 static const int UNREGISTERED = -1;
6284
6285 // [prototype_users]: WeakFixedArray containing maps using this prototype,
6286 // or Smi(0) if uninitialized.
6287 DECL_ACCESSORS(prototype_users, Object)
6288 // [registry_slot]: Slot in prototype's user registry where this user
6289 // is stored. Returns UNREGISTERED if this prototype has not been registered.
6290 inline int registry_slot() const;
6291 inline void set_registry_slot(int slot);
6292 // [validity_cell]: Cell containing the validity bit for prototype chains
6293 // going through this object, or Smi(0) if uninitialized.
6294 // When a prototype object changes its map, then both its own validity cell
6295 // and those of all "downstream" prototypes are invalidated; handlers for a
6296 // given receiver embed the currently valid cell for that receiver's prototype
6297 // during their compilation and check it on execution.
6298 DECL_ACCESSORS(validity_cell, Object)
6299
6300 DECLARE_CAST(PrototypeInfo)
6301
6302 // Dispatched behavior.
6303 DECLARE_PRINTER(PrototypeInfo)
6304 DECLARE_VERIFIER(PrototypeInfo)
6305
6306 static const int kPrototypeUsersOffset = HeapObject::kHeaderSize;
6307 static const int kRegistrySlotOffset = kPrototypeUsersOffset + kPointerSize;
6308 static const int kValidityCellOffset = kRegistrySlotOffset + kPointerSize;
6309 static const int kConstructorNameOffset = kValidityCellOffset + kPointerSize;
6310 static const int kSize = kConstructorNameOffset + kPointerSize;
6311
6312 private:
6313 DISALLOW_IMPLICIT_CONSTRUCTORS(PrototypeInfo);
6314};
6315
6316
6317// Pair used to store both a ScopeInfo and an extension object in the extension
6318// slot of a block context. Needed in the rare case where a declaration block
6319// scope (a "varblock" as used to desugar parameter destructuring) also contains
6320// a sloppy direct eval. (In no other case both are needed at the same time.)
6321class SloppyBlockWithEvalContextExtension : public Struct {
6322 public:
6323 // [scope_info]: Scope info.
6324 DECL_ACCESSORS(scope_info, ScopeInfo)
6325 // [extension]: Extension object.
6326 DECL_ACCESSORS(extension, JSObject)
6327
6328 DECLARE_CAST(SloppyBlockWithEvalContextExtension)
6329
6330 // Dispatched behavior.
6331 DECLARE_PRINTER(SloppyBlockWithEvalContextExtension)
6332 DECLARE_VERIFIER(SloppyBlockWithEvalContextExtension)
6333
6334 static const int kScopeInfoOffset = HeapObject::kHeaderSize;
6335 static const int kExtensionOffset = kScopeInfoOffset + kPointerSize;
6336 static const int kSize = kExtensionOffset + kPointerSize;
6337
6338 private:
6339 DISALLOW_IMPLICIT_CONSTRUCTORS(SloppyBlockWithEvalContextExtension);
6340};
6341
6342
Steve Blocka7e24c12009-10-30 11:49:00 +00006343// Script describes a script which has been added to the VM.
6344class Script: public Struct {
6345 public:
6346 // Script types.
6347 enum Type {
6348 TYPE_NATIVE = 0,
6349 TYPE_EXTENSION = 1,
6350 TYPE_NORMAL = 2
6351 };
6352
6353 // Script compilation types.
6354 enum CompilationType {
6355 COMPILATION_TYPE_HOST = 0,
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08006356 COMPILATION_TYPE_EVAL = 1
Steve Blocka7e24c12009-10-30 11:49:00 +00006357 };
6358
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006359 // Script compilation state.
6360 enum CompilationState {
6361 COMPILATION_STATE_INITIAL = 0,
6362 COMPILATION_STATE_COMPILED = 1
6363 };
6364
Steve Blocka7e24c12009-10-30 11:49:00 +00006365 // [source]: the script source.
6366 DECL_ACCESSORS(source, Object)
6367
6368 // [name]: the script name.
6369 DECL_ACCESSORS(name, Object)
6370
6371 // [id]: the script id.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006372 DECL_INT_ACCESSORS(id)
Steve Blocka7e24c12009-10-30 11:49:00 +00006373
6374 // [line_offset]: script line offset in resource from where it was extracted.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006375 DECL_INT_ACCESSORS(line_offset)
Steve Blocka7e24c12009-10-30 11:49:00 +00006376
6377 // [column_offset]: script column offset in resource from where it was
6378 // extracted.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006379 DECL_INT_ACCESSORS(column_offset)
Steve Blocka7e24c12009-10-30 11:49:00 +00006380
Steve Blocka7e24c12009-10-30 11:49:00 +00006381 // [context_data]: context data for the context this script was compiled in.
6382 DECL_ACCESSORS(context_data, Object)
6383
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006384 // [wrapper]: the wrapper cache. This is either undefined or a WeakCell.
6385 DECL_ACCESSORS(wrapper, HeapObject)
Steve Blocka7e24c12009-10-30 11:49:00 +00006386
6387 // [type]: the script type.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006388 DECL_INT_ACCESSORS(type)
Steve Blocka7e24c12009-10-30 11:49:00 +00006389
Steve Blockd0582a62009-12-15 09:54:21 +00006390 // [line_ends]: FixedArray of line ends positions.
Steve Blocka7e24c12009-10-30 11:49:00 +00006391 DECL_ACCESSORS(line_ends, Object)
6392
Ben Murdoch097c5b22016-05-18 11:27:45 +01006393 // [eval_from_shared]: for eval scripts the shared function info for the
Steve Blockd0582a62009-12-15 09:54:21 +00006394 // function from which eval was called.
6395 DECL_ACCESSORS(eval_from_shared, Object)
Steve Blocka7e24c12009-10-30 11:49:00 +00006396
Ben Murdochc5610432016-08-08 18:44:38 +01006397 // [eval_from_position]: the source position in the code for the function
6398 // from which eval was called, as positive integer. Or the code offset in the
6399 // code from which eval was called, as negative integer.
6400 DECL_INT_ACCESSORS(eval_from_position)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006401
6402 // [shared_function_infos]: weak fixed array containing all shared
6403 // function infos created from this script.
6404 DECL_ACCESSORS(shared_function_infos, Object)
Steve Blocka7e24c12009-10-30 11:49:00 +00006405
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006406 // [flags]: Holds an exciting bitfield.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006407 DECL_INT_ACCESSORS(flags)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006408
6409 // [source_url]: sourceURL from magic comment
6410 DECL_ACCESSORS(source_url, Object)
6411
6412 // [source_url]: sourceMappingURL magic comment
6413 DECL_ACCESSORS(source_mapping_url, Object)
6414
6415 // [compilation_type]: how the the script was compiled. Encoded in the
6416 // 'flags' field.
6417 inline CompilationType compilation_type();
6418 inline void set_compilation_type(CompilationType type);
6419
6420 // [compilation_state]: determines whether the script has already been
6421 // compiled. Encoded in the 'flags' field.
6422 inline CompilationState compilation_state();
6423 inline void set_compilation_state(CompilationState state);
6424
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006425 // [hide_source]: determines whether the script source can be exposed as
6426 // function source. Encoded in the 'flags' field.
6427 inline bool hide_source();
6428 inline void set_hide_source(bool value);
6429
6430 // [origin_options]: optional attributes set by the embedder via ScriptOrigin,
6431 // and used by the embedder to make decisions about the script. V8 just passes
6432 // this through. Encoded in the 'flags' field.
6433 inline v8::ScriptOriginOptions origin_options();
6434 inline void set_origin_options(ScriptOriginOptions origin_options);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006435
6436 DECLARE_CAST(Script)
Steve Blocka7e24c12009-10-30 11:49:00 +00006437
Steve Block3ce2e202009-11-05 08:53:23 +00006438 // If script source is an external string, check that the underlying
6439 // resource is accessible. Otherwise, always return true.
6440 inline bool HasValidSource();
6441
Ben Murdoch097c5b22016-05-18 11:27:45 +01006442 // Convert code offset into column number.
6443 static int GetColumnNumber(Handle<Script> script, int code_offset);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006444
Ben Murdoch097c5b22016-05-18 11:27:45 +01006445 // Convert code offset into (zero-based) line number.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006446 // The non-handlified version does not allocate, but may be much slower.
Ben Murdoch097c5b22016-05-18 11:27:45 +01006447 static int GetLineNumber(Handle<Script> script, int code_offset);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006448 int GetLineNumber(int code_pos);
6449
6450 static Handle<Object> GetNameOrSourceURL(Handle<Script> script);
6451
Ben Murdochc5610432016-08-08 18:44:38 +01006452 // Set eval origin for stack trace formatting.
6453 static void SetEvalOrigin(Handle<Script> script,
6454 Handle<SharedFunctionInfo> outer,
6455 int eval_position);
6456 // Retrieve source position from where eval was called.
6457 int GetEvalPosition();
6458
Ben Murdoch097c5b22016-05-18 11:27:45 +01006459 // Init line_ends array with source code positions of line ends.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006460 static void InitLineEnds(Handle<Script> script);
6461
6462 // Get the JS object wrapping the given script; create it if none exists.
6463 static Handle<JSObject> GetWrapper(Handle<Script> script);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006464
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006465 // Look through the list of existing shared function infos to find one
6466 // that matches the function literal. Return empty handle if not found.
6467 MaybeHandle<SharedFunctionInfo> FindSharedFunctionInfo(FunctionLiteral* fun);
6468
6469 // Iterate over all script objects on the heap.
6470 class Iterator {
6471 public:
6472 explicit Iterator(Isolate* isolate);
6473 Script* Next();
6474
6475 private:
6476 WeakFixedArray::Iterator iterator_;
6477 DISALLOW_COPY_AND_ASSIGN(Iterator);
6478 };
6479
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006480 // Dispatched behavior.
6481 DECLARE_PRINTER(Script)
6482 DECLARE_VERIFIER(Script)
Steve Blocka7e24c12009-10-30 11:49:00 +00006483
6484 static const int kSourceOffset = HeapObject::kHeaderSize;
6485 static const int kNameOffset = kSourceOffset + kPointerSize;
6486 static const int kLineOffsetOffset = kNameOffset + kPointerSize;
6487 static const int kColumnOffsetOffset = kLineOffsetOffset + kPointerSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006488 static const int kContextOffset = kColumnOffsetOffset + kPointerSize;
Steve Blocka7e24c12009-10-30 11:49:00 +00006489 static const int kWrapperOffset = kContextOffset + kPointerSize;
6490 static const int kTypeOffset = kWrapperOffset + kPointerSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006491 static const int kLineEndsOffset = kTypeOffset + kPointerSize;
Steve Blocka7e24c12009-10-30 11:49:00 +00006492 static const int kIdOffset = kLineEndsOffset + kPointerSize;
Steve Blockd0582a62009-12-15 09:54:21 +00006493 static const int kEvalFromSharedOffset = kIdOffset + kPointerSize;
Ben Murdochc5610432016-08-08 18:44:38 +01006494 static const int kEvalFromPositionOffset =
Steve Blockd0582a62009-12-15 09:54:21 +00006495 kEvalFromSharedOffset + kPointerSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006496 static const int kSharedFunctionInfosOffset =
Ben Murdochc5610432016-08-08 18:44:38 +01006497 kEvalFromPositionOffset + kPointerSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006498 static const int kFlagsOffset = kSharedFunctionInfosOffset + kPointerSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006499 static const int kSourceUrlOffset = kFlagsOffset + kPointerSize;
6500 static const int kSourceMappingUrlOffset = kSourceUrlOffset + kPointerSize;
6501 static const int kSize = kSourceMappingUrlOffset + kPointerSize;
Steve Blocka7e24c12009-10-30 11:49:00 +00006502
6503 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006504 int GetLineNumberWithArray(int code_pos);
6505
6506 // Bit positions in the flags field.
6507 static const int kCompilationTypeBit = 0;
6508 static const int kCompilationStateBit = 1;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006509 static const int kHideSourceBit = 2;
6510 static const int kOriginOptionsShift = 3;
6511 static const int kOriginOptionsSize = 3;
6512 static const int kOriginOptionsMask = ((1 << kOriginOptionsSize) - 1)
6513 << kOriginOptionsShift;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006514
Steve Blocka7e24c12009-10-30 11:49:00 +00006515 DISALLOW_IMPLICIT_CONSTRUCTORS(Script);
6516};
6517
6518
Ben Murdochb0fe1622011-05-05 13:52:32 +01006519// List of builtin functions we want to identify to improve code
6520// generation.
6521//
6522// Each entry has a name of a global object property holding an object
6523// optionally followed by ".prototype", a name of a builtin function
6524// on the object (the one the id is set for), and a label.
6525//
6526// Installation of ids for the selected builtin functions is handled
6527// by the bootstrapper.
Ben Murdochda12d292016-06-02 14:46:10 +01006528#define FUNCTIONS_WITH_ID_LIST(V) \
6529 V(Array.prototype, indexOf, ArrayIndexOf) \
6530 V(Array.prototype, lastIndexOf, ArrayLastIndexOf) \
6531 V(Array.prototype, push, ArrayPush) \
6532 V(Array.prototype, pop, ArrayPop) \
6533 V(Array.prototype, shift, ArrayShift) \
6534 V(Function.prototype, apply, FunctionApply) \
6535 V(Function.prototype, call, FunctionCall) \
6536 V(Object.prototype, hasOwnProperty, ObjectHasOwnProperty) \
6537 V(String.prototype, charCodeAt, StringCharCodeAt) \
6538 V(String.prototype, charAt, StringCharAt) \
6539 V(String.prototype, concat, StringConcat) \
6540 V(String.prototype, toLowerCase, StringToLowerCase) \
6541 V(String.prototype, toUpperCase, StringToUpperCase) \
6542 V(String, fromCharCode, StringFromCharCode) \
6543 V(Math, random, MathRandom) \
6544 V(Math, floor, MathFloor) \
6545 V(Math, round, MathRound) \
6546 V(Math, ceil, MathCeil) \
6547 V(Math, abs, MathAbs) \
6548 V(Math, log, MathLog) \
6549 V(Math, exp, MathExp) \
6550 V(Math, sqrt, MathSqrt) \
6551 V(Math, pow, MathPow) \
6552 V(Math, max, MathMax) \
6553 V(Math, min, MathMin) \
6554 V(Math, cos, MathCos) \
6555 V(Math, sin, MathSin) \
6556 V(Math, tan, MathTan) \
6557 V(Math, acos, MathAcos) \
6558 V(Math, asin, MathAsin) \
6559 V(Math, atan, MathAtan) \
6560 V(Math, atan2, MathAtan2) \
6561 V(Math, imul, MathImul) \
6562 V(Math, clz32, MathClz32) \
6563 V(Math, fround, MathFround) \
6564 V(Math, trunc, MathTrunc)
Ben Murdochb0fe1622011-05-05 13:52:32 +01006565
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006566#define ATOMIC_FUNCTIONS_WITH_ID_LIST(V) \
6567 V(Atomics, load, AtomicsLoad) \
6568 V(Atomics, store, AtomicsStore)
6569
Ben Murdochb0fe1622011-05-05 13:52:32 +01006570enum BuiltinFunctionId {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006571 kArrayCode,
Ben Murdochb0fe1622011-05-05 13:52:32 +01006572#define DECLARE_FUNCTION_ID(ignored1, ignore2, name) \
6573 k##name,
6574 FUNCTIONS_WITH_ID_LIST(DECLARE_FUNCTION_ID)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006575 ATOMIC_FUNCTIONS_WITH_ID_LIST(DECLARE_FUNCTION_ID)
Ben Murdochb0fe1622011-05-05 13:52:32 +01006576#undef DECLARE_FUNCTION_ID
6577 // Fake id for a special case of Math.pow. Note, it continues the
6578 // list of math functions.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006579 kMathPowHalf
Ben Murdochb0fe1622011-05-05 13:52:32 +01006580};
6581
6582
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006583// Result of searching in an optimized code map of a SharedFunctionInfo. Note
6584// that both {code} and {literals} can be NULL to pass search result status.
6585struct CodeAndLiterals {
6586 Code* code; // Cached optimized code.
6587 LiteralsArray* literals; // Cached literals array.
6588};
6589
6590
Steve Blocka7e24c12009-10-30 11:49:00 +00006591// SharedFunctionInfo describes the JSFunction information that can be
6592// shared by multiple instances of the function.
6593class SharedFunctionInfo: public HeapObject {
6594 public:
6595 // [name]: Function name.
6596 DECL_ACCESSORS(name, Object)
6597
6598 // [code]: Function code.
6599 DECL_ACCESSORS(code, Code)
Ben Murdoch097c5b22016-05-18 11:27:45 +01006600
Ben Murdochda12d292016-06-02 14:46:10 +01006601 // Get the abstract code associated with the function, which will either be
6602 // a Code object or a BytecodeArray.
6603 inline AbstractCode* abstract_code();
6604
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006605 inline void ReplaceCode(Code* code);
6606
6607 // [optimized_code_map]: Map from native context to optimized code
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006608 // and a shared literals array.
6609 DECL_ACCESSORS(optimized_code_map, FixedArray)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006610
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006611 // Returns entry from optimized code map for specified context and OSR entry.
6612 // Note that {code == nullptr, literals == nullptr} indicates no matching
6613 // entry has been found, whereas {code, literals == nullptr} indicates that
6614 // code is context-independent.
6615 CodeAndLiterals SearchOptimizedCodeMap(Context* native_context,
6616 BailoutId osr_ast_id);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006617
6618 // Clear optimized code map.
6619 void ClearOptimizedCodeMap();
6620
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006621 // We have a special root FixedArray with the right shape and values
6622 // to represent the cleared optimized code map. This predicate checks
6623 // if that root is installed.
6624 inline bool OptimizedCodeMapIsCleared() const;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006625
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006626 // Removes a specific optimized code object from the optimized code map.
6627 // In case of non-OSR the code reference is cleared from the cache entry but
6628 // the entry itself is left in the map in order to proceed sharing literals.
6629 void EvictFromOptimizedCodeMap(Code* optimized_code, const char* reason);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006630
6631 // Trims the optimized code map after entries have been removed.
6632 void TrimOptimizedCodeMap(int shrink_by);
6633
Ben Murdochda12d292016-06-02 14:46:10 +01006634 // Add or update entry in the optimized code map for context-independent code.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006635 static void AddSharedCodeToOptimizedCodeMap(Handle<SharedFunctionInfo> shared,
6636 Handle<Code> code);
6637
Ben Murdochda12d292016-06-02 14:46:10 +01006638 // Add or update entry in the optimized code map for context-dependent code.
6639 // If {code} is not given, then an existing entry's code won't be overwritten.
6640 static void AddToOptimizedCodeMap(Handle<SharedFunctionInfo> shared,
6641 Handle<Context> native_context,
6642 MaybeHandle<Code> code,
6643 Handle<LiteralsArray> literals,
6644 BailoutId osr_ast_id);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006645
6646 // Set up the link between shared function info and the script. The shared
6647 // function info is added to the list on the script.
6648 static void SetScript(Handle<SharedFunctionInfo> shared,
6649 Handle<Object> script_object);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006650
6651 // Layout description of the optimized code map.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006652 static const int kSharedCodeIndex = 0;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006653 static const int kEntriesStart = 1;
6654 static const int kContextOffset = 0;
6655 static const int kCachedCodeOffset = 1;
6656 static const int kLiteralsOffset = 2;
6657 static const int kOsrAstIdOffset = 3;
6658 static const int kEntryLength = 4;
6659 static const int kInitialLength = kEntriesStart + kEntryLength;
Steve Blocka7e24c12009-10-30 11:49:00 +00006660
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006661 static const int kNotFound = -1;
6662
Ben Murdochc5610432016-08-08 18:44:38 +01006663 // Helpers for assembly code that does a backwards walk of the optimized code
6664 // map.
6665 static const int kOffsetToPreviousContext =
6666 FixedArray::kHeaderSize + kPointerSize * (kContextOffset - kEntryLength);
6667 static const int kOffsetToPreviousCachedCode =
6668 FixedArray::kHeaderSize +
6669 kPointerSize * (kCachedCodeOffset - kEntryLength);
6670 static const int kOffsetToPreviousLiterals =
6671 FixedArray::kHeaderSize + kPointerSize * (kLiteralsOffset - kEntryLength);
6672 static const int kOffsetToPreviousOsrAstId =
6673 FixedArray::kHeaderSize + kPointerSize * (kOsrAstIdOffset - kEntryLength);
6674
Ben Murdoch3bec4d22010-07-22 14:51:16 +01006675 // [scope_info]: Scope info.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006676 DECL_ACCESSORS(scope_info, ScopeInfo)
Ben Murdoch3bec4d22010-07-22 14:51:16 +01006677
Steve Blocka7e24c12009-10-30 11:49:00 +00006678 // [construct stub]: Code stub for constructing instances of this function.
6679 DECL_ACCESSORS(construct_stub, Code)
6680
6681 // Returns if this function has been compiled to native code yet.
6682 inline bool is_compiled();
6683
6684 // [length]: The function length - usually the number of declared parameters.
6685 // Use up to 2^30 parameters.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006686 inline int length() const;
Steve Blocka7e24c12009-10-30 11:49:00 +00006687 inline void set_length(int value);
6688
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006689 // [internal formal parameter count]: The declared number of parameters.
6690 // For subclass constructors, also includes new.target.
6691 // The size of function's frame is internal_formal_parameter_count + 1.
6692 inline int internal_formal_parameter_count() const;
6693 inline void set_internal_formal_parameter_count(int value);
Steve Blocka7e24c12009-10-30 11:49:00 +00006694
6695 // Set the formal parameter count so the function code will be
6696 // called without using argument adaptor frames.
6697 inline void DontAdaptArguments();
6698
6699 // [expected_nof_properties]: Expected number of properties for the function.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006700 inline int expected_nof_properties() const;
Steve Blocka7e24c12009-10-30 11:49:00 +00006701 inline void set_expected_nof_properties(int value);
6702
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006703 // [feedback_vector] - accumulates ast node feedback from full-codegen and
6704 // (increasingly) from crankshafted code where sufficient feedback isn't
6705 // available.
6706 DECL_ACCESSORS(feedback_vector, TypeFeedbackVector)
Kristian Monsen0d5e1162010-09-30 15:31:59 +01006707
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006708 // Unconditionally clear the type feedback vector (including vector ICs).
6709 void ClearTypeFeedbackInfo();
6710
6711 // Clear the type feedback vector with a more subtle policy at GC time.
6712 void ClearTypeFeedbackInfoAtGCTime();
6713
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006714#if TRACE_MAPS
6715 // [unique_id] - For --trace-maps purposes, an identifier that's persistent
6716 // even if the GC moves this SharedFunctionInfo.
6717 inline int unique_id() const;
6718 inline void set_unique_id(int value);
6719#endif
6720
Steve Blocka7e24c12009-10-30 11:49:00 +00006721 // [instance class name]: class name for instances.
6722 DECL_ACCESSORS(instance_class_name, Object)
6723
Steve Block6ded16b2010-05-10 14:33:55 +01006724 // [function data]: This field holds some additional data for function.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006725 // Currently it has one of:
6726 // - a FunctionTemplateInfo to make benefit the API [IsApiFunction()].
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006727 // - a BytecodeArray for the interpreter [HasBytecodeArray()].
Steve Blocka7e24c12009-10-30 11:49:00 +00006728 DECL_ACCESSORS(function_data, Object)
6729
Steve Block6ded16b2010-05-10 14:33:55 +01006730 inline bool IsApiFunction();
6731 inline FunctionTemplateInfo* get_api_func_data();
Ben Murdochda12d292016-06-02 14:46:10 +01006732 inline void set_api_func_data(FunctionTemplateInfo* data);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006733 inline bool HasBytecodeArray();
6734 inline BytecodeArray* bytecode_array();
Ben Murdochda12d292016-06-02 14:46:10 +01006735 inline void set_bytecode_array(BytecodeArray* bytecode);
6736 inline void ClearBytecodeArray();
6737
6738 // [function identifier]: This field holds an additional identifier for the
6739 // function.
6740 // - a Smi identifying a builtin function [HasBuiltinFunctionId()].
6741 // - a String identifying the function's inferred name [HasInferredName()].
6742 // The inferred_name is inferred from variable or property
6743 // assignment of this function. It is used to facilitate debugging and
6744 // profiling of JavaScript code written in OO style, where almost
6745 // all functions are anonymous but are assigned to object
6746 // properties.
6747 DECL_ACCESSORS(function_identifier, Object)
6748
6749 inline bool HasBuiltinFunctionId();
6750 inline BuiltinFunctionId builtin_function_id();
6751 inline void set_builtin_function_id(BuiltinFunctionId id);
6752 inline bool HasInferredName();
6753 inline String* inferred_name();
6754 inline void set_inferred_name(String* inferred_name);
Steve Block6ded16b2010-05-10 14:33:55 +01006755
Steve Blocka7e24c12009-10-30 11:49:00 +00006756 // [script info]: Script from which the function originates.
6757 DECL_ACCESSORS(script, Object)
6758
Steve Block6ded16b2010-05-10 14:33:55 +01006759 // [num_literals]: Number of literals used by this function.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006760 inline int num_literals() const;
Steve Block6ded16b2010-05-10 14:33:55 +01006761 inline void set_num_literals(int value);
6762
Steve Blocka7e24c12009-10-30 11:49:00 +00006763 // [start_position_and_type]: Field used to store both the source code
6764 // position, whether or not the function is a function expression,
6765 // and whether or not the function is a toplevel function. The two
6766 // least significants bit indicates whether the function is an
6767 // expression and the rest contains the source code position.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006768 inline int start_position_and_type() const;
Steve Blocka7e24c12009-10-30 11:49:00 +00006769 inline void set_start_position_and_type(int value);
6770
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006771 // The function is subject to debugging if a debug info is attached.
6772 inline bool HasDebugInfo();
6773 inline DebugInfo* GetDebugInfo();
6774
6775 // A function has debug code if the compiled code has debug break slots.
6776 inline bool HasDebugCode();
6777
Steve Blocka7e24c12009-10-30 11:49:00 +00006778 // [debug info]: Debug information.
6779 DECL_ACCESSORS(debug_info, Object)
6780
Ben Murdochf87a2032010-10-22 12:50:53 +01006781 // The function's name if it is non-empty, otherwise the inferred name.
6782 String* DebugName();
6783
Ben Murdochda12d292016-06-02 14:46:10 +01006784 // Used for flags such as --hydrogen-filter.
6785 bool PassesFilter(const char* raw_filter);
6786
Steve Blocka7e24c12009-10-30 11:49:00 +00006787 // Position of the 'function' token in the script source.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006788 inline int function_token_position() const;
Steve Blocka7e24c12009-10-30 11:49:00 +00006789 inline void set_function_token_position(int function_token_position);
6790
6791 // Position of this function in the script source.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006792 inline int start_position() const;
Steve Blocka7e24c12009-10-30 11:49:00 +00006793 inline void set_start_position(int start_position);
6794
6795 // End position of this function in the script source.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006796 inline int end_position() const;
Steve Blocka7e24c12009-10-30 11:49:00 +00006797 inline void set_end_position(int end_position);
6798
Ben Murdoch097c5b22016-05-18 11:27:45 +01006799 // Is this function a named function expression in the source code.
6800 DECL_BOOLEAN_ACCESSORS(is_named_expression)
Steve Blocka7e24c12009-10-30 11:49:00 +00006801
6802 // Is this function a top-level function (scripts, evals).
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00006803 DECL_BOOLEAN_ACCESSORS(is_toplevel)
Steve Blocka7e24c12009-10-30 11:49:00 +00006804
6805 // Bit field containing various information collected by the compiler to
6806 // drive optimization.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006807 inline int compiler_hints() const;
Steve Blocka7e24c12009-10-30 11:49:00 +00006808 inline void set_compiler_hints(int value);
6809
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006810 inline int ast_node_count() const;
Ben Murdoch8f9999f2012-04-23 10:39:17 +01006811 inline void set_ast_node_count(int count);
6812
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006813 inline int profiler_ticks() const;
6814 inline void set_profiler_ticks(int ticks);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006815
Ben Murdoch8f9999f2012-04-23 10:39:17 +01006816 // Inline cache age is used to infer whether the function survived a context
6817 // disposal or not. In the former case we reset the opt_count.
6818 inline int ic_age();
6819 inline void set_ic_age(int age);
Ben Murdochb0fe1622011-05-05 13:52:32 +01006820
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01006821 // Indicates if this function can be lazy compiled.
6822 // This is used to determine if we can safely flush code from a function
6823 // when doing GC if we expect that the function will no longer be used.
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00006824 DECL_BOOLEAN_ACCESSORS(allows_lazy_compilation)
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01006825
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006826 // Indicates if this function can be lazy compiled without a context.
6827 // This is used to determine if we can force compilation without reaching
6828 // the function through program execution but through other means (e.g. heap
6829 // iteration by the debugger).
6830 DECL_BOOLEAN_ACCESSORS(allows_lazy_compilation_without_context)
Iain Merrick75681382010-08-19 15:07:18 +01006831
Ben Murdochb0fe1622011-05-05 13:52:32 +01006832 // Indicates whether optimizations have been disabled for this
6833 // shared function info. If a function is repeatedly optimized or if
6834 // we cannot optimize the function we disable optimization to avoid
6835 // spending time attempting to optimize it again.
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00006836 DECL_BOOLEAN_ACCESSORS(optimization_disabled)
Ben Murdochb0fe1622011-05-05 13:52:32 +01006837
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006838 // Indicates the language mode.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006839 inline LanguageMode language_mode();
6840 inline void set_language_mode(LanguageMode language_mode);
Steve Block1e0659c2011-05-24 12:43:12 +01006841
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00006842 // False if the function definitely does not allocate an arguments object.
6843 DECL_BOOLEAN_ACCESSORS(uses_arguments)
6844
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006845 // Indicates that this function uses a super property (or an eval that may
6846 // use a super property).
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006847 // This is needed to set up the [[HomeObject]] on the function instance.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006848 DECL_BOOLEAN_ACCESSORS(needs_home_object)
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006849
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00006850 // True if the function has any duplicated parameter names.
6851 DECL_BOOLEAN_ACCESSORS(has_duplicate_parameters)
6852
6853 // Indicates whether the function is a native function.
Ben Murdoch589d6972011-11-30 16:04:58 +00006854 // These needs special treatment in .call and .apply since
Ben Murdoch257744e2011-11-30 15:57:28 +00006855 // null passed as the receiver should not be translated to the
6856 // global object.
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00006857 DECL_BOOLEAN_ACCESSORS(native)
6858
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006859 // Indicate that this function should always be inlined in optimized code.
6860 DECL_BOOLEAN_ACCESSORS(force_inline)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006861
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00006862 // Indicates that the function was created by the Function function.
6863 // Though it's anonymous, toString should treat it as if it had the name
6864 // "anonymous". We don't set the name itself so that the system does not
6865 // see a binding for it.
6866 DECL_BOOLEAN_ACCESSORS(name_should_print_as_anonymous)
6867
Ben Murdoch097c5b22016-05-18 11:27:45 +01006868 // Indicates that the function is either an anonymous expression
6869 // or an arrow function (the name field can be set through the API,
6870 // which does not change this flag).
6871 DECL_BOOLEAN_ACCESSORS(is_anonymous_expression)
Ben Murdoch257744e2011-11-30 15:57:28 +00006872
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006873 // Is this a function or top-level/eval code.
6874 DECL_BOOLEAN_ACCESSORS(is_function)
6875
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006876 // Indicates that code for this function cannot be compiled with Crankshaft.
6877 DECL_BOOLEAN_ACCESSORS(dont_crankshaft)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006878
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006879 // Indicates that code for this function cannot be flushed.
6880 DECL_BOOLEAN_ACCESSORS(dont_flush)
6881
6882 // Indicates that this function is a generator.
6883 DECL_BOOLEAN_ACCESSORS(is_generator)
6884
Ben Murdochc5610432016-08-08 18:44:38 +01006885 // Indicates that this function is an async function.
6886 DECL_BOOLEAN_ACCESSORS(is_async)
6887
6888 // Indicates that this function can be suspended, either via YieldExpressions
6889 // or AwaitExpressions.
6890 inline bool is_resumable() const;
6891
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006892 // Indicates that this function is an arrow function.
6893 DECL_BOOLEAN_ACCESSORS(is_arrow)
6894
6895 // Indicates that this function is a concise method.
6896 DECL_BOOLEAN_ACCESSORS(is_concise_method)
6897
Ben Murdoch097c5b22016-05-18 11:27:45 +01006898 // Indicates that this function is a getter.
6899 DECL_BOOLEAN_ACCESSORS(is_getter_function)
6900
6901 // Indicates that this function is a setter.
6902 DECL_BOOLEAN_ACCESSORS(is_setter_function)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006903
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006904 // Indicates that this function is a default constructor.
6905 DECL_BOOLEAN_ACCESSORS(is_default_constructor)
6906
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006907 // Indicates that this function is an asm function.
6908 DECL_BOOLEAN_ACCESSORS(asm_function)
6909
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006910 // Indicates that the the shared function info is deserialized from cache.
6911 DECL_BOOLEAN_ACCESSORS(deserialized)
6912
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006913 // Indicates that the the shared function info has never been compiled before.
6914 DECL_BOOLEAN_ACCESSORS(never_compiled)
6915
Ben Murdoch097c5b22016-05-18 11:27:45 +01006916 // Whether this function was created from a FunctionDeclaration.
6917 DECL_BOOLEAN_ACCESSORS(is_declaration)
6918
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006919 inline FunctionKind kind();
6920 inline void set_kind(FunctionKind kind);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006921
Ben Murdochb0fe1622011-05-05 13:52:32 +01006922 // Indicates whether or not the code in the shared function support
6923 // deoptimization.
6924 inline bool has_deoptimization_support();
6925
6926 // Enable deoptimization support through recompiled code.
6927 void EnableDeoptimizationSupport(Code* recompiled);
6928
Ben Murdoch257744e2011-11-30 15:57:28 +00006929 // Disable (further) attempted optimization of all functions sharing this
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006930 // shared function info.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006931 void DisableOptimization(BailoutReason reason);
Ben Murdoch257744e2011-11-30 15:57:28 +00006932
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006933 inline BailoutReason disable_optimization_reason();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006934
6935 // Lookup the bailout ID and DCHECK that it exists in the non-optimized
Ben Murdochb0fe1622011-05-05 13:52:32 +01006936 // code, returns whether it asserted (i.e., always true if assertions are
6937 // disabled).
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006938 bool VerifyBailoutId(BailoutId id);
Steve Blocka7e24c12009-10-30 11:49:00 +00006939
6940 // [source code]: Source code for the function.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006941 bool HasSourceCode() const;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006942 Handle<Object> GetSourceCode();
Steve Blocka7e24c12009-10-30 11:49:00 +00006943
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006944 // Number of times the function was optimized.
Ben Murdochb0fe1622011-05-05 13:52:32 +01006945 inline int opt_count();
6946 inline void set_opt_count(int opt_count);
6947
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006948 // Number of times the function was deoptimized.
6949 inline void set_deopt_count(int value);
6950 inline int deopt_count();
6951 inline void increment_deopt_count();
6952
6953 // Number of time we tried to re-enable optimization after it
6954 // was disabled due to high number of deoptimizations.
6955 inline void set_opt_reenable_tries(int value);
6956 inline int opt_reenable_tries();
6957
6958 inline void TryReenableOptimization();
6959
6960 // Stores deopt_count, opt_reenable_tries and ic_age as bit-fields.
6961 inline void set_counters(int value);
6962 inline int counters() const;
6963
6964 // Stores opt_count and bailout_reason as bit-fields.
6965 inline void set_opt_count_and_bailout_reason(int value);
6966 inline int opt_count_and_bailout_reason() const;
6967
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006968 inline void set_disable_optimization_reason(BailoutReason reason);
6969
6970 // Tells whether this function should be subject to debugging.
6971 inline bool IsSubjectToDebugging();
6972
6973 // Whether this function is defined in native code or extensions.
6974 inline bool IsBuiltin();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006975
6976 // Check whether or not this function is inlineable.
6977 bool IsInlineable();
6978
Ben Murdochb0fe1622011-05-05 13:52:32 +01006979 // Source size of this function.
6980 int SourceSize();
6981
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006982 // Returns `false` if formal parameters include rest parameters, optional
6983 // parameters, or destructuring parameters.
6984 // TODO(caitp): make this a flag set during parsing
6985 inline bool has_simple_parameters();
Steve Blocka7e24c12009-10-30 11:49:00 +00006986
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006987 // Initialize a SharedFunctionInfo from a parsed function literal.
6988 static void InitFromFunctionLiteral(Handle<SharedFunctionInfo> shared_info,
6989 FunctionLiteral* lit);
Steve Blocka7e24c12009-10-30 11:49:00 +00006990
6991 // Dispatched behavior.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006992 DECLARE_PRINTER(SharedFunctionInfo)
6993 DECLARE_VERIFIER(SharedFunctionInfo)
Steve Blocka7e24c12009-10-30 11:49:00 +00006994
Ben Murdoch8f9999f2012-04-23 10:39:17 +01006995 void ResetForNewContext(int new_ic_age);
6996
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006997 // Iterate over all shared function infos.
6998 class Iterator {
6999 public:
7000 explicit Iterator(Isolate* isolate);
7001 SharedFunctionInfo* Next();
7002
7003 private:
7004 bool NextScript();
7005
7006 Script::Iterator script_iterator_;
7007 WeakFixedArray::Iterator sfi_iterator_;
7008 DisallowHeapAllocation no_gc_;
7009 DISALLOW_COPY_AND_ASSIGN(Iterator);
7010 };
7011
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007012 DECLARE_CAST(SharedFunctionInfo)
Steve Blocka7e24c12009-10-30 11:49:00 +00007013
7014 // Constants.
7015 static const int kDontAdaptArgumentsSentinel = -1;
7016
7017 // Layout description.
Steve Block6ded16b2010-05-10 14:33:55 +01007018 // Pointer fields.
Steve Blocka7e24c12009-10-30 11:49:00 +00007019 static const int kNameOffset = HeapObject::kHeaderSize;
7020 static const int kCodeOffset = kNameOffset + kPointerSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007021 static const int kOptimizedCodeMapOffset = kCodeOffset + kPointerSize;
7022 static const int kScopeInfoOffset = kOptimizedCodeMapOffset + kPointerSize;
Ben Murdoch3bec4d22010-07-22 14:51:16 +01007023 static const int kConstructStubOffset = kScopeInfoOffset + kPointerSize;
Steve Block6ded16b2010-05-10 14:33:55 +01007024 static const int kInstanceClassNameOffset =
7025 kConstructStubOffset + kPointerSize;
7026 static const int kFunctionDataOffset =
7027 kInstanceClassNameOffset + kPointerSize;
7028 static const int kScriptOffset = kFunctionDataOffset + kPointerSize;
7029 static const int kDebugInfoOffset = kScriptOffset + kPointerSize;
Ben Murdochda12d292016-06-02 14:46:10 +01007030 static const int kFunctionIdentifierOffset = kDebugInfoOffset + kPointerSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007031 static const int kFeedbackVectorOffset =
Ben Murdochda12d292016-06-02 14:46:10 +01007032 kFunctionIdentifierOffset + kPointerSize;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007033#if TRACE_MAPS
7034 static const int kUniqueIdOffset = kFeedbackVectorOffset + kPointerSize;
7035 static const int kLastPointerFieldOffset = kUniqueIdOffset;
7036#else
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007037 // Just to not break the postmortrem support with conditional offsets
7038 static const int kUniqueIdOffset = kFeedbackVectorOffset;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007039 static const int kLastPointerFieldOffset = kFeedbackVectorOffset;
7040#endif
7041
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01007042#if V8_HOST_ARCH_32_BIT
7043 // Smi fields.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007044 static const int kLengthOffset = kLastPointerFieldOffset + kPointerSize;
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01007045 static const int kFormalParameterCountOffset = kLengthOffset + kPointerSize;
7046 static const int kExpectedNofPropertiesOffset =
7047 kFormalParameterCountOffset + kPointerSize;
7048 static const int kNumLiteralsOffset =
7049 kExpectedNofPropertiesOffset + kPointerSize;
7050 static const int kStartPositionAndTypeOffset =
7051 kNumLiteralsOffset + kPointerSize;
7052 static const int kEndPositionOffset =
7053 kStartPositionAndTypeOffset + kPointerSize;
7054 static const int kFunctionTokenPositionOffset =
7055 kEndPositionOffset + kPointerSize;
7056 static const int kCompilerHintsOffset =
7057 kFunctionTokenPositionOffset + kPointerSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007058 static const int kOptCountAndBailoutReasonOffset =
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01007059 kCompilerHintsOffset + kPointerSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007060 static const int kCountersOffset =
7061 kOptCountAndBailoutReasonOffset + kPointerSize;
7062 static const int kAstNodeCountOffset =
7063 kCountersOffset + kPointerSize;
7064 static const int kProfilerTicksOffset =
7065 kAstNodeCountOffset + kPointerSize;
Ben Murdoch8f9999f2012-04-23 10:39:17 +01007066
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01007067 // Total size.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007068 static const int kSize = kProfilerTicksOffset + kPointerSize;
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01007069#else
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007070// The only reason to use smi fields instead of int fields is to allow
7071// iteration without maps decoding during garbage collections.
7072// To avoid wasting space on 64-bit architectures we use the following trick:
7073// we group integer fields into pairs
7074// The least significant integer in each pair is shifted left by 1. By doing
7075// this we guarantee that LSB of each kPointerSize aligned word is not set and
7076// thus this word cannot be treated as pointer to HeapObject during old space
7077// traversal.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007078#if V8_TARGET_LITTLE_ENDIAN
7079 static const int kLengthOffset = kLastPointerFieldOffset + kPointerSize;
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01007080 static const int kFormalParameterCountOffset =
7081 kLengthOffset + kIntSize;
7082
Steve Blocka7e24c12009-10-30 11:49:00 +00007083 static const int kExpectedNofPropertiesOffset =
7084 kFormalParameterCountOffset + kIntSize;
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01007085 static const int kNumLiteralsOffset =
7086 kExpectedNofPropertiesOffset + kIntSize;
7087
7088 static const int kEndPositionOffset =
Steve Block6ded16b2010-05-10 14:33:55 +01007089 kNumLiteralsOffset + kIntSize;
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01007090 static const int kStartPositionAndTypeOffset =
7091 kEndPositionOffset + kIntSize;
7092
7093 static const int kFunctionTokenPositionOffset =
7094 kStartPositionAndTypeOffset + kIntSize;
Steve Block6ded16b2010-05-10 14:33:55 +01007095 static const int kCompilerHintsOffset =
Steve Blocka7e24c12009-10-30 11:49:00 +00007096 kFunctionTokenPositionOffset + kIntSize;
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01007097
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007098 static const int kOptCountAndBailoutReasonOffset =
Steve Block6ded16b2010-05-10 14:33:55 +01007099 kCompilerHintsOffset + kIntSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007100 static const int kCountersOffset =
7101 kOptCountAndBailoutReasonOffset + kIntSize;
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01007102
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007103 static const int kAstNodeCountOffset =
7104 kCountersOffset + kIntSize;
7105 static const int kProfilerTicksOffset =
7106 kAstNodeCountOffset + kIntSize;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007107
Steve Block6ded16b2010-05-10 14:33:55 +01007108 // Total size.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007109 static const int kSize = kProfilerTicksOffset + kIntSize;
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01007110
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007111#elif V8_TARGET_BIG_ENDIAN
7112 static const int kFormalParameterCountOffset =
7113 kLastPointerFieldOffset + kPointerSize;
7114 static const int kLengthOffset = kFormalParameterCountOffset + kIntSize;
7115
7116 static const int kNumLiteralsOffset = kLengthOffset + kIntSize;
7117 static const int kExpectedNofPropertiesOffset = kNumLiteralsOffset + kIntSize;
7118
7119 static const int kStartPositionAndTypeOffset =
7120 kExpectedNofPropertiesOffset + kIntSize;
7121 static const int kEndPositionOffset = kStartPositionAndTypeOffset + kIntSize;
7122
7123 static const int kCompilerHintsOffset = kEndPositionOffset + kIntSize;
7124 static const int kFunctionTokenPositionOffset =
7125 kCompilerHintsOffset + kIntSize;
7126
7127 static const int kCountersOffset = kFunctionTokenPositionOffset + kIntSize;
7128 static const int kOptCountAndBailoutReasonOffset = kCountersOffset + kIntSize;
7129
7130 static const int kProfilerTicksOffset =
7131 kOptCountAndBailoutReasonOffset + kIntSize;
7132 static const int kAstNodeCountOffset = kProfilerTicksOffset + kIntSize;
7133
7134 // Total size.
7135 static const int kSize = kAstNodeCountOffset + kIntSize;
7136
7137#else
7138#error Unknown byte ordering
7139#endif // Big endian
7140#endif // 64-bit
7141
Kristian Monsen0d5e1162010-09-30 15:31:59 +01007142
Steve Block6ded16b2010-05-10 14:33:55 +01007143 static const int kAlignedSize = POINTER_SIZE_ALIGN(kSize);
Steve Blocka7e24c12009-10-30 11:49:00 +00007144
Iain Merrick75681382010-08-19 15:07:18 +01007145 typedef FixedBodyDescriptor<kNameOffset,
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007146 kLastPointerFieldOffset + kPointerSize,
Iain Merrick75681382010-08-19 15:07:18 +01007147 kSize> BodyDescriptor;
7148
Steve Blocka7e24c12009-10-30 11:49:00 +00007149 // Bit positions in start_position_and_type.
7150 // The source code start position is in the 30 most significant bits of
7151 // the start_position_and_type field.
Ben Murdoch097c5b22016-05-18 11:27:45 +01007152 static const int kIsNamedExpressionBit = 0;
7153 static const int kIsTopLevelBit = 1;
Steve Blocka7e24c12009-10-30 11:49:00 +00007154 static const int kStartPositionShift = 2;
Ben Murdoch097c5b22016-05-18 11:27:45 +01007155 static const int kStartPositionMask = ~((1 << kStartPositionShift) - 1);
Steve Blocka7e24c12009-10-30 11:49:00 +00007156
7157 // Bit positions in compiler_hints.
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00007158 enum CompilerHints {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007159 // byte 0
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00007160 kAllowLazyCompilation,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007161 kAllowLazyCompilationWithoutContext,
7162 kOptimizationDisabled,
Ben Murdochda12d292016-06-02 14:46:10 +01007163 kNeverCompiled,
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00007164 kNative,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007165 kStrictModeFunction,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007166 kUsesArguments,
7167 kNeedsHomeObject,
7168 // byte 1
7169 kHasDuplicateParameters,
7170 kForceInline,
7171 kIsAsmFunction,
Ben Murdoch097c5b22016-05-18 11:27:45 +01007172 kIsAnonymousExpression,
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00007173 kNameShouldPrintAsAnonymous,
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007174 kIsFunction,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007175 kDontCrankshaft,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007176 kDontFlush,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007177 // byte 2
7178 kFunctionKind,
7179 kIsArrow = kFunctionKind,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007180 kIsGenerator,
7181 kIsConciseMethod,
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007182 kIsDefaultConstructor,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007183 kIsSubclassConstructor,
7184 kIsBaseConstructor,
Ben Murdoch097c5b22016-05-18 11:27:45 +01007185 kIsGetterFunction,
7186 kIsSetterFunction,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007187 // byte 3
Ben Murdochc5610432016-08-08 18:44:38 +01007188 kIsAsyncFunction,
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007189 kDeserialized,
Ben Murdoch097c5b22016-05-18 11:27:45 +01007190 kIsDeclaration,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007191 kCompilerHintsCount, // Pseudo entry
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00007192 };
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007193 // Add hints for other modes when they're added.
7194 STATIC_ASSERT(LANGUAGE_END == 3);
7195 // kFunctionKind has to be byte-aligned
7196 STATIC_ASSERT((kFunctionKind % kBitsPerByte) == 0);
7197// Make sure that FunctionKind and byte 2 are in sync:
7198#define ASSERT_FUNCTION_KIND_ORDER(functionKind, compilerFunctionKind) \
7199 STATIC_ASSERT(FunctionKind::functionKind == \
7200 1 << (compilerFunctionKind - kFunctionKind))
7201 ASSERT_FUNCTION_KIND_ORDER(kArrowFunction, kIsArrow);
7202 ASSERT_FUNCTION_KIND_ORDER(kGeneratorFunction, kIsGenerator);
7203 ASSERT_FUNCTION_KIND_ORDER(kConciseMethod, kIsConciseMethod);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007204 ASSERT_FUNCTION_KIND_ORDER(kDefaultConstructor, kIsDefaultConstructor);
7205 ASSERT_FUNCTION_KIND_ORDER(kSubclassConstructor, kIsSubclassConstructor);
7206 ASSERT_FUNCTION_KIND_ORDER(kBaseConstructor, kIsBaseConstructor);
Ben Murdoch097c5b22016-05-18 11:27:45 +01007207 ASSERT_FUNCTION_KIND_ORDER(kGetterFunction, kIsGetterFunction);
7208 ASSERT_FUNCTION_KIND_ORDER(kSetterFunction, kIsSetterFunction);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007209#undef ASSERT_FUNCTION_KIND_ORDER
Steve Blocka7e24c12009-10-30 11:49:00 +00007210
Ben Murdochc5610432016-08-08 18:44:38 +01007211 class FunctionKindBits : public BitField<FunctionKind, kIsArrow, 9> {};
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007212
7213 class DeoptCountBits : public BitField<int, 0, 4> {};
7214 class OptReenableTriesBits : public BitField<int, 4, 18> {};
7215 class ICAgeBits : public BitField<int, 22, 8> {};
7216
7217 class OptCountBits : public BitField<int, 0, 22> {};
7218 class DisabledOptimizationReasonBits : public BitField<int, 22, 8> {};
7219
Ben Murdoche0cee9b2011-05-25 10:26:03 +01007220 private:
7221#if V8_HOST_ARCH_32_BIT
7222 // On 32 bit platforms, compiler hints is a smi.
7223 static const int kCompilerHintsSmiTagSize = kSmiTagSize;
7224 static const int kCompilerHintsSize = kPointerSize;
7225#else
7226 // On 64 bit platforms, compiler hints is not a smi, see comment above.
7227 static const int kCompilerHintsSmiTagSize = 0;
7228 static const int kCompilerHintsSize = kIntSize;
7229#endif
7230
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00007231 STATIC_ASSERT(SharedFunctionInfo::kCompilerHintsCount <=
7232 SharedFunctionInfo::kCompilerHintsSize * kBitsPerByte);
7233
Ben Murdoche0cee9b2011-05-25 10:26:03 +01007234 public:
Ben Murdoch257744e2011-11-30 15:57:28 +00007235 // Constants for optimizing codegen for strict mode function and
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007236 // native tests when using integer-width instructions.
7237 static const int kStrictModeBit =
7238 kStrictModeFunction + kCompilerHintsSmiTagSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007239 static const int kNativeBit = kNative + kCompilerHintsSmiTagSize;
Ben Murdochc5610432016-08-08 18:44:38 +01007240 static const int kHasDuplicateParametersBit =
7241 kHasDuplicateParameters + kCompilerHintsSmiTagSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007242
7243 static const int kClassConstructorBits =
7244 FunctionKind::kClassConstructor
7245 << (kFunctionKind + kCompilerHintsSmiTagSize);
7246
7247 // Constants for optimizing codegen for strict mode function and
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00007248 // native tests.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007249 // Allows to use byte-width instructions.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007250 static const int kStrictModeBitWithinByte = kStrictModeBit % kBitsPerByte;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007251 static const int kNativeBitWithinByte = kNativeBit % kBitsPerByte;
Ben Murdochc5610432016-08-08 18:44:38 +01007252 static const int kHasDuplicateParametersBitWithinByte =
7253 kHasDuplicateParametersBit % kBitsPerByte;
Ben Murdoche0cee9b2011-05-25 10:26:03 +01007254
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007255 static const int kClassConstructorBitsWithinByte =
7256 FunctionKind::kClassConstructor << kCompilerHintsSmiTagSize;
7257 STATIC_ASSERT(kClassConstructorBitsWithinByte < (1 << kBitsPerByte));
Ben Murdoch257744e2011-11-30 15:57:28 +00007258
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007259#if defined(V8_TARGET_LITTLE_ENDIAN)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007260#define BYTE_OFFSET(compiler_hint) \
7261 kCompilerHintsOffset + \
7262 (compiler_hint + kCompilerHintsSmiTagSize) / kBitsPerByte
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007263#elif defined(V8_TARGET_BIG_ENDIAN)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007264#define BYTE_OFFSET(compiler_hint) \
7265 kCompilerHintsOffset + (kCompilerHintsSize - 1) - \
7266 ((compiler_hint + kCompilerHintsSmiTagSize) / kBitsPerByte)
Ben Murdoche0cee9b2011-05-25 10:26:03 +01007267#else
7268#error Unknown byte ordering
7269#endif
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007270 static const int kStrictModeByteOffset = BYTE_OFFSET(kStrictModeFunction);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007271 static const int kNativeByteOffset = BYTE_OFFSET(kNative);
7272 static const int kFunctionKindByteOffset = BYTE_OFFSET(kFunctionKind);
Ben Murdochc5610432016-08-08 18:44:38 +01007273 static const int kHasDuplicateParametersByteOffset =
7274 BYTE_OFFSET(kHasDuplicateParameters);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007275#undef BYTE_OFFSET
Ben Murdoche0cee9b2011-05-25 10:26:03 +01007276
7277 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007278 // Returns entry from optimized code map for specified context and OSR entry.
7279 // The result is either kNotFound, kSharedCodeIndex for context-independent
7280 // entry or a start index of the context-dependent entry.
7281 int SearchOptimizedCodeMapEntry(Context* native_context,
7282 BailoutId osr_ast_id);
7283
Steve Blocka7e24c12009-10-30 11:49:00 +00007284 DISALLOW_IMPLICIT_CONSTRUCTORS(SharedFunctionInfo);
7285};
7286
7287
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007288// Printing support.
7289struct SourceCodeOf {
7290 explicit SourceCodeOf(SharedFunctionInfo* v, int max = -1)
7291 : value(v), max_length(max) {}
7292 const SharedFunctionInfo* value;
7293 int max_length;
7294};
7295
7296
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007297std::ostream& operator<<(std::ostream& os, const SourceCodeOf& v);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007298
7299
7300class JSGeneratorObject: public JSObject {
7301 public:
7302 // [function]: The function corresponding to this generator object.
7303 DECL_ACCESSORS(function, JSFunction)
7304
7305 // [context]: The context of the suspended computation.
7306 DECL_ACCESSORS(context, Context)
7307
7308 // [receiver]: The receiver of the suspended computation.
7309 DECL_ACCESSORS(receiver, Object)
7310
Ben Murdoch097c5b22016-05-18 11:27:45 +01007311 // [input]: The most recent input value.
7312 DECL_ACCESSORS(input, Object)
7313
Ben Murdochc5610432016-08-08 18:44:38 +01007314 // [resume_mode]: The most recent resume mode.
7315 enum ResumeMode { kNext, kReturn, kThrow };
7316 DECL_INT_ACCESSORS(resume_mode)
7317
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007318 // [continuation]: Offset into code of continuation.
7319 //
7320 // A positive offset indicates a suspended generator. The special
7321 // kGeneratorExecuting and kGeneratorClosed values indicate that a generator
7322 // cannot be resumed.
7323 inline int continuation() const;
7324 inline void set_continuation(int continuation);
7325 inline bool is_closed();
7326 inline bool is_executing();
7327 inline bool is_suspended();
7328
7329 // [operand_stack]: Saved operand stack.
7330 DECL_ACCESSORS(operand_stack, FixedArray)
7331
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007332 DECLARE_CAST(JSGeneratorObject)
7333
7334 // Dispatched behavior.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007335 DECLARE_VERIFIER(JSGeneratorObject)
7336
7337 // Magic sentinel values for the continuation.
Ben Murdochc5610432016-08-08 18:44:38 +01007338 static const int kGeneratorExecuting = -2;
7339 static const int kGeneratorClosed = -1;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007340
7341 // Layout description.
7342 static const int kFunctionOffset = JSObject::kHeaderSize;
7343 static const int kContextOffset = kFunctionOffset + kPointerSize;
7344 static const int kReceiverOffset = kContextOffset + kPointerSize;
Ben Murdoch097c5b22016-05-18 11:27:45 +01007345 static const int kInputOffset = kReceiverOffset + kPointerSize;
Ben Murdochc5610432016-08-08 18:44:38 +01007346 static const int kResumeModeOffset = kInputOffset + kPointerSize;
7347 static const int kContinuationOffset = kResumeModeOffset + kPointerSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007348 static const int kOperandStackOffset = kContinuationOffset + kPointerSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007349 static const int kSize = kOperandStackOffset + kPointerSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007350
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007351 private:
7352 DISALLOW_IMPLICIT_CONSTRUCTORS(JSGeneratorObject);
7353};
7354
7355
7356// Representation for module instance objects.
7357class JSModule: public JSObject {
7358 public:
7359 // [context]: the context holding the module's locals, or undefined if none.
7360 DECL_ACCESSORS(context, Object)
7361
7362 // [scope_info]: Scope info.
7363 DECL_ACCESSORS(scope_info, ScopeInfo)
7364
7365 DECLARE_CAST(JSModule)
7366
7367 // Dispatched behavior.
7368 DECLARE_PRINTER(JSModule)
7369 DECLARE_VERIFIER(JSModule)
7370
7371 // Layout description.
7372 static const int kContextOffset = JSObject::kHeaderSize;
7373 static const int kScopeInfoOffset = kContextOffset + kPointerSize;
7374 static const int kSize = kScopeInfoOffset + kPointerSize;
7375
7376 private:
7377 DISALLOW_IMPLICIT_CONSTRUCTORS(JSModule);
7378};
7379
7380
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007381// JSBoundFunction describes a bound function exotic object.
7382class JSBoundFunction : public JSObject {
7383 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007384 // [bound_target_function]: The wrapped function object.
7385 DECL_ACCESSORS(bound_target_function, JSReceiver)
7386
7387 // [bound_this]: The value that is always passed as the this value when
7388 // calling the wrapped function.
7389 DECL_ACCESSORS(bound_this, Object)
7390
7391 // [bound_arguments]: A list of values whose elements are used as the first
7392 // arguments to any call to the wrapped function.
7393 DECL_ACCESSORS(bound_arguments, FixedArray)
7394
Ben Murdochc5610432016-08-08 18:44:38 +01007395 static MaybeHandle<String> GetName(Isolate* isolate,
7396 Handle<JSBoundFunction> function);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007397 static MaybeHandle<Context> GetFunctionRealm(
7398 Handle<JSBoundFunction> function);
7399
7400 DECLARE_CAST(JSBoundFunction)
7401
7402 // Dispatched behavior.
7403 DECLARE_PRINTER(JSBoundFunction)
7404 DECLARE_VERIFIER(JSBoundFunction)
7405
7406 // The bound function's string representation implemented according
7407 // to ES6 section 19.2.3.5 Function.prototype.toString ( ).
7408 static Handle<String> ToString(Handle<JSBoundFunction> function);
7409
7410 // Layout description.
7411 static const int kBoundTargetFunctionOffset = JSObject::kHeaderSize;
7412 static const int kBoundThisOffset = kBoundTargetFunctionOffset + kPointerSize;
7413 static const int kBoundArgumentsOffset = kBoundThisOffset + kPointerSize;
Ben Murdochc5610432016-08-08 18:44:38 +01007414 static const int kSize = kBoundArgumentsOffset + kPointerSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007415
7416 private:
7417 DISALLOW_IMPLICIT_CONSTRUCTORS(JSBoundFunction);
7418};
7419
7420
Steve Blocka7e24c12009-10-30 11:49:00 +00007421// JSFunction describes JavaScript functions.
7422class JSFunction: public JSObject {
7423 public:
7424 // [prototype_or_initial_map]:
7425 DECL_ACCESSORS(prototype_or_initial_map, Object)
7426
Ben Murdoch589d6972011-11-30 16:04:58 +00007427 // [shared]: The information about the function that
Steve Blocka7e24c12009-10-30 11:49:00 +00007428 // can be shared by instances.
7429 DECL_ACCESSORS(shared, SharedFunctionInfo)
7430
7431 // [context]: The context for this function.
7432 inline Context* context();
Steve Blocka7e24c12009-10-30 11:49:00 +00007433 inline void set_context(Object* context);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007434 inline JSObject* global_proxy();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007435 inline Context* native_context();
7436
Ben Murdochc5610432016-08-08 18:44:38 +01007437 static Handle<Object> GetName(Isolate* isolate, Handle<JSFunction> function);
7438 static MaybeHandle<Smi> GetLength(Isolate* isolate,
7439 Handle<JSFunction> function);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007440 static Handle<Context> GetFunctionRealm(Handle<JSFunction> function);
Steve Blocka7e24c12009-10-30 11:49:00 +00007441
7442 // [code]: The generated code object for this function. Executed
7443 // when the function is invoked, e.g. foo() or new foo(). See
7444 // [[Call]] and [[Construct]] description in ECMA-262, section
7445 // 8.6.2, page 27.
7446 inline Code* code();
Ben Murdochb0fe1622011-05-05 13:52:32 +01007447 inline void set_code(Code* code);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007448 inline void set_code_no_write_barrier(Code* code);
Ben Murdochb0fe1622011-05-05 13:52:32 +01007449 inline void ReplaceCode(Code* code);
Steve Blocka7e24c12009-10-30 11:49:00 +00007450
Ben Murdochda12d292016-06-02 14:46:10 +01007451 // Get the abstract code associated with the function, which will either be
7452 // a Code object or a BytecodeArray.
7453 inline AbstractCode* abstract_code();
7454
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007455 // Tells whether this function inlines the given shared function info.
7456 bool Inlines(SharedFunctionInfo* candidate);
Ben Murdochb0fe1622011-05-05 13:52:32 +01007457
7458 // Tells whether or not this function has been optimized.
7459 inline bool IsOptimized();
7460
Ben Murdochc5610432016-08-08 18:44:38 +01007461 // Mark this function for lazy recompilation. The function will be recompiled
7462 // the next time it is executed.
7463 void MarkForBaseline();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007464 void MarkForOptimization();
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007465 void AttemptConcurrentOptimization();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007466
Ben Murdochc5610432016-08-08 18:44:38 +01007467 // Tells whether or not the function is already marked for lazy recompilation.
7468 inline bool IsMarkedForBaseline();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007469 inline bool IsMarkedForOptimization();
7470 inline bool IsMarkedForConcurrentOptimization();
Ben Murdochb0fe1622011-05-05 13:52:32 +01007471
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007472 // Tells whether or not the function is on the concurrent recompilation queue.
7473 inline bool IsInOptimizationQueue();
7474
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007475 // Completes inobject slack tracking on initial map if it is active.
7476 inline void CompleteInobjectSlackTrackingIfActive();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007477
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007478 // [literals]: Fixed array holding the materialized literals.
Steve Blocka7e24c12009-10-30 11:49:00 +00007479 //
7480 // If the function contains object, regexp or array literals, the
7481 // literals array prefix contains the object, regexp, and array
7482 // function to be used when creating these literals. This is
7483 // necessary so that we do not dynamically lookup the object, regexp
7484 // or array functions. Performing a dynamic lookup, we might end up
7485 // using the functions from a new context that we should not have
7486 // access to.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007487 DECL_ACCESSORS(literals, LiteralsArray)
Steve Blocka7e24c12009-10-30 11:49:00 +00007488
7489 // The initial map for an object created by this constructor.
7490 inline Map* initial_map();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007491 static void SetInitialMap(Handle<JSFunction> function, Handle<Map> map,
7492 Handle<Object> prototype);
Steve Blocka7e24c12009-10-30 11:49:00 +00007493 inline bool has_initial_map();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007494 static void EnsureHasInitialMap(Handle<JSFunction> function);
Steve Blocka7e24c12009-10-30 11:49:00 +00007495
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007496 // Creates a map that matches the constructor's initial map, but with
7497 // [[prototype]] being new.target.prototype. Because new.target can be a
7498 // JSProxy, this can call back into JavaScript.
7499 static MUST_USE_RESULT MaybeHandle<Map> GetDerivedMap(
7500 Isolate* isolate, Handle<JSFunction> constructor,
7501 Handle<JSReceiver> new_target);
7502
Steve Blocka7e24c12009-10-30 11:49:00 +00007503 // Get and set the prototype property on a JSFunction. If the
7504 // function has an initial map the prototype is set on the initial
7505 // map. Otherwise, the prototype is put in the initial map field
7506 // until an initial map is needed.
7507 inline bool has_prototype();
7508 inline bool has_instance_prototype();
7509 inline Object* prototype();
7510 inline Object* instance_prototype();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007511 static void SetPrototype(Handle<JSFunction> function,
7512 Handle<Object> value);
7513 static void SetInstancePrototype(Handle<JSFunction> function,
7514 Handle<Object> value);
7515
Steve Block6ded16b2010-05-10 14:33:55 +01007516 // After prototype is removed, it will not be created when accessed, and
7517 // [[Construct]] from this function will not be allowed.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007518 bool RemovePrototype();
Steve Blocka7e24c12009-10-30 11:49:00 +00007519
7520 // Returns if this function has been compiled to native code yet.
7521 inline bool is_compiled();
7522
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007523 // [next_function_link]: Links functions into various lists, e.g. the list
7524 // of optimized functions hanging off the native_context. The CodeFlusher
7525 // uses this link to chain together flushing candidates. Treated weakly
7526 // by the garbage collector.
Ben Murdochb0fe1622011-05-05 13:52:32 +01007527 DECL_ACCESSORS(next_function_link, Object)
7528
7529 // Prints the name of the function using PrintF.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007530 void PrintName(FILE* out = stdout);
Ben Murdochb0fe1622011-05-05 13:52:32 +01007531
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007532 DECLARE_CAST(JSFunction)
Steve Blocka7e24c12009-10-30 11:49:00 +00007533
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007534 // Calculate the instance size and in-object properties count.
7535 void CalculateInstanceSize(InstanceType instance_type,
7536 int requested_internal_fields, int* instance_size,
7537 int* in_object_properties);
7538 void CalculateInstanceSizeForDerivedClass(InstanceType instance_type,
7539 int requested_internal_fields,
7540 int* instance_size,
7541 int* in_object_properties);
Ben Murdochda12d292016-06-02 14:46:10 +01007542 static void CalculateInstanceSizeHelper(InstanceType instance_type,
7543 int requested_internal_fields,
7544 int requested_in_object_properties,
7545 int* instance_size,
7546 int* in_object_properties);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007547 // Visiting policy flags define whether the code entry or next function
7548 // should be visited or not.
7549 enum BodyVisitingPolicy {
7550 kVisitCodeEntry = 1 << 0,
7551 kVisitNextFunction = 1 << 1,
7552
7553 kSkipCodeEntryAndNextFunction = 0,
7554 kVisitCodeEntryAndNextFunction = kVisitCodeEntry | kVisitNextFunction
7555 };
7556 // Iterates the function object according to the visiting policy.
7557 template <BodyVisitingPolicy>
7558 class BodyDescriptorImpl;
7559
7560 // Visit the whole object.
7561 typedef BodyDescriptorImpl<kVisitCodeEntryAndNextFunction> BodyDescriptor;
7562
7563 // Don't visit next function.
7564 typedef BodyDescriptorImpl<kVisitCodeEntry> BodyDescriptorStrongCode;
7565 typedef BodyDescriptorImpl<kSkipCodeEntryAndNextFunction>
7566 BodyDescriptorWeakCode;
Steve Block791712a2010-08-27 10:21:07 +01007567
Steve Blocka7e24c12009-10-30 11:49:00 +00007568 // Dispatched behavior.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007569 DECLARE_PRINTER(JSFunction)
7570 DECLARE_VERIFIER(JSFunction)
Steve Blocka7e24c12009-10-30 11:49:00 +00007571
7572 // Returns the number of allocated literals.
7573 inline int NumberOfLiterals();
7574
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007575 // The function's name if it is configured, otherwise shared function info
7576 // debug name.
7577 static Handle<String> GetName(Handle<JSFunction> function);
7578
Ben Murdoch097c5b22016-05-18 11:27:45 +01007579 // ES6 section 9.2.11 SetFunctionName
7580 // Because of the way this abstract operation is used in the spec,
7581 // it should never fail.
7582 static void SetName(Handle<JSFunction> function, Handle<Name> name,
7583 Handle<String> prefix);
7584
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007585 // The function's displayName if it is set, otherwise name if it is
7586 // configured, otherwise shared function info
7587 // debug name.
7588 static Handle<String> GetDebugName(Handle<JSFunction> function);
7589
7590 // The function's string representation implemented according to
7591 // ES6 section 19.2.3.5 Function.prototype.toString ( ).
7592 static Handle<String> ToString(Handle<JSFunction> function);
7593
Ben Murdochb0fe1622011-05-05 13:52:32 +01007594 // Layout descriptors. The last property (from kNonWeakFieldsEndOffset to
7595 // kSize) is weak and has special handling during garbage collection.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007596 static const int kPrototypeOrInitialMapOffset = JSObject::kHeaderSize;
Steve Blocka7e24c12009-10-30 11:49:00 +00007597 static const int kSharedFunctionInfoOffset =
7598 kPrototypeOrInitialMapOffset + kPointerSize;
7599 static const int kContextOffset = kSharedFunctionInfoOffset + kPointerSize;
7600 static const int kLiteralsOffset = kContextOffset + kPointerSize;
Ben Murdochb0fe1622011-05-05 13:52:32 +01007601 static const int kNonWeakFieldsEndOffset = kLiteralsOffset + kPointerSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007602 static const int kCodeEntryOffset = kNonWeakFieldsEndOffset;
7603 static const int kNextFunctionLinkOffset = kCodeEntryOffset + kPointerSize;
Ben Murdochb0fe1622011-05-05 13:52:32 +01007604 static const int kSize = kNextFunctionLinkOffset + kPointerSize;
Steve Blocka7e24c12009-10-30 11:49:00 +00007605
Steve Blocka7e24c12009-10-30 11:49:00 +00007606 private:
7607 DISALLOW_IMPLICIT_CONSTRUCTORS(JSFunction);
7608};
7609
7610
7611// JSGlobalProxy's prototype must be a JSGlobalObject or null,
7612// and the prototype is hidden. JSGlobalProxy always delegates
7613// property accesses to its prototype if the prototype is not null.
7614//
7615// A JSGlobalProxy can be reinitialized which will preserve its identity.
7616//
7617// Accessing a JSGlobalProxy requires security check.
7618
7619class JSGlobalProxy : public JSObject {
7620 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007621 // [native_context]: the owner native context of this global proxy object.
Steve Blocka7e24c12009-10-30 11:49:00 +00007622 // It is null value if this object is not used by any context.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007623 DECL_ACCESSORS(native_context, Object)
Steve Blocka7e24c12009-10-30 11:49:00 +00007624
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007625 // [hash]: The hash code property (undefined if not initialized yet).
7626 DECL_ACCESSORS(hash, Object)
7627
7628 DECLARE_CAST(JSGlobalProxy)
7629
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007630 inline bool IsDetachedFrom(JSGlobalObject* global) const;
Steve Blocka7e24c12009-10-30 11:49:00 +00007631
7632 // Dispatched behavior.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007633 DECLARE_PRINTER(JSGlobalProxy)
7634 DECLARE_VERIFIER(JSGlobalProxy)
Steve Blocka7e24c12009-10-30 11:49:00 +00007635
7636 // Layout description.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007637 static const int kNativeContextOffset = JSObject::kHeaderSize;
7638 static const int kHashOffset = kNativeContextOffset + kPointerSize;
7639 static const int kSize = kHashOffset + kPointerSize;
Steve Blocka7e24c12009-10-30 11:49:00 +00007640
7641 private:
Steve Blocka7e24c12009-10-30 11:49:00 +00007642 DISALLOW_IMPLICIT_CONSTRUCTORS(JSGlobalProxy);
7643};
7644
7645
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007646// JavaScript global object.
7647class JSGlobalObject : public JSObject {
Steve Blocka7e24c12009-10-30 11:49:00 +00007648 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007649 // [native context]: the natives corresponding to this global object.
7650 DECL_ACCESSORS(native_context, Context)
7651
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007652 // [global proxy]: the global proxy object of the context
7653 DECL_ACCESSORS(global_proxy, JSObject)
Steve Blocka7e24c12009-10-30 11:49:00 +00007654
Steve Blocka7e24c12009-10-30 11:49:00 +00007655
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007656 static void InvalidatePropertyCell(Handle<JSGlobalObject> object,
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007657 Handle<Name> name);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007658 // Ensure that the global object has a cell for the given property name.
7659 static Handle<PropertyCell> EnsurePropertyCell(Handle<JSGlobalObject> global,
7660 Handle<Name> name);
7661
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007662 DECLARE_CAST(JSGlobalObject)
7663
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007664 inline bool IsDetached();
Steve Blocka7e24c12009-10-30 11:49:00 +00007665
7666 // Dispatched behavior.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007667 DECLARE_PRINTER(JSGlobalObject)
7668 DECLARE_VERIFIER(JSGlobalObject)
Steve Blocka7e24c12009-10-30 11:49:00 +00007669
7670 // Layout description.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007671 static const int kNativeContextOffset = JSObject::kHeaderSize;
7672 static const int kGlobalProxyOffset = kNativeContextOffset + kPointerSize;
7673 static const int kHeaderSize = kGlobalProxyOffset + kPointerSize;
7674 static const int kSize = kHeaderSize;
Steve Blocka7e24c12009-10-30 11:49:00 +00007675
7676 private:
7677 DISALLOW_IMPLICIT_CONSTRUCTORS(JSGlobalObject);
7678};
7679
7680
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007681// Representation for JS Wrapper objects, String, Number, Boolean, etc.
Steve Blocka7e24c12009-10-30 11:49:00 +00007682class JSValue: public JSObject {
7683 public:
7684 // [value]: the object being wrapped.
7685 DECL_ACCESSORS(value, Object)
7686
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007687 DECLARE_CAST(JSValue)
Steve Blocka7e24c12009-10-30 11:49:00 +00007688
7689 // Dispatched behavior.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007690 DECLARE_PRINTER(JSValue)
7691 DECLARE_VERIFIER(JSValue)
Steve Blocka7e24c12009-10-30 11:49:00 +00007692
7693 // Layout description.
7694 static const int kValueOffset = JSObject::kHeaderSize;
7695 static const int kSize = kValueOffset + kPointerSize;
7696
7697 private:
7698 DISALLOW_IMPLICIT_CONSTRUCTORS(JSValue);
7699};
7700
Steve Block1e0659c2011-05-24 12:43:12 +01007701
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007702class DateCache;
7703
7704// Representation for JS date objects.
7705class JSDate: public JSObject {
7706 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007707 static MUST_USE_RESULT MaybeHandle<JSDate> New(Handle<JSFunction> constructor,
7708 Handle<JSReceiver> new_target,
7709 double tv);
7710
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007711 // If one component is NaN, all of them are, indicating a NaN time value.
7712 // [value]: the time value.
7713 DECL_ACCESSORS(value, Object)
7714 // [year]: caches year. Either undefined, smi, or NaN.
7715 DECL_ACCESSORS(year, Object)
7716 // [month]: caches month. Either undefined, smi, or NaN.
7717 DECL_ACCESSORS(month, Object)
7718 // [day]: caches day. Either undefined, smi, or NaN.
7719 DECL_ACCESSORS(day, Object)
7720 // [weekday]: caches day of week. Either undefined, smi, or NaN.
7721 DECL_ACCESSORS(weekday, Object)
7722 // [hour]: caches hours. Either undefined, smi, or NaN.
7723 DECL_ACCESSORS(hour, Object)
7724 // [min]: caches minutes. Either undefined, smi, or NaN.
7725 DECL_ACCESSORS(min, Object)
7726 // [sec]: caches seconds. Either undefined, smi, or NaN.
7727 DECL_ACCESSORS(sec, Object)
7728 // [cache stamp]: sample of the date cache stamp at the
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007729 // moment when chached fields were cached.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007730 DECL_ACCESSORS(cache_stamp, Object)
7731
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007732 DECLARE_CAST(JSDate)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007733
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007734 // Returns the time value (UTC) identifying the current time.
7735 static double CurrentTimeValue(Isolate* isolate);
7736
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007737 // Returns the date field with the specified index.
7738 // See FieldIndex for the list of date fields.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007739 static Object* GetField(Object* date, Smi* index);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007740
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007741 static Handle<Object> SetValue(Handle<JSDate> date, double v);
7742
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007743 void SetValue(Object* value, bool is_value_nan);
7744
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007745 // ES6 section 20.3.4.45 Date.prototype [ @@toPrimitive ]
7746 static MUST_USE_RESULT MaybeHandle<Object> ToPrimitive(
7747 Handle<JSReceiver> receiver, Handle<Object> hint);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007748
7749 // Dispatched behavior.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007750 DECLARE_PRINTER(JSDate)
7751 DECLARE_VERIFIER(JSDate)
7752
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007753 // The order is important. It must be kept in sync with date macros
7754 // in macros.py.
7755 enum FieldIndex {
7756 kDateValue,
7757 kYear,
7758 kMonth,
7759 kDay,
7760 kWeekday,
7761 kHour,
7762 kMinute,
7763 kSecond,
7764 kFirstUncachedField,
7765 kMillisecond = kFirstUncachedField,
7766 kDays,
7767 kTimeInDay,
7768 kFirstUTCField,
7769 kYearUTC = kFirstUTCField,
7770 kMonthUTC,
7771 kDayUTC,
7772 kWeekdayUTC,
7773 kHourUTC,
7774 kMinuteUTC,
7775 kSecondUTC,
7776 kMillisecondUTC,
7777 kDaysUTC,
7778 kTimeInDayUTC,
7779 kTimezoneOffset
7780 };
7781
7782 // Layout description.
7783 static const int kValueOffset = JSObject::kHeaderSize;
7784 static const int kYearOffset = kValueOffset + kPointerSize;
7785 static const int kMonthOffset = kYearOffset + kPointerSize;
7786 static const int kDayOffset = kMonthOffset + kPointerSize;
7787 static const int kWeekdayOffset = kDayOffset + kPointerSize;
7788 static const int kHourOffset = kWeekdayOffset + kPointerSize;
7789 static const int kMinOffset = kHourOffset + kPointerSize;
7790 static const int kSecOffset = kMinOffset + kPointerSize;
7791 static const int kCacheStampOffset = kSecOffset + kPointerSize;
7792 static const int kSize = kCacheStampOffset + kPointerSize;
7793
7794 private:
7795 inline Object* DoGetField(FieldIndex index);
7796
7797 Object* GetUTCField(FieldIndex index, double value, DateCache* date_cache);
7798
7799 // Computes and caches the cacheable fields of the date.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007800 inline void SetCachedFields(int64_t local_time_ms, DateCache* date_cache);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007801
7802
7803 DISALLOW_IMPLICIT_CONSTRUCTORS(JSDate);
7804};
7805
7806
Steve Block1e0659c2011-05-24 12:43:12 +01007807// Representation of message objects used for error reporting through
7808// the API. The messages are formatted in JavaScript so this object is
7809// a real JavaScript object. The information used for formatting the
7810// error messages are not directly accessible from JavaScript to
7811// prevent leaking information to user code called during error
7812// formatting.
7813class JSMessageObject: public JSObject {
7814 public:
7815 // [type]: the type of error message.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007816 inline int type() const;
7817 inline void set_type(int value);
Steve Block1e0659c2011-05-24 12:43:12 +01007818
7819 // [arguments]: the arguments for formatting the error message.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007820 DECL_ACCESSORS(argument, Object)
Steve Block1e0659c2011-05-24 12:43:12 +01007821
7822 // [script]: the script from which the error message originated.
7823 DECL_ACCESSORS(script, Object)
7824
Steve Block1e0659c2011-05-24 12:43:12 +01007825 // [stack_frames]: an array of stack frames for this error object.
7826 DECL_ACCESSORS(stack_frames, Object)
7827
7828 // [start_position]: the start position in the script for the error message.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007829 inline int start_position() const;
Steve Block1e0659c2011-05-24 12:43:12 +01007830 inline void set_start_position(int value);
7831
7832 // [end_position]: the end position in the script for the error message.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007833 inline int end_position() const;
Steve Block1e0659c2011-05-24 12:43:12 +01007834 inline void set_end_position(int value);
7835
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007836 DECLARE_CAST(JSMessageObject)
Steve Block1e0659c2011-05-24 12:43:12 +01007837
7838 // Dispatched behavior.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007839 DECLARE_PRINTER(JSMessageObject)
7840 DECLARE_VERIFIER(JSMessageObject)
Steve Block1e0659c2011-05-24 12:43:12 +01007841
7842 // Layout description.
7843 static const int kTypeOffset = JSObject::kHeaderSize;
7844 static const int kArgumentsOffset = kTypeOffset + kPointerSize;
7845 static const int kScriptOffset = kArgumentsOffset + kPointerSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007846 static const int kStackFramesOffset = kScriptOffset + kPointerSize;
Steve Block1e0659c2011-05-24 12:43:12 +01007847 static const int kStartPositionOffset = kStackFramesOffset + kPointerSize;
7848 static const int kEndPositionOffset = kStartPositionOffset + kPointerSize;
7849 static const int kSize = kEndPositionOffset + kPointerSize;
7850
7851 typedef FixedBodyDescriptor<HeapObject::kMapOffset,
7852 kStackFramesOffset + kPointerSize,
7853 kSize> BodyDescriptor;
7854};
7855
7856
Steve Blocka7e24c12009-10-30 11:49:00 +00007857// Regular expressions
7858// The regular expression holds a single reference to a FixedArray in
7859// the kDataOffset field.
7860// The FixedArray contains the following data:
7861// - tag : type of regexp implementation (not compiled yet, atom or irregexp)
7862// - reference to the original source string
7863// - reference to the original flag string
7864// If it is an atom regexp
7865// - a reference to a literal string to search for
7866// If it is an irregexp regexp:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007867// - a reference to code for Latin1 inputs (bytecode or compiled), or a smi
Ben Murdoch257744e2011-11-30 15:57:28 +00007868// used for tracking the last usage (used for code flushing).
7869// - a reference to code for UC16 inputs (bytecode or compiled), or a smi
7870// used for tracking the last usage (used for code flushing)..
Steve Blocka7e24c12009-10-30 11:49:00 +00007871// - max number of registers used by irregexp implementations.
7872// - number of capture registers (output values) of the regexp.
7873class JSRegExp: public JSObject {
7874 public:
7875 // Meaning of Type:
7876 // NOT_COMPILED: Initial value. No data has been stored in the JSRegExp yet.
7877 // ATOM: A simple string to match against using an indexOf operation.
7878 // IRREGEXP: Compiled with Irregexp.
7879 // IRREGEXP_NATIVE: Compiled to native code with Irregexp.
7880 enum Type { NOT_COMPILED, ATOM, IRREGEXP };
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007881 enum Flag {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007882 kNone = 0,
7883 kGlobal = 1 << 0,
7884 kIgnoreCase = 1 << 1,
7885 kMultiline = 1 << 2,
7886 kSticky = 1 << 3,
7887 kUnicode = 1 << 4,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007888 };
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007889 typedef base::Flags<Flag> Flags;
Steve Blocka7e24c12009-10-30 11:49:00 +00007890
7891 DECL_ACCESSORS(data, Object)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007892 DECL_ACCESSORS(flags, Object)
7893 DECL_ACCESSORS(source, Object)
7894
7895 static MaybeHandle<JSRegExp> New(Handle<String> source, Flags flags);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007896 static Handle<JSRegExp> Copy(Handle<JSRegExp> regexp);
7897
7898 static MaybeHandle<JSRegExp> Initialize(Handle<JSRegExp> regexp,
7899 Handle<String> source, Flags flags);
7900 static MaybeHandle<JSRegExp> Initialize(Handle<JSRegExp> regexp,
7901 Handle<String> source,
7902 Handle<String> flags_string);
Steve Blocka7e24c12009-10-30 11:49:00 +00007903
7904 inline Type TypeTag();
7905 inline int CaptureCount();
7906 inline Flags GetFlags();
7907 inline String* Pattern();
7908 inline Object* DataAt(int index);
7909 // Set implementation data after the object has been prepared.
7910 inline void SetDataAt(int index, Object* value);
Ben Murdoch257744e2011-11-30 15:57:28 +00007911
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007912 static int code_index(bool is_latin1) {
7913 if (is_latin1) {
7914 return kIrregexpLatin1CodeIndex;
Steve Blocka7e24c12009-10-30 11:49:00 +00007915 } else {
7916 return kIrregexpUC16CodeIndex;
7917 }
7918 }
7919
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007920 static int saved_code_index(bool is_latin1) {
7921 if (is_latin1) {
7922 return kIrregexpLatin1CodeSavedIndex;
Ben Murdoch257744e2011-11-30 15:57:28 +00007923 } else {
7924 return kIrregexpUC16CodeSavedIndex;
7925 }
7926 }
7927
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007928 DECLARE_CAST(JSRegExp)
Steve Blocka7e24c12009-10-30 11:49:00 +00007929
7930 // Dispatched behavior.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007931 DECLARE_PRINTER(JSRegExp)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007932 DECLARE_VERIFIER(JSRegExp)
Steve Blocka7e24c12009-10-30 11:49:00 +00007933
7934 static const int kDataOffset = JSObject::kHeaderSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007935 static const int kSourceOffset = kDataOffset + kPointerSize;
7936 static const int kFlagsOffset = kSourceOffset + kPointerSize;
7937 static const int kSize = kFlagsOffset + kPointerSize;
Steve Blocka7e24c12009-10-30 11:49:00 +00007938
7939 // Indices in the data array.
7940 static const int kTagIndex = 0;
7941 static const int kSourceIndex = kTagIndex + 1;
7942 static const int kFlagsIndex = kSourceIndex + 1;
7943 static const int kDataIndex = kFlagsIndex + 1;
7944 // The data fields are used in different ways depending on the
7945 // value of the tag.
7946 // Atom regexps (literal strings).
7947 static const int kAtomPatternIndex = kDataIndex;
7948
7949 static const int kAtomDataSize = kAtomPatternIndex + 1;
7950
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007951 // Irregexp compiled code or bytecode for Latin1. If compilation
Steve Blocka7e24c12009-10-30 11:49:00 +00007952 // fails, this fields hold an exception object that should be
7953 // thrown if the regexp is used again.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007954 static const int kIrregexpLatin1CodeIndex = kDataIndex;
Steve Blocka7e24c12009-10-30 11:49:00 +00007955 // Irregexp compiled code or bytecode for UC16. If compilation
7956 // fails, this fields hold an exception object that should be
7957 // thrown if the regexp is used again.
7958 static const int kIrregexpUC16CodeIndex = kDataIndex + 1;
Ben Murdoch257744e2011-11-30 15:57:28 +00007959
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007960 // Saved instance of Irregexp compiled code or bytecode for Latin1 that
Ben Murdoch257744e2011-11-30 15:57:28 +00007961 // is a potential candidate for flushing.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007962 static const int kIrregexpLatin1CodeSavedIndex = kDataIndex + 2;
Ben Murdoch257744e2011-11-30 15:57:28 +00007963 // Saved instance of Irregexp compiled code or bytecode for UC16 that is
7964 // a potential candidate for flushing.
7965 static const int kIrregexpUC16CodeSavedIndex = kDataIndex + 3;
7966
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007967 // Maximal number of registers used by either Latin1 or UC16.
Steve Blocka7e24c12009-10-30 11:49:00 +00007968 // Only used to check that there is enough stack space
Ben Murdoch257744e2011-11-30 15:57:28 +00007969 static const int kIrregexpMaxRegisterCountIndex = kDataIndex + 4;
Steve Blocka7e24c12009-10-30 11:49:00 +00007970 // Number of captures in the compiled regexp.
Ben Murdoch257744e2011-11-30 15:57:28 +00007971 static const int kIrregexpCaptureCountIndex = kDataIndex + 5;
Steve Blocka7e24c12009-10-30 11:49:00 +00007972
7973 static const int kIrregexpDataSize = kIrregexpCaptureCountIndex + 1;
Leon Clarkee46be812010-01-19 14:06:41 +00007974
7975 // Offsets directly into the data fixed array.
7976 static const int kDataTagOffset =
7977 FixedArray::kHeaderSize + kTagIndex * kPointerSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007978 static const int kDataOneByteCodeOffset =
7979 FixedArray::kHeaderSize + kIrregexpLatin1CodeIndex * kPointerSize;
Leon Clarked91b9f72010-01-27 17:25:45 +00007980 static const int kDataUC16CodeOffset =
7981 FixedArray::kHeaderSize + kIrregexpUC16CodeIndex * kPointerSize;
Leon Clarkee46be812010-01-19 14:06:41 +00007982 static const int kIrregexpCaptureCountOffset =
7983 FixedArray::kHeaderSize + kIrregexpCaptureCountIndex * kPointerSize;
Steve Block6ded16b2010-05-10 14:33:55 +01007984
7985 // In-object fields.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007986 static const int kLastIndexFieldIndex = 0;
7987 static const int kInObjectFieldCount = 1;
Ben Murdoch257744e2011-11-30 15:57:28 +00007988
7989 // The uninitialized value for a regexp code object.
7990 static const int kUninitializedValue = -1;
7991
7992 // The compilation error value for the regexp code object. The real error
7993 // object is in the saved code field.
7994 static const int kCompilationErrorValue = -2;
7995
7996 // When we store the sweep generation at which we moved the code from the
7997 // code index to the saved code index we mask it of to be in the [0:255]
7998 // range.
7999 static const int kCodeAgeMask = 0xff;
Steve Blocka7e24c12009-10-30 11:49:00 +00008000};
8001
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008002DEFINE_OPERATORS_FOR_FLAGS(JSRegExp::Flags)
8003
Steve Blocka7e24c12009-10-30 11:49:00 +00008004
Ben Murdochc7cc0282012-03-05 14:35:55 +00008005class CompilationCacheShape : public BaseShape<HashTableKey*> {
Steve Blocka7e24c12009-10-30 11:49:00 +00008006 public:
8007 static inline bool IsMatch(HashTableKey* key, Object* value) {
8008 return key->IsMatch(value);
8009 }
8010
8011 static inline uint32_t Hash(HashTableKey* key) {
8012 return key->Hash();
8013 }
8014
8015 static inline uint32_t HashForObject(HashTableKey* key, Object* object) {
8016 return key->HashForObject(object);
8017 }
8018
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008019 static inline Handle<Object> AsHandle(Isolate* isolate, HashTableKey* key);
Steve Blocka7e24c12009-10-30 11:49:00 +00008020
8021 static const int kPrefixSize = 0;
8022 static const int kEntrySize = 2;
8023};
8024
Steve Block3ce2e202009-11-05 08:53:23 +00008025
Emily Bernierd0a1eb72015-03-24 16:35:39 -04008026// This cache is used in two different variants. For regexp caching, it simply
8027// maps identifying info of the regexp to the cached regexp object. Scripts and
8028// eval code only gets cached after a second probe for the code object. To do
8029// so, on first "put" only a hash identifying the source is entered into the
8030// cache, mapping it to a lifetime count of the hash. On each call to Age all
8031// such lifetimes get reduced, and removed once they reach zero. If a second put
8032// is called while such a hash is live in the cache, the hash gets replaced by
8033// an actual cache entry. Age also removes stale live entries from the cache.
8034// Such entries are identified by SharedFunctionInfos pointing to either the
8035// recompilation stub, or to "old" code. This avoids memory leaks due to
8036// premature caching of scripts and eval strings that are never needed later.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008037class CompilationCacheTable: public HashTable<CompilationCacheTable,
8038 CompilationCacheShape,
Steve Blocka7e24c12009-10-30 11:49:00 +00008039 HashTableKey*> {
8040 public:
8041 // Find cached value for a string key, otherwise return null.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008042 Handle<Object> Lookup(
8043 Handle<String> src, Handle<Context> context, LanguageMode language_mode);
8044 Handle<Object> LookupEval(
8045 Handle<String> src, Handle<SharedFunctionInfo> shared,
8046 LanguageMode language_mode, int scope_position);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008047 Handle<Object> LookupRegExp(Handle<String> source, JSRegExp::Flags flags);
8048 static Handle<CompilationCacheTable> Put(
8049 Handle<CompilationCacheTable> cache, Handle<String> src,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008050 Handle<Context> context, LanguageMode language_mode,
8051 Handle<Object> value);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008052 static Handle<CompilationCacheTable> PutEval(
8053 Handle<CompilationCacheTable> cache, Handle<String> src,
8054 Handle<SharedFunctionInfo> context, Handle<SharedFunctionInfo> value,
8055 int scope_position);
8056 static Handle<CompilationCacheTable> PutRegExp(
8057 Handle<CompilationCacheTable> cache, Handle<String> src,
8058 JSRegExp::Flags flags, Handle<FixedArray> value);
Ben Murdochb0fe1622011-05-05 13:52:32 +01008059 void Remove(Object* value);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04008060 void Age();
8061 static const int kHashGenerations = 10;
Ben Murdochb0fe1622011-05-05 13:52:32 +01008062
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008063 DECLARE_CAST(CompilationCacheTable)
Steve Blocka7e24c12009-10-30 11:49:00 +00008064
8065 private:
8066 DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationCacheTable);
8067};
8068
8069
Ben Murdochc7cc0282012-03-05 14:35:55 +00008070class CodeCacheHashTableShape : public BaseShape<HashTableKey*> {
Steve Block6ded16b2010-05-10 14:33:55 +01008071 public:
8072 static inline bool IsMatch(HashTableKey* key, Object* value) {
8073 return key->IsMatch(value);
8074 }
8075
8076 static inline uint32_t Hash(HashTableKey* key) {
8077 return key->Hash();
8078 }
8079
8080 static inline uint32_t HashForObject(HashTableKey* key, Object* object) {
8081 return key->HashForObject(object);
8082 }
8083
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008084 static inline Handle<Object> AsHandle(Isolate* isolate, HashTableKey* key);
Steve Block6ded16b2010-05-10 14:33:55 +01008085
8086 static const int kPrefixSize = 0;
Ben Murdochc5610432016-08-08 18:44:38 +01008087 // The both the key (name + flags) and value (code object) can be derived from
8088 // the fixed array that stores both the name and code.
8089 // TODO(verwaest): Don't allocate a fixed array but inline name and code.
8090 // Rewrite IsMatch to get table + index as input rather than just the raw key.
8091 static const int kEntrySize = 1;
Steve Block6ded16b2010-05-10 14:33:55 +01008092};
8093
8094
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008095class CodeCacheHashTable: public HashTable<CodeCacheHashTable,
8096 CodeCacheHashTableShape,
Steve Block6ded16b2010-05-10 14:33:55 +01008097 HashTableKey*> {
8098 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008099 static Handle<CodeCacheHashTable> Put(
8100 Handle<CodeCacheHashTable> table,
8101 Handle<Name> name,
8102 Handle<Code> code);
Steve Block6ded16b2010-05-10 14:33:55 +01008103
Ben Murdochc5610432016-08-08 18:44:38 +01008104 Code* Lookup(Name* name, Code::Flags flags);
Steve Block6ded16b2010-05-10 14:33:55 +01008105
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008106 DECLARE_CAST(CodeCacheHashTable)
Steve Block6ded16b2010-05-10 14:33:55 +01008107
8108 // Initial size of the fixed array backing the hash table.
Ben Murdochc5610432016-08-08 18:44:38 +01008109 static const int kInitialSize = 16;
Steve Block6ded16b2010-05-10 14:33:55 +01008110
8111 private:
8112 DISALLOW_IMPLICIT_CONSTRUCTORS(CodeCacheHashTable);
8113};
8114
8115
Ben Murdoch3ef787d2012-04-12 10:51:47 +01008116class TypeFeedbackInfo: public Struct {
8117 public:
8118 inline int ic_total_count();
8119 inline void set_ic_total_count(int count);
8120
Ben Murdoch8f9999f2012-04-23 10:39:17 +01008121 inline int ic_with_type_info_count();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008122 inline void change_ic_with_type_info_count(int delta);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01008123
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008124 inline int ic_generic_count();
8125 inline void change_ic_generic_count(int delta);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01008126
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008127 inline void initialize_storage();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01008128
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008129 inline void change_own_type_change_checksum();
8130 inline int own_type_change_checksum();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01008131
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008132 inline void set_inlined_type_change_checksum(int checksum);
8133 inline bool matches_inlined_type_change_checksum(int checksum);
8134
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008135 DECLARE_CAST(TypeFeedbackInfo)
8136
8137 // Dispatched behavior.
8138 DECLARE_PRINTER(TypeFeedbackInfo)
8139 DECLARE_VERIFIER(TypeFeedbackInfo)
8140
8141 static const int kStorage1Offset = HeapObject::kHeaderSize;
8142 static const int kStorage2Offset = kStorage1Offset + kPointerSize;
8143 static const int kStorage3Offset = kStorage2Offset + kPointerSize;
8144 static const int kSize = kStorage3Offset + kPointerSize;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01008145
8146 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008147 static const int kTypeChangeChecksumBits = 7;
8148
8149 class ICTotalCountField: public BitField<int, 0,
8150 kSmiValueSize - kTypeChangeChecksumBits> {}; // NOLINT
8151 class OwnTypeChangeChecksum: public BitField<int,
8152 kSmiValueSize - kTypeChangeChecksumBits,
8153 kTypeChangeChecksumBits> {}; // NOLINT
8154 class ICsWithTypeInfoCountField: public BitField<int, 0,
8155 kSmiValueSize - kTypeChangeChecksumBits> {}; // NOLINT
8156 class InlinedTypeChangeChecksum: public BitField<int,
8157 kSmiValueSize - kTypeChangeChecksumBits,
8158 kTypeChangeChecksumBits> {}; // NOLINT
8159
Ben Murdoch3ef787d2012-04-12 10:51:47 +01008160 DISALLOW_IMPLICIT_CONSTRUCTORS(TypeFeedbackInfo);
8161};
8162
8163
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008164enum AllocationSiteMode {
8165 DONT_TRACK_ALLOCATION_SITE,
8166 TRACK_ALLOCATION_SITE,
8167 LAST_ALLOCATION_SITE_MODE = TRACK_ALLOCATION_SITE
8168};
8169
8170
8171class AllocationSite: public Struct {
8172 public:
8173 static const uint32_t kMaximumArrayBytesToPretransition = 8 * 1024;
8174 static const double kPretenureRatio;
8175 static const int kPretenureMinimumCreated = 100;
8176
8177 // Values for pretenure decision field.
8178 enum PretenureDecision {
8179 kUndecided = 0,
8180 kDontTenure = 1,
8181 kMaybeTenure = 2,
8182 kTenure = 3,
8183 kZombie = 4,
8184 kLastPretenureDecisionValue = kZombie
8185 };
8186
8187 const char* PretenureDecisionName(PretenureDecision decision);
8188
8189 DECL_ACCESSORS(transition_info, Object)
8190 // nested_site threads a list of sites that represent nested literals
8191 // walked in a particular order. So [[1, 2], 1, 2] will have one
8192 // nested_site, but [[1, 2], 3, [4]] will have a list of two.
8193 DECL_ACCESSORS(nested_site, Object)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008194 DECL_INT_ACCESSORS(pretenure_data)
8195 DECL_INT_ACCESSORS(pretenure_create_count)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008196 DECL_ACCESSORS(dependent_code, DependentCode)
8197 DECL_ACCESSORS(weak_next, Object)
8198
8199 inline void Initialize();
8200
8201 // This method is expensive, it should only be called for reporting.
8202 bool IsNestedSite();
8203
8204 // transition_info bitfields, for constructed array transition info.
8205 class ElementsKindBits: public BitField<ElementsKind, 0, 15> {};
8206 class UnusedBits: public BitField<int, 15, 14> {};
8207 class DoNotInlineBit: public BitField<bool, 29, 1> {};
8208
8209 // Bitfields for pretenure_data
8210 class MementoFoundCountBits: public BitField<int, 0, 26> {};
8211 class PretenureDecisionBits: public BitField<PretenureDecision, 26, 3> {};
8212 class DeoptDependentCodeBit: public BitField<bool, 29, 1> {};
8213 STATIC_ASSERT(PretenureDecisionBits::kMax >= kLastPretenureDecisionValue);
8214
8215 // Increments the mementos found counter and returns true when the first
8216 // memento was found for a given allocation site.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008217 inline bool IncrementMementoFoundCount(int increment = 1);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008218
8219 inline void IncrementMementoCreateCount();
8220
8221 PretenureFlag GetPretenureMode();
8222
8223 void ResetPretenureDecision();
8224
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008225 inline PretenureDecision pretenure_decision();
8226 inline void set_pretenure_decision(PretenureDecision decision);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008227
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008228 inline bool deopt_dependent_code();
8229 inline void set_deopt_dependent_code(bool deopt);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008230
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008231 inline int memento_found_count();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008232 inline void set_memento_found_count(int count);
8233
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008234 inline int memento_create_count();
8235 inline void set_memento_create_count(int count);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008236
8237 // The pretenuring decision is made during gc, and the zombie state allows
8238 // us to recognize when an allocation site is just being kept alive because
8239 // a later traversal of new space may discover AllocationMementos that point
8240 // to this AllocationSite.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008241 inline bool IsZombie();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008242
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008243 inline bool IsMaybeTenure();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008244
8245 inline void MarkZombie();
8246
8247 inline bool MakePretenureDecision(PretenureDecision current_decision,
8248 double ratio,
8249 bool maximum_size_scavenge);
8250
8251 inline bool DigestPretenuringFeedback(bool maximum_size_scavenge);
8252
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008253 inline ElementsKind GetElementsKind();
8254 inline void SetElementsKind(ElementsKind kind);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008255
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008256 inline bool CanInlineCall();
8257 inline void SetDoNotInlineCall();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008258
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008259 inline bool SitePointsToLiteral();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008260
8261 static void DigestTransitionFeedback(Handle<AllocationSite> site,
8262 ElementsKind to_kind);
8263
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008264 DECLARE_PRINTER(AllocationSite)
8265 DECLARE_VERIFIER(AllocationSite)
8266
8267 DECLARE_CAST(AllocationSite)
8268 static inline AllocationSiteMode GetMode(
8269 ElementsKind boilerplate_elements_kind);
8270 static inline AllocationSiteMode GetMode(ElementsKind from, ElementsKind to);
8271 static inline bool CanTrack(InstanceType type);
8272
8273 static const int kTransitionInfoOffset = HeapObject::kHeaderSize;
8274 static const int kNestedSiteOffset = kTransitionInfoOffset + kPointerSize;
8275 static const int kPretenureDataOffset = kNestedSiteOffset + kPointerSize;
8276 static const int kPretenureCreateCountOffset =
8277 kPretenureDataOffset + kPointerSize;
8278 static const int kDependentCodeOffset =
8279 kPretenureCreateCountOffset + kPointerSize;
8280 static const int kWeakNextOffset = kDependentCodeOffset + kPointerSize;
8281 static const int kSize = kWeakNextOffset + kPointerSize;
8282
8283 // During mark compact we need to take special care for the dependent code
8284 // field.
8285 static const int kPointerFieldsBeginOffset = kTransitionInfoOffset;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008286 static const int kPointerFieldsEndOffset = kWeakNextOffset;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008287
8288 // For other visitors, use the fixed body descriptor below.
Ben Murdoch097c5b22016-05-18 11:27:45 +01008289 typedef FixedBodyDescriptor<HeapObject::kHeaderSize, kSize, kSize>
8290 BodyDescriptor;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008291
8292 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008293 inline bool PretenuringDecisionMade();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008294
8295 DISALLOW_IMPLICIT_CONSTRUCTORS(AllocationSite);
8296};
8297
8298
8299class AllocationMemento: public Struct {
8300 public:
8301 static const int kAllocationSiteOffset = HeapObject::kHeaderSize;
8302 static const int kSize = kAllocationSiteOffset + kPointerSize;
8303
8304 DECL_ACCESSORS(allocation_site, Object)
8305
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008306 inline bool IsValid();
8307 inline AllocationSite* GetAllocationSite();
Ben Murdoch097c5b22016-05-18 11:27:45 +01008308 inline Address GetAllocationSiteUnchecked();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008309
8310 DECLARE_PRINTER(AllocationMemento)
8311 DECLARE_VERIFIER(AllocationMemento)
8312
8313 DECLARE_CAST(AllocationMemento)
8314
8315 private:
8316 DISALLOW_IMPLICIT_CONSTRUCTORS(AllocationMemento);
8317};
8318
8319
8320// Representation of a slow alias as part of a sloppy arguments objects.
8321// For fast aliases (if HasSloppyArgumentsElements()):
Ben Murdoch3ef787d2012-04-12 10:51:47 +01008322// - the parameter map contains an index into the context
8323// - all attributes of the element have default values
8324// For slow aliases (if HasDictionaryArgumentsElements()):
8325// - the parameter map contains no fast alias mapping (i.e. the hole)
8326// - this struct (in the slow backing store) contains an index into the context
8327// - all attributes are available as part if the property details
8328class AliasedArgumentsEntry: public Struct {
8329 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008330 inline int aliased_context_slot() const;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01008331 inline void set_aliased_context_slot(int count);
8332
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008333 DECLARE_CAST(AliasedArgumentsEntry)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01008334
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008335 // Dispatched behavior.
8336 DECLARE_PRINTER(AliasedArgumentsEntry)
8337 DECLARE_VERIFIER(AliasedArgumentsEntry)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01008338
8339 static const int kAliasedContextSlot = HeapObject::kHeaderSize;
8340 static const int kSize = kAliasedContextSlot + kPointerSize;
8341
8342 private:
8343 DISALLOW_IMPLICIT_CONSTRUCTORS(AliasedArgumentsEntry);
8344};
8345
8346
Steve Blocka7e24c12009-10-30 11:49:00 +00008347enum AllowNullsFlag {ALLOW_NULLS, DISALLOW_NULLS};
8348enum RobustnessFlag {ROBUST_STRING_TRAVERSAL, FAST_STRING_TRAVERSAL};
8349
8350
8351class StringHasher {
8352 public:
Ben Murdochc7cc0282012-03-05 14:35:55 +00008353 explicit inline StringHasher(int length, uint32_t seed);
Steve Blocka7e24c12009-10-30 11:49:00 +00008354
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008355 template <typename schar>
8356 static inline uint32_t HashSequentialString(const schar* chars,
8357 int length,
8358 uint32_t seed);
Steve Blocka7e24c12009-10-30 11:49:00 +00008359
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008360 // Reads all the data, even for long strings and computes the utf16 length.
8361 static uint32_t ComputeUtf8Hash(Vector<const char> chars,
8362 uint32_t seed,
8363 int* utf16_length_out);
Steve Blocka7e24c12009-10-30 11:49:00 +00008364
Kristian Monsen80d68ea2010-09-08 11:05:35 +01008365 // Calculated hash value for a string consisting of 1 to
8366 // String::kMaxArrayIndexSize digits with no leading zeros (except "0").
8367 // value is represented decimal value.
Iain Merrick9ac36c92010-09-13 15:29:50 +01008368 static uint32_t MakeArrayIndexHash(uint32_t value, int length);
Kristian Monsen80d68ea2010-09-08 11:05:35 +01008369
Ben Murdochc7cc0282012-03-05 14:35:55 +00008370 // No string is allowed to have a hash of zero. That value is reserved
8371 // for internal properties. If the hash calculation yields zero then we
8372 // use 27 instead.
8373 static const int kZeroHash = 27;
8374
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008375 // Reusable parts of the hashing algorithm.
8376 INLINE(static uint32_t AddCharacterCore(uint32_t running_hash, uint16_t c));
8377 INLINE(static uint32_t GetHashCore(uint32_t running_hash));
Emily Bernierd0a1eb72015-03-24 16:35:39 -04008378 INLINE(static uint32_t ComputeRunningHash(uint32_t running_hash,
8379 const uc16* chars, int length));
8380 INLINE(static uint32_t ComputeRunningHashOneByte(uint32_t running_hash,
8381 const char* chars,
8382 int length));
Steve Blocka7e24c12009-10-30 11:49:00 +00008383
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008384 protected:
8385 // Returns the value to store in the hash field of a string with
8386 // the given length and contents.
8387 uint32_t GetHashField();
8388 // Returns true if the hash of this string can be computed without
8389 // looking at the contents.
8390 inline bool has_trivial_hash();
8391 // Adds a block of characters to the hash.
8392 template<typename Char>
8393 inline void AddCharacters(const Char* chars, int len);
8394
8395 private:
8396 // Add a character to the hash.
8397 inline void AddCharacter(uint16_t c);
8398 // Update index. Returns true if string is still an index.
8399 inline bool UpdateIndex(uint16_t c);
Steve Blocka7e24c12009-10-30 11:49:00 +00008400
8401 int length_;
8402 uint32_t raw_running_hash_;
8403 uint32_t array_index_;
8404 bool is_array_index_;
8405 bool is_first_char_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008406 DISALLOW_COPY_AND_ASSIGN(StringHasher);
Steve Blocka7e24c12009-10-30 11:49:00 +00008407};
8408
8409
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008410class IteratingStringHasher : public StringHasher {
8411 public:
8412 static inline uint32_t Hash(String* string, uint32_t seed);
8413 inline void VisitOneByteString(const uint8_t* chars, int length);
8414 inline void VisitTwoByteString(const uint16_t* chars, int length);
8415
8416 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008417 inline IteratingStringHasher(int len, uint32_t seed);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04008418 void VisitConsString(ConsString* cons_string);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008419 DISALLOW_COPY_AND_ASSIGN(IteratingStringHasher);
8420};
Steve Block44f0eee2011-05-26 01:26:41 +01008421
8422
Steve Blocka7e24c12009-10-30 11:49:00 +00008423// The characteristics of a string are stored in its map. Retrieving these
8424// few bits of information is moderately expensive, involving two memory
8425// loads where the second is dependent on the first. To improve efficiency
8426// the shape of the string is given its own class so that it can be retrieved
8427// once and used for several string operations. A StringShape is small enough
8428// to be passed by value and is immutable, but be aware that flattening a
8429// string can potentially alter its shape. Also be aware that a GC caused by
8430// something else can alter the shape of a string due to ConsString
8431// shortcutting. Keeping these restrictions in mind has proven to be error-
8432// prone and so we no longer put StringShapes in variables unless there is a
8433// concrete performance benefit at that particular point in the code.
8434class StringShape BASE_EMBEDDED {
8435 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008436 inline explicit StringShape(const String* s);
Steve Blocka7e24c12009-10-30 11:49:00 +00008437 inline explicit StringShape(Map* s);
8438 inline explicit StringShape(InstanceType t);
8439 inline bool IsSequential();
8440 inline bool IsExternal();
8441 inline bool IsCons();
Ben Murdoch69a99ed2011-11-30 16:03:39 +00008442 inline bool IsSliced();
8443 inline bool IsIndirect();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008444 inline bool IsExternalOneByte();
Steve Blocka7e24c12009-10-30 11:49:00 +00008445 inline bool IsExternalTwoByte();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008446 inline bool IsSequentialOneByte();
Steve Blocka7e24c12009-10-30 11:49:00 +00008447 inline bool IsSequentialTwoByte();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008448 inline bool IsInternalized();
Steve Blocka7e24c12009-10-30 11:49:00 +00008449 inline StringRepresentationTag representation_tag();
Ben Murdoch69a99ed2011-11-30 16:03:39 +00008450 inline uint32_t encoding_tag();
Steve Blocka7e24c12009-10-30 11:49:00 +00008451 inline uint32_t full_representation_tag();
8452 inline uint32_t size_tag();
8453#ifdef DEBUG
8454 inline uint32_t type() { return type_; }
8455 inline void invalidate() { valid_ = false; }
8456 inline bool valid() { return valid_; }
8457#else
8458 inline void invalidate() { }
8459#endif
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00008460
Steve Blocka7e24c12009-10-30 11:49:00 +00008461 private:
8462 uint32_t type_;
8463#ifdef DEBUG
8464 inline void set_valid() { valid_ = true; }
8465 bool valid_;
8466#else
8467 inline void set_valid() { }
8468#endif
8469};
8470
8471
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008472// The Name abstract class captures anything that can be used as a property
8473// name, i.e., strings and symbols. All names store a hash value.
8474class Name: public HeapObject {
8475 public:
8476 // Get and set the hash field of the name.
8477 inline uint32_t hash_field();
8478 inline void set_hash_field(uint32_t value);
8479
8480 // Tells whether the hash code has been computed.
8481 inline bool HasHashCode();
8482
8483 // Returns a hash value used for the property table
8484 inline uint32_t Hash();
8485
8486 // Equality operations.
8487 inline bool Equals(Name* other);
8488 inline static bool Equals(Handle<Name> one, Handle<Name> two);
8489
8490 // Conversion.
8491 inline bool AsArrayIndex(uint32_t* index);
8492
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008493 // If the name is private, it can only name own properties.
8494 inline bool IsPrivate();
8495
Ben Murdoch097c5b22016-05-18 11:27:45 +01008496 inline bool IsUniqueName() const;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008497
8498 // Return a string version of this name that is converted according to the
8499 // rules described in ES6 section 9.2.11.
8500 MUST_USE_RESULT static MaybeHandle<String> ToFunctionName(Handle<Name> name);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008501
8502 DECLARE_CAST(Name)
8503
8504 DECLARE_PRINTER(Name)
Emily Bernierd0a1eb72015-03-24 16:35:39 -04008505#if TRACE_MAPS
8506 void NameShortPrint();
8507 int NameShortPrint(Vector<char> str);
8508#endif
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008509
8510 // Layout description.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04008511 static const int kHashFieldSlot = HeapObject::kHeaderSize;
8512#if V8_TARGET_LITTLE_ENDIAN || !V8_HOST_ARCH_64_BIT
8513 static const int kHashFieldOffset = kHashFieldSlot;
8514#else
8515 static const int kHashFieldOffset = kHashFieldSlot + kIntSize;
8516#endif
8517 static const int kSize = kHashFieldSlot + kPointerSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008518
8519 // Mask constant for checking if a name has a computed hash code
8520 // and if it is a string that is an array index. The least significant bit
8521 // indicates whether a hash code has been computed. If the hash code has
8522 // been computed the 2nd bit tells whether the string can be used as an
8523 // array index.
8524 static const int kHashNotComputedMask = 1;
8525 static const int kIsNotArrayIndexMask = 1 << 1;
8526 static const int kNofHashBitFields = 2;
8527
8528 // Shift constant retrieving hash code from hash field.
8529 static const int kHashShift = kNofHashBitFields;
8530
8531 // Only these bits are relevant in the hash, since the top two are shifted
8532 // out.
8533 static const uint32_t kHashBitMask = 0xffffffffu >> kHashShift;
8534
8535 // Array index strings this short can keep their index in the hash field.
8536 static const int kMaxCachedArrayIndexLength = 7;
8537
8538 // For strings which are array indexes the hash value has the string length
8539 // mixed into the hash, mainly to avoid a hash value of zero which would be
8540 // the case for the string '0'. 24 bits are used for the array index value.
8541 static const int kArrayIndexValueBits = 24;
8542 static const int kArrayIndexLengthBits =
8543 kBitsPerInt - kArrayIndexValueBits - kNofHashBitFields;
8544
8545 STATIC_ASSERT((kArrayIndexLengthBits > 0));
8546
8547 class ArrayIndexValueBits : public BitField<unsigned int, kNofHashBitFields,
8548 kArrayIndexValueBits> {}; // NOLINT
8549 class ArrayIndexLengthBits : public BitField<unsigned int,
8550 kNofHashBitFields + kArrayIndexValueBits,
8551 kArrayIndexLengthBits> {}; // NOLINT
8552
8553 // Check that kMaxCachedArrayIndexLength + 1 is a power of two so we
8554 // could use a mask to test if the length of string is less than or equal to
8555 // kMaxCachedArrayIndexLength.
8556 STATIC_ASSERT(IS_POWER_OF_TWO(kMaxCachedArrayIndexLength + 1));
8557
8558 static const unsigned int kContainsCachedArrayIndexMask =
8559 (~static_cast<unsigned>(kMaxCachedArrayIndexLength)
8560 << ArrayIndexLengthBits::kShift) |
8561 kIsNotArrayIndexMask;
8562
8563 // Value of empty hash field indicating that the hash is not computed.
8564 static const int kEmptyHashField =
8565 kIsNotArrayIndexMask | kHashNotComputedMask;
8566
8567 protected:
8568 static inline bool IsHashFieldComputed(uint32_t field);
8569
8570 private:
8571 DISALLOW_IMPLICIT_CONSTRUCTORS(Name);
8572};
8573
8574
8575// ES6 symbols.
8576class Symbol: public Name {
8577 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008578 // [name]: The print name of a symbol, or undefined if none.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008579 DECL_ACCESSORS(name, Object)
8580
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008581 DECL_INT_ACCESSORS(flags)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008582
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008583 // [is_private]: Whether this is a private symbol. Private symbols can only
8584 // be used to designate own properties of objects.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008585 DECL_BOOLEAN_ACCESSORS(is_private)
8586
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008587 // [is_well_known_symbol]: Whether this is a spec-defined well-known symbol,
8588 // or not. Well-known symbols do not throw when an access check fails during
8589 // a load.
8590 DECL_BOOLEAN_ACCESSORS(is_well_known_symbol)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008591
8592 DECLARE_CAST(Symbol)
8593
8594 // Dispatched behavior.
8595 DECLARE_PRINTER(Symbol)
8596 DECLARE_VERIFIER(Symbol)
8597
8598 // Layout description.
8599 static const int kNameOffset = Name::kSize;
8600 static const int kFlagsOffset = kNameOffset + kPointerSize;
8601 static const int kSize = kFlagsOffset + kPointerSize;
8602
8603 typedef FixedBodyDescriptor<kNameOffset, kFlagsOffset, kSize> BodyDescriptor;
8604
Emily Bernierd0a1eb72015-03-24 16:35:39 -04008605 void SymbolShortPrint(std::ostream& os);
8606
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008607 private:
8608 static const int kPrivateBit = 0;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008609 static const int kWellKnownSymbolBit = 1;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008610
Emily Bernierd0a1eb72015-03-24 16:35:39 -04008611 const char* PrivateSymbolToName() const;
8612
8613#if TRACE_MAPS
8614 friend class Name; // For PrivateSymbolToName.
8615#endif
8616
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008617 DISALLOW_IMPLICIT_CONSTRUCTORS(Symbol);
8618};
8619
8620
8621class ConsString;
8622
Steve Blocka7e24c12009-10-30 11:49:00 +00008623// The String abstract class captures JavaScript string values:
8624//
8625// Ecma-262:
8626// 4.3.16 String Value
8627// A string value is a member of the type String and is a finite
8628// ordered sequence of zero or more 16-bit unsigned integer values.
8629//
8630// All string values have a length field.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008631class String: public Name {
Steve Blocka7e24c12009-10-30 11:49:00 +00008632 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008633 enum Encoding { ONE_BYTE_ENCODING, TWO_BYTE_ENCODING };
8634
8635 // Array index strings this short can keep their index in the hash field.
8636 static const int kMaxCachedArrayIndexLength = 7;
8637
8638 // For strings which are array indexes the hash value has the string length
8639 // mixed into the hash, mainly to avoid a hash value of zero which would be
8640 // the case for the string '0'. 24 bits are used for the array index value.
8641 static const int kArrayIndexValueBits = 24;
8642 static const int kArrayIndexLengthBits =
8643 kBitsPerInt - kArrayIndexValueBits - kNofHashBitFields;
8644
8645 STATIC_ASSERT((kArrayIndexLengthBits > 0));
8646
8647 class ArrayIndexValueBits : public BitField<unsigned int, kNofHashBitFields,
8648 kArrayIndexValueBits> {}; // NOLINT
8649 class ArrayIndexLengthBits : public BitField<unsigned int,
8650 kNofHashBitFields + kArrayIndexValueBits,
8651 kArrayIndexLengthBits> {}; // NOLINT
8652
8653 // Check that kMaxCachedArrayIndexLength + 1 is a power of two so we
8654 // could use a mask to test if the length of string is less than or equal to
8655 // kMaxCachedArrayIndexLength.
8656 STATIC_ASSERT(IS_POWER_OF_TWO(kMaxCachedArrayIndexLength + 1));
8657
8658 static const unsigned int kContainsCachedArrayIndexMask =
8659 (~static_cast<unsigned>(kMaxCachedArrayIndexLength)
8660 << ArrayIndexLengthBits::kShift) |
8661 kIsNotArrayIndexMask;
8662
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008663 class SubStringRange {
8664 public:
8665 explicit inline SubStringRange(String* string, int first = 0,
8666 int length = -1);
8667 class iterator;
8668 inline iterator begin();
8669 inline iterator end();
8670
8671 private:
8672 String* string_;
8673 int first_;
8674 int length_;
8675 };
8676
Ben Murdoch69a99ed2011-11-30 16:03:39 +00008677 // Representation of the flat content of a String.
8678 // A non-flat string doesn't have flat content.
8679 // A flat string has content that's encoded as a sequence of either
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008680 // one-byte chars or two-byte UC16.
Ben Murdoch69a99ed2011-11-30 16:03:39 +00008681 // Returned by String::GetFlatContent().
8682 class FlatContent {
8683 public:
8684 // Returns true if the string is flat and this structure contains content.
Ben Murdochc5610432016-08-08 18:44:38 +01008685 bool IsFlat() const { return state_ != NON_FLAT; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008686 // Returns true if the structure contains one-byte content.
Ben Murdochc5610432016-08-08 18:44:38 +01008687 bool IsOneByte() const { return state_ == ONE_BYTE; }
Ben Murdoch69a99ed2011-11-30 16:03:39 +00008688 // Returns true if the structure contains two-byte content.
Ben Murdochc5610432016-08-08 18:44:38 +01008689 bool IsTwoByte() const { return state_ == TWO_BYTE; }
Ben Murdoch69a99ed2011-11-30 16:03:39 +00008690
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008691 // Return the one byte content of the string. Only use if IsOneByte()
8692 // returns true.
Ben Murdochc5610432016-08-08 18:44:38 +01008693 Vector<const uint8_t> ToOneByteVector() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008694 DCHECK_EQ(ONE_BYTE, state_);
8695 return Vector<const uint8_t>(onebyte_start, length_);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00008696 }
8697 // Return the two-byte content of the string. Only use if IsTwoByte()
8698 // returns true.
Ben Murdochc5610432016-08-08 18:44:38 +01008699 Vector<const uc16> ToUC16Vector() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008700 DCHECK_EQ(TWO_BYTE, state_);
8701 return Vector<const uc16>(twobyte_start, length_);
8702 }
8703
Ben Murdochc5610432016-08-08 18:44:38 +01008704 uc16 Get(int i) const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008705 DCHECK(i < length_);
8706 DCHECK(state_ != NON_FLAT);
8707 if (state_ == ONE_BYTE) return onebyte_start[i];
8708 return twobyte_start[i];
Ben Murdoch69a99ed2011-11-30 16:03:39 +00008709 }
8710
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008711 bool UsesSameString(const FlatContent& other) const {
8712 return onebyte_start == other.onebyte_start;
8713 }
8714
Ben Murdoch69a99ed2011-11-30 16:03:39 +00008715 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008716 enum State { NON_FLAT, ONE_BYTE, TWO_BYTE };
Ben Murdoch69a99ed2011-11-30 16:03:39 +00008717
8718 // Constructors only used by String::GetFlatContent().
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008719 explicit FlatContent(const uint8_t* start, int length)
8720 : onebyte_start(start), length_(length), state_(ONE_BYTE) {}
8721 explicit FlatContent(const uc16* start, int length)
8722 : twobyte_start(start), length_(length), state_(TWO_BYTE) { }
8723 FlatContent() : onebyte_start(NULL), length_(0), state_(NON_FLAT) { }
Ben Murdoch69a99ed2011-11-30 16:03:39 +00008724
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008725 union {
8726 const uint8_t* onebyte_start;
8727 const uc16* twobyte_start;
8728 };
8729 int length_;
Ben Murdoch69a99ed2011-11-30 16:03:39 +00008730 State state_;
8731
8732 friend class String;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008733 friend class IterableSubString;
Ben Murdoch69a99ed2011-11-30 16:03:39 +00008734 };
8735
Emily Bernierd0a1eb72015-03-24 16:35:39 -04008736 template <typename Char>
8737 INLINE(Vector<const Char> GetCharVector());
8738
Steve Blocka7e24c12009-10-30 11:49:00 +00008739 // Get and set the length of the string.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008740 inline int length() const;
Steve Blocka7e24c12009-10-30 11:49:00 +00008741 inline void set_length(int value);
8742
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008743 // Get and set the length of the string using acquire loads and release
8744 // stores.
8745 inline int synchronized_length() const;
8746 inline void synchronized_set_length(int value);
Steve Blocka7e24c12009-10-30 11:49:00 +00008747
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008748 // Returns whether this string has only one-byte chars, i.e. all of them can
8749 // be one-byte encoded. This might be the case even if the string is
Ben Murdoch69a99ed2011-11-30 16:03:39 +00008750 // two-byte. Such strings may appear when the embedder prefers
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008751 // two-byte external representations even for one-byte data.
8752 inline bool IsOneByteRepresentation() const;
8753 inline bool IsTwoByteRepresentation() const;
Steve Blocka7e24c12009-10-30 11:49:00 +00008754
Ben Murdoch69a99ed2011-11-30 16:03:39 +00008755 // Cons and slices have an encoding flag that may not represent the actual
8756 // encoding of the underlying string. This is taken into account here.
8757 // Requires: this->IsFlat()
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008758 inline bool IsOneByteRepresentationUnderneath();
Ben Murdoch69a99ed2011-11-30 16:03:39 +00008759 inline bool IsTwoByteRepresentationUnderneath();
8760
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01008761 // NOTE: this should be considered only a hint. False negatives are
8762 // possible.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008763 inline bool HasOnlyOneByteChars();
Steve Block6ded16b2010-05-10 14:33:55 +01008764
Steve Blocka7e24c12009-10-30 11:49:00 +00008765 // Get and set individual two byte chars in the string.
8766 inline void Set(int index, uint16_t value);
8767 // Get individual two byte char in the string. Repeated calls
8768 // to this method are not efficient unless the string is flat.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008769 INLINE(uint16_t Get(int index));
Steve Blocka7e24c12009-10-30 11:49:00 +00008770
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008771 // ES6 section 7.1.3.1 ToNumber Applied to the String Type
8772 static Handle<Object> ToNumber(Handle<String> subject);
8773
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008774 // Flattens the string. Checks first inline to see if it is
Leon Clarkef7060e22010-06-03 12:02:55 +01008775 // necessary. Does nothing if the string is not a cons string.
8776 // Flattening allocates a sequential string with the same data as
8777 // the given string and mutates the cons string to a degenerate
8778 // form, where the first component is the new sequential string and
8779 // the second component is the empty string. If allocation fails,
8780 // this function returns a failure. If flattening succeeds, this
8781 // function returns the sequential string that is now the first
8782 // component of the cons string.
8783 //
8784 // Degenerate cons strings are handled specially by the garbage
8785 // collector (see IsShortcutCandidate).
Steve Blocka7e24c12009-10-30 11:49:00 +00008786
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008787 static inline Handle<String> Flatten(Handle<String> string,
8788 PretenureFlag pretenure = NOT_TENURED);
Leon Clarkef7060e22010-06-03 12:02:55 +01008789
Ben Murdoch69a99ed2011-11-30 16:03:39 +00008790 // Tries to return the content of a flat string as a structure holding either
8791 // a flat vector of char or of uc16.
8792 // If the string isn't flat, and therefore doesn't have flat content, the
8793 // returned structure will report so, and can't provide a vector of either
8794 // kind.
8795 FlatContent GetFlatContent();
8796
8797 // Returns the parent of a sliced string or first part of a flat cons string.
8798 // Requires: StringShape(this).IsIndirect() && this->IsFlat()
8799 inline String* GetUnderlying();
Steve Blocka7e24c12009-10-30 11:49:00 +00008800
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008801 // String relational comparison, implemented according to ES6 section 7.2.11
8802 // Abstract Relational Comparison (step 5): The comparison of Strings uses a
8803 // simple lexicographic ordering on sequences of code unit values. There is no
8804 // attempt to use the more complex, semantically oriented definitions of
8805 // character or string equality and collating order defined in the Unicode
8806 // specification. Therefore String values that are canonically equal according
8807 // to the Unicode standard could test as unequal. In effect this algorithm
8808 // assumes that both Strings are already in normalized form. Also, note that
8809 // for strings containing supplementary characters, lexicographic ordering on
8810 // sequences of UTF-16 code unit values differs from that on sequences of code
8811 // point values.
8812 MUST_USE_RESULT static ComparisonResult Compare(Handle<String> x,
8813 Handle<String> y);
Steve Blocka7e24c12009-10-30 11:49:00 +00008814
Steve Blocka7e24c12009-10-30 11:49:00 +00008815 // String equality operations.
8816 inline bool Equals(String* other);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008817 inline static bool Equals(Handle<String> one, Handle<String> two);
8818 bool IsUtf8EqualTo(Vector<const char> str, bool allow_prefix_match = false);
8819 bool IsOneByteEqualTo(Vector<const uint8_t> str);
Steve Block9fac8402011-05-12 15:51:54 +01008820 bool IsTwoByteEqualTo(Vector<const uc16> str);
Steve Blocka7e24c12009-10-30 11:49:00 +00008821
8822 // Return a UTF8 representation of the string. The string is null
8823 // terminated but may optionally contain nulls. Length is returned
8824 // in length_output if length_output is not a null pointer The string
8825 // should be nearly flat, otherwise the performance of this method may
8826 // be very slow (quadratic in the length). Setting robustness_flag to
8827 // ROBUST_STRING_TRAVERSAL invokes behaviour that is robust This means it
8828 // handles unexpected data without causing assert failures and it does not
8829 // do any heap allocations. This is useful when printing stack traces.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008830 base::SmartArrayPointer<char> ToCString(AllowNullsFlag allow_nulls,
8831 RobustnessFlag robustness_flag,
8832 int offset, int length,
8833 int* length_output = 0);
8834 base::SmartArrayPointer<char> ToCString(
Steve Blocka7e24c12009-10-30 11:49:00 +00008835 AllowNullsFlag allow_nulls = DISALLOW_NULLS,
8836 RobustnessFlag robustness_flag = FAST_STRING_TRAVERSAL,
8837 int* length_output = 0);
8838
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008839 bool ComputeArrayIndex(uint32_t* index);
Steve Blocka7e24c12009-10-30 11:49:00 +00008840
8841 // Externalization.
8842 bool MakeExternal(v8::String::ExternalStringResource* resource);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008843 bool MakeExternal(v8::String::ExternalOneByteStringResource* resource);
Steve Blocka7e24c12009-10-30 11:49:00 +00008844
8845 // Conversion.
8846 inline bool AsArrayIndex(uint32_t* index);
8847
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008848 DECLARE_CAST(String)
Steve Blocka7e24c12009-10-30 11:49:00 +00008849
8850 void PrintOn(FILE* out);
8851
8852 // For use during stack traces. Performs rudimentary sanity check.
8853 bool LooksValid();
8854
8855 // Dispatched behavior.
8856 void StringShortPrint(StringStream* accumulator);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04008857 void PrintUC16(std::ostream& os, int start = 0, int end = -1); // NOLINT
8858#if defined(DEBUG) || defined(OBJECT_PRINT)
Ben Murdoch69a99ed2011-11-30 16:03:39 +00008859 char* ToAsciiArray();
Ben Murdochb0fe1622011-05-05 13:52:32 +01008860#endif
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008861 DECLARE_PRINTER(String)
8862 DECLARE_VERIFIER(String)
8863
Steve Blocka7e24c12009-10-30 11:49:00 +00008864 inline bool IsFlat();
8865
8866 // Layout description.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008867 static const int kLengthOffset = Name::kSize;
8868 static const int kSize = kLengthOffset + kPointerSize;
Steve Blocka7e24c12009-10-30 11:49:00 +00008869
Steve Blockd0582a62009-12-15 09:54:21 +00008870 // Maximum number of characters to consider when trying to convert a string
8871 // value into an array index.
Steve Blocka7e24c12009-10-30 11:49:00 +00008872 static const int kMaxArrayIndexSize = 10;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008873 STATIC_ASSERT(kMaxArrayIndexSize < (1 << kArrayIndexLengthBits));
Steve Blocka7e24c12009-10-30 11:49:00 +00008874
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008875 // Max char codes.
8876 static const int32_t kMaxOneByteCharCode = unibrow::Latin1::kMaxChar;
8877 static const uint32_t kMaxOneByteCharCodeU = unibrow::Latin1::kMaxChar;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01008878 static const int kMaxUtf16CodeUnit = 0xffff;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008879 static const uint32_t kMaxUtf16CodeUnitU = kMaxUtf16CodeUnit;
Ben Murdoch097c5b22016-05-18 11:27:45 +01008880 static const uc32 kMaxCodePoint = 0x10ffff;
Steve Blockd0582a62009-12-15 09:54:21 +00008881
8882 // Maximal string length.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008883 static const int kMaxLength = (1 << 28) - 16;
Steve Blockd0582a62009-12-15 09:54:21 +00008884
8885 // Max length for computing hash. For strings longer than this limit the
8886 // string length is used as the hash value.
8887 static const int kMaxHashCalcLength = 16383;
Steve Blocka7e24c12009-10-30 11:49:00 +00008888
8889 // Limit for truncation in short printing.
8890 static const int kMaxShortPrintLength = 1024;
8891
8892 // Support for regular expressions.
Steve Blocka7e24c12009-10-30 11:49:00 +00008893 const uc16* GetTwoByteData(unsigned start);
8894
Steve Blocka7e24c12009-10-30 11:49:00 +00008895 // Helper function for flattening strings.
8896 template <typename sinkchar>
8897 static void WriteToFlat(String* source,
8898 sinkchar* sink,
8899 int from,
8900 int to);
8901
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008902 // The return value may point to the first aligned word containing the first
8903 // non-one-byte character, rather than directly to the non-one-byte character.
8904 // If the return value is >= the passed length, the entire string was
8905 // one-byte.
8906 static inline int NonAsciiStart(const char* chars, int length) {
8907 const char* start = chars;
Steve Block9fac8402011-05-12 15:51:54 +01008908 const char* limit = chars + length;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008909
8910 if (length >= kIntptrSize) {
8911 // Check unaligned bytes.
8912 while (!IsAligned(reinterpret_cast<intptr_t>(chars), sizeof(uintptr_t))) {
8913 if (static_cast<uint8_t>(*chars) > unibrow::Utf8::kMaxOneByteChar) {
8914 return static_cast<int>(chars - start);
8915 }
8916 ++chars;
Steve Block9fac8402011-05-12 15:51:54 +01008917 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008918 // Check aligned words.
8919 DCHECK(unibrow::Utf8::kMaxOneByteChar == 0x7F);
8920 const uintptr_t non_one_byte_mask = kUintptrAllBitsSet / 0xFF * 0x80;
8921 while (chars + sizeof(uintptr_t) <= limit) {
8922 if (*reinterpret_cast<const uintptr_t*>(chars) & non_one_byte_mask) {
8923 return static_cast<int>(chars - start);
8924 }
8925 chars += sizeof(uintptr_t);
8926 }
Steve Block9fac8402011-05-12 15:51:54 +01008927 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008928 // Check remaining unaligned bytes.
Steve Block9fac8402011-05-12 15:51:54 +01008929 while (chars < limit) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008930 if (static_cast<uint8_t>(*chars) > unibrow::Utf8::kMaxOneByteChar) {
8931 return static_cast<int>(chars - start);
8932 }
Steve Block9fac8402011-05-12 15:51:54 +01008933 ++chars;
8934 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008935
8936 return static_cast<int>(chars - start);
Steve Block9fac8402011-05-12 15:51:54 +01008937 }
8938
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008939 static inline bool IsAscii(const char* chars, int length) {
8940 return NonAsciiStart(chars, length) >= length;
8941 }
8942
8943 static inline bool IsAscii(const uint8_t* chars, int length) {
8944 return
8945 NonAsciiStart(reinterpret_cast<const char*>(chars), length) >= length;
8946 }
8947
8948 static inline int NonOneByteStart(const uc16* chars, int length) {
Steve Block9fac8402011-05-12 15:51:54 +01008949 const uc16* limit = chars + length;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008950 const uc16* start = chars;
Steve Block9fac8402011-05-12 15:51:54 +01008951 while (chars < limit) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008952 if (*chars > kMaxOneByteCharCodeU) return static_cast<int>(chars - start);
Steve Block9fac8402011-05-12 15:51:54 +01008953 ++chars;
8954 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008955 return static_cast<int>(chars - start);
Steve Block9fac8402011-05-12 15:51:54 +01008956 }
8957
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008958 static inline bool IsOneByte(const uc16* chars, int length) {
8959 return NonOneByteStart(chars, length) >= length;
8960 }
Steve Blocka7e24c12009-10-30 11:49:00 +00008961
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008962 template<class Visitor>
8963 static inline ConsString* VisitFlat(Visitor* visitor,
8964 String* string,
8965 int offset = 0);
8966
8967 static Handle<FixedArray> CalculateLineEnds(Handle<String> string,
8968 bool include_ending_line);
8969
8970 // Use the hash field to forward to the canonical internalized string
8971 // when deserializing an internalized string.
8972 inline void SetForwardedInternalizedString(String* string);
8973 inline String* GetForwardedInternalizedString();
Steve Blocka7e24c12009-10-30 11:49:00 +00008974
8975 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008976 friend class Name;
8977 friend class StringTableInsertionKey;
Leon Clarkef7060e22010-06-03 12:02:55 +01008978
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008979 static Handle<String> SlowFlatten(Handle<ConsString> cons,
8980 PretenureFlag tenure);
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01008981
Steve Blocka7e24c12009-10-30 11:49:00 +00008982 // Slow case of String::Equals. This implementation works on any strings
8983 // but it is most efficient on strings that are almost flat.
8984 bool SlowEquals(String* other);
8985
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008986 static bool SlowEquals(Handle<String> one, Handle<String> two);
8987
Steve Blocka7e24c12009-10-30 11:49:00 +00008988 // Slow case of AsArrayIndex.
8989 bool SlowAsArrayIndex(uint32_t* index);
8990
8991 // Compute and set the hash code.
8992 uint32_t ComputeAndSetHash();
8993
8994 DISALLOW_IMPLICIT_CONSTRUCTORS(String);
8995};
8996
8997
8998// The SeqString abstract class captures sequential string values.
8999class SeqString: public String {
9000 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009001 DECLARE_CAST(SeqString)
Steve Blocka7e24c12009-10-30 11:49:00 +00009002
Ben Murdoch3ef787d2012-04-12 10:51:47 +01009003 // Layout description.
9004 static const int kHeaderSize = String::kSize;
9005
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009006 // Truncate the string in-place if possible and return the result.
9007 // In case of new_length == 0, the empty string is returned without
9008 // truncating the original string.
9009 MUST_USE_RESULT static Handle<String> Truncate(Handle<SeqString> string,
9010 int new_length);
Steve Blocka7e24c12009-10-30 11:49:00 +00009011 private:
9012 DISALLOW_IMPLICIT_CONSTRUCTORS(SeqString);
9013};
9014
9015
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009016// The OneByteString class captures sequential one-byte string objects.
9017// Each character in the OneByteString is an one-byte character.
9018class SeqOneByteString: public SeqString {
Steve Blocka7e24c12009-10-30 11:49:00 +00009019 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009020 static const bool kHasOneByteEncoding = true;
Leon Clarkeac952652010-07-15 11:15:24 +01009021
Steve Blocka7e24c12009-10-30 11:49:00 +00009022 // Dispatched behavior.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009023 inline uint16_t SeqOneByteStringGet(int index);
9024 inline void SeqOneByteStringSet(int index, uint16_t value);
Steve Blocka7e24c12009-10-30 11:49:00 +00009025
9026 // Get the address of the characters in this string.
9027 inline Address GetCharsAddress();
9028
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009029 inline uint8_t* GetChars();
Steve Blocka7e24c12009-10-30 11:49:00 +00009030
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009031 DECLARE_CAST(SeqOneByteString)
Steve Blocka7e24c12009-10-30 11:49:00 +00009032
9033 // Garbage collection support. This method is called by the
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009034 // garbage collector to compute the actual size of an OneByteString
Steve Blocka7e24c12009-10-30 11:49:00 +00009035 // instance.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009036 inline int SeqOneByteStringSize(InstanceType instance_type);
Steve Blocka7e24c12009-10-30 11:49:00 +00009037
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009038 // Computes the size for an OneByteString instance of a given length.
Steve Blocka7e24c12009-10-30 11:49:00 +00009039 static int SizeFor(int length) {
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01009040 return OBJECT_POINTER_ALIGN(kHeaderSize + length * kCharSize);
Steve Blocka7e24c12009-10-30 11:49:00 +00009041 }
9042
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009043 // Maximal memory usage for a single sequential one-byte string.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01009044 static const int kMaxSize = 512 * MB - 1;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009045 STATIC_ASSERT((kMaxSize - kHeaderSize) >= String::kMaxLength);
Steve Blocka7e24c12009-10-30 11:49:00 +00009046
9047 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009048 DISALLOW_IMPLICIT_CONSTRUCTORS(SeqOneByteString);
Steve Blocka7e24c12009-10-30 11:49:00 +00009049};
9050
9051
9052// The TwoByteString class captures sequential unicode string objects.
9053// Each character in the TwoByteString is a two-byte uint16_t.
9054class SeqTwoByteString: public SeqString {
9055 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009056 static const bool kHasOneByteEncoding = false;
Leon Clarkeac952652010-07-15 11:15:24 +01009057
Steve Blocka7e24c12009-10-30 11:49:00 +00009058 // Dispatched behavior.
9059 inline uint16_t SeqTwoByteStringGet(int index);
9060 inline void SeqTwoByteStringSet(int index, uint16_t value);
9061
9062 // Get the address of the characters in this string.
9063 inline Address GetCharsAddress();
9064
9065 inline uc16* GetChars();
9066
9067 // For regexp code.
9068 const uint16_t* SeqTwoByteStringGetData(unsigned start);
9069
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009070 DECLARE_CAST(SeqTwoByteString)
Steve Blocka7e24c12009-10-30 11:49:00 +00009071
9072 // Garbage collection support. This method is called by the
9073 // garbage collector to compute the actual size of a TwoByteString
9074 // instance.
9075 inline int SeqTwoByteStringSize(InstanceType instance_type);
9076
9077 // Computes the size for a TwoByteString instance of a given length.
9078 static int SizeFor(int length) {
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01009079 return OBJECT_POINTER_ALIGN(kHeaderSize + length * kShortSize);
Steve Blocka7e24c12009-10-30 11:49:00 +00009080 }
9081
Leon Clarkee46be812010-01-19 14:06:41 +00009082 // Maximal memory usage for a single sequential two-byte string.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01009083 static const int kMaxSize = 512 * MB - 1;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009084 STATIC_ASSERT(static_cast<int>((kMaxSize - kHeaderSize)/sizeof(uint16_t)) >=
9085 String::kMaxLength);
Steve Blocka7e24c12009-10-30 11:49:00 +00009086
9087 private:
9088 DISALLOW_IMPLICIT_CONSTRUCTORS(SeqTwoByteString);
9089};
9090
9091
9092// The ConsString class describes string values built by using the
9093// addition operator on strings. A ConsString is a pair where the
9094// first and second components are pointers to other string values.
9095// One or both components of a ConsString can be pointers to other
9096// ConsStrings, creating a binary tree of ConsStrings where the leaves
9097// are non-ConsString string values. The string value represented by
9098// a ConsString can be obtained by concatenating the leaf string
9099// values in a left-to-right depth-first traversal of the tree.
9100class ConsString: public String {
9101 public:
9102 // First string of the cons cell.
9103 inline String* first();
9104 // Doesn't check that the result is a string, even in debug mode. This is
9105 // useful during GC where the mark bits confuse the checks.
9106 inline Object* unchecked_first();
9107 inline void set_first(String* first,
9108 WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
9109
9110 // Second string of the cons cell.
9111 inline String* second();
9112 // Doesn't check that the result is a string, even in debug mode. This is
9113 // useful during GC where the mark bits confuse the checks.
9114 inline Object* unchecked_second();
9115 inline void set_second(String* second,
9116 WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
9117
9118 // Dispatched behavior.
9119 uint16_t ConsStringGet(int index);
9120
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009121 DECLARE_CAST(ConsString)
Steve Blocka7e24c12009-10-30 11:49:00 +00009122
Steve Blocka7e24c12009-10-30 11:49:00 +00009123 // Layout description.
9124 static const int kFirstOffset = POINTER_SIZE_ALIGN(String::kSize);
9125 static const int kSecondOffset = kFirstOffset + kPointerSize;
9126 static const int kSize = kSecondOffset + kPointerSize;
9127
Steve Blocka7e24c12009-10-30 11:49:00 +00009128 // Minimum length for a cons string.
9129 static const int kMinLength = 13;
9130
Iain Merrick75681382010-08-19 15:07:18 +01009131 typedef FixedBodyDescriptor<kFirstOffset, kSecondOffset + kPointerSize, kSize>
9132 BodyDescriptor;
9133
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009134 DECLARE_VERIFIER(ConsString)
Ben Murdoch69a99ed2011-11-30 16:03:39 +00009135
Steve Blocka7e24c12009-10-30 11:49:00 +00009136 private:
9137 DISALLOW_IMPLICIT_CONSTRUCTORS(ConsString);
9138};
9139
9140
Ben Murdoch69a99ed2011-11-30 16:03:39 +00009141// The Sliced String class describes strings that are substrings of another
9142// sequential string. The motivation is to save time and memory when creating
9143// a substring. A Sliced String is described as a pointer to the parent,
9144// the offset from the start of the parent string and the length. Using
9145// a Sliced String therefore requires unpacking of the parent string and
9146// adding the offset to the start address. A substring of a Sliced String
9147// are not nested since the double indirection is simplified when creating
9148// such a substring.
9149// Currently missing features are:
9150// - handling externalized parent strings
9151// - external strings as parent
9152// - truncating sliced string to enable otherwise unneeded parent to be GC'ed.
9153class SlicedString: public String {
9154 public:
Ben Murdoch69a99ed2011-11-30 16:03:39 +00009155 inline String* parent();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009156 inline void set_parent(String* parent,
9157 WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
9158 inline int offset() const;
Ben Murdoch69a99ed2011-11-30 16:03:39 +00009159 inline void set_offset(int offset);
9160
9161 // Dispatched behavior.
9162 uint16_t SlicedStringGet(int index);
9163
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009164 DECLARE_CAST(SlicedString)
Ben Murdoch69a99ed2011-11-30 16:03:39 +00009165
9166 // Layout description.
9167 static const int kParentOffset = POINTER_SIZE_ALIGN(String::kSize);
9168 static const int kOffsetOffset = kParentOffset + kPointerSize;
9169 static const int kSize = kOffsetOffset + kPointerSize;
9170
Ben Murdoch69a99ed2011-11-30 16:03:39 +00009171 // Minimum length for a sliced string.
9172 static const int kMinLength = 13;
9173
9174 typedef FixedBodyDescriptor<kParentOffset,
9175 kOffsetOffset + kPointerSize, kSize>
9176 BodyDescriptor;
9177
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009178 DECLARE_VERIFIER(SlicedString)
Ben Murdoch69a99ed2011-11-30 16:03:39 +00009179
9180 private:
9181 DISALLOW_IMPLICIT_CONSTRUCTORS(SlicedString);
9182};
9183
9184
Steve Blocka7e24c12009-10-30 11:49:00 +00009185// The ExternalString class describes string values that are backed by
9186// a string resource that lies outside the V8 heap. ExternalStrings
9187// consist of the length field common to all strings, a pointer to the
9188// external resource. It is important to ensure (externally) that the
9189// resource is not deallocated while the ExternalString is live in the
9190// V8 heap.
9191//
9192// The API expects that all ExternalStrings are created through the
9193// API. Therefore, ExternalStrings should not be used internally.
9194class ExternalString: public String {
9195 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009196 DECLARE_CAST(ExternalString)
Steve Blocka7e24c12009-10-30 11:49:00 +00009197
9198 // Layout description.
9199 static const int kResourceOffset = POINTER_SIZE_ALIGN(String::kSize);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01009200 static const int kShortSize = kResourceOffset + kPointerSize;
9201 static const int kResourceDataOffset = kResourceOffset + kPointerSize;
9202 static const int kSize = kResourceDataOffset + kPointerSize;
9203
9204 // Return whether external string is short (data pointer is not cached).
9205 inline bool is_short();
Steve Blocka7e24c12009-10-30 11:49:00 +00009206
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009207 STATIC_ASSERT(kResourceOffset == Internals::kStringResourceOffset);
Steve Blocka7e24c12009-10-30 11:49:00 +00009208
9209 private:
9210 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalString);
9211};
9212
9213
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009214// The ExternalOneByteString class is an external string backed by an
9215// one-byte string.
9216class ExternalOneByteString : public ExternalString {
Steve Blocka7e24c12009-10-30 11:49:00 +00009217 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009218 static const bool kHasOneByteEncoding = true;
Leon Clarkeac952652010-07-15 11:15:24 +01009219
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009220 typedef v8::String::ExternalOneByteStringResource Resource;
Steve Blocka7e24c12009-10-30 11:49:00 +00009221
9222 // The underlying resource.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01009223 inline const Resource* resource();
9224 inline void set_resource(const Resource* buffer);
9225
9226 // Update the pointer cache to the external character array.
9227 // The cached pointer is always valid, as the external character array does =
9228 // not move during lifetime. Deserialization is the only exception, after
9229 // which the pointer cache has to be refreshed.
9230 inline void update_data_cache();
9231
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009232 inline const uint8_t* GetChars();
Steve Blocka7e24c12009-10-30 11:49:00 +00009233
9234 // Dispatched behavior.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009235 inline uint16_t ExternalOneByteStringGet(int index);
Steve Blocka7e24c12009-10-30 11:49:00 +00009236
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009237 DECLARE_CAST(ExternalOneByteString)
Steve Blocka7e24c12009-10-30 11:49:00 +00009238
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009239 class BodyDescriptor;
Steve Blocka7e24c12009-10-30 11:49:00 +00009240
Steve Blocka7e24c12009-10-30 11:49:00 +00009241 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009242 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalOneByteString);
Steve Blocka7e24c12009-10-30 11:49:00 +00009243};
9244
9245
9246// The ExternalTwoByteString class is an external string backed by a UTF-16
9247// encoded string.
9248class ExternalTwoByteString: public ExternalString {
9249 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009250 static const bool kHasOneByteEncoding = false;
Leon Clarkeac952652010-07-15 11:15:24 +01009251
Steve Blocka7e24c12009-10-30 11:49:00 +00009252 typedef v8::String::ExternalStringResource Resource;
9253
9254 // The underlying string resource.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01009255 inline const Resource* resource();
9256 inline void set_resource(const Resource* buffer);
9257
9258 // Update the pointer cache to the external character array.
9259 // The cached pointer is always valid, as the external character array does =
9260 // not move during lifetime. Deserialization is the only exception, after
9261 // which the pointer cache has to be refreshed.
9262 inline void update_data_cache();
9263
9264 inline const uint16_t* GetChars();
Steve Blocka7e24c12009-10-30 11:49:00 +00009265
9266 // Dispatched behavior.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01009267 inline uint16_t ExternalTwoByteStringGet(int index);
Steve Blocka7e24c12009-10-30 11:49:00 +00009268
9269 // For regexp code.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01009270 inline const uint16_t* ExternalTwoByteStringGetData(unsigned start);
Steve Blocka7e24c12009-10-30 11:49:00 +00009271
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009272 DECLARE_CAST(ExternalTwoByteString)
Steve Blocka7e24c12009-10-30 11:49:00 +00009273
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009274 class BodyDescriptor;
Iain Merrick75681382010-08-19 15:07:18 +01009275
Steve Blocka7e24c12009-10-30 11:49:00 +00009276 private:
9277 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalTwoByteString);
9278};
9279
9280
9281// Utility superclass for stack-allocated objects that must be updated
9282// on gc. It provides two ways for the gc to update instances, either
9283// iterating or updating after gc.
9284class Relocatable BASE_EMBEDDED {
9285 public:
Steve Block44f0eee2011-05-26 01:26:41 +01009286 explicit inline Relocatable(Isolate* isolate);
9287 inline virtual ~Relocatable();
Steve Blocka7e24c12009-10-30 11:49:00 +00009288 virtual void IterateInstance(ObjectVisitor* v) { }
9289 virtual void PostGarbageCollection() { }
9290
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009291 static void PostGarbageCollectionProcessing(Isolate* isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00009292 static int ArchiveSpacePerThread();
Ben Murdoch257744e2011-11-30 15:57:28 +00009293 static char* ArchiveState(Isolate* isolate, char* to);
9294 static char* RestoreState(Isolate* isolate, char* from);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009295 static void Iterate(Isolate* isolate, ObjectVisitor* v);
Steve Blocka7e24c12009-10-30 11:49:00 +00009296 static void Iterate(ObjectVisitor* v, Relocatable* top);
9297 static char* Iterate(ObjectVisitor* v, char* t);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009298
Steve Blocka7e24c12009-10-30 11:49:00 +00009299 private:
Steve Block44f0eee2011-05-26 01:26:41 +01009300 Isolate* isolate_;
Steve Blocka7e24c12009-10-30 11:49:00 +00009301 Relocatable* prev_;
9302};
9303
9304
9305// A flat string reader provides random access to the contents of a
9306// string independent of the character width of the string. The handle
9307// must be valid as long as the reader is being used.
9308class FlatStringReader : public Relocatable {
9309 public:
Steve Block44f0eee2011-05-26 01:26:41 +01009310 FlatStringReader(Isolate* isolate, Handle<String> str);
9311 FlatStringReader(Isolate* isolate, Vector<const char> input);
Steve Blocka7e24c12009-10-30 11:49:00 +00009312 void PostGarbageCollection();
9313 inline uc32 Get(int index);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04009314 template <typename Char>
9315 inline Char Get(int index);
Steve Blocka7e24c12009-10-30 11:49:00 +00009316 int length() { return length_; }
9317 private:
9318 String** str_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009319 bool is_one_byte_;
Steve Blocka7e24c12009-10-30 11:49:00 +00009320 int length_;
9321 const void* start_;
9322};
9323
9324
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009325// This maintains an off-stack representation of the stack frames required
9326// to traverse a ConsString, allowing an entirely iterative and restartable
9327// traversal of the entire string
Emily Bernierd0a1eb72015-03-24 16:35:39 -04009328class ConsStringIterator {
Steve Blocka7e24c12009-10-30 11:49:00 +00009329 public:
Emily Bernierd0a1eb72015-03-24 16:35:39 -04009330 inline ConsStringIterator() {}
9331 inline explicit ConsStringIterator(ConsString* cons_string, int offset = 0) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009332 Reset(cons_string, offset);
9333 }
9334 inline void Reset(ConsString* cons_string, int offset = 0) {
9335 depth_ = 0;
9336 // Next will always return NULL.
9337 if (cons_string == NULL) return;
9338 Initialize(cons_string, offset);
9339 }
9340 // Returns NULL when complete.
9341 inline String* Next(int* offset_out) {
9342 *offset_out = 0;
9343 if (depth_ == 0) return NULL;
9344 return Continue(offset_out);
9345 }
9346
9347 private:
9348 static const int kStackSize = 32;
9349 // Use a mask instead of doing modulo operations for stack wrapping.
9350 static const int kDepthMask = kStackSize-1;
9351 STATIC_ASSERT(IS_POWER_OF_TWO(kStackSize));
9352 static inline int OffsetForDepth(int depth);
9353
9354 inline void PushLeft(ConsString* string);
9355 inline void PushRight(ConsString* string);
9356 inline void AdjustMaximumDepth();
9357 inline void Pop();
9358 inline bool StackBlown() { return maximum_depth_ - depth_ == kStackSize; }
9359 void Initialize(ConsString* cons_string, int offset);
9360 String* Continue(int* offset_out);
9361 String* NextLeaf(bool* blew_stack);
9362 String* Search(int* offset_out);
9363
9364 // Stack must always contain only frames for which right traversal
9365 // has not yet been performed.
9366 ConsString* frames_[kStackSize];
9367 ConsString* root_;
9368 int depth_;
9369 int maximum_depth_;
9370 int consumed_;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04009371 DISALLOW_COPY_AND_ASSIGN(ConsStringIterator);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009372};
9373
9374
9375class StringCharacterStream {
9376 public:
9377 inline StringCharacterStream(String* string,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009378 int offset = 0);
9379 inline uint16_t GetNext();
9380 inline bool HasMore();
9381 inline void Reset(String* string, int offset = 0);
9382 inline void VisitOneByteString(const uint8_t* chars, int length);
9383 inline void VisitTwoByteString(const uint16_t* chars, int length);
9384
9385 private:
Emily Bernierd0a1eb72015-03-24 16:35:39 -04009386 ConsStringIterator iter_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009387 bool is_one_byte_;
9388 union {
9389 const uint8_t* buffer8_;
9390 const uint16_t* buffer16_;
9391 };
9392 const uint8_t* end_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009393 DISALLOW_COPY_AND_ASSIGN(StringCharacterStream);
Steve Blocka7e24c12009-10-30 11:49:00 +00009394};
9395
9396
9397template <typename T>
9398class VectorIterator {
9399 public:
9400 VectorIterator(T* d, int l) : data_(Vector<const T>(d, l)), index_(0) { }
9401 explicit VectorIterator(Vector<const T> data) : data_(data), index_(0) { }
9402 T GetNext() { return data_[index_++]; }
9403 bool has_more() { return index_ < data_.length(); }
9404 private:
9405 Vector<const T> data_;
9406 int index_;
9407};
9408
9409
9410// The Oddball describes objects null, undefined, true, and false.
9411class Oddball: public HeapObject {
9412 public:
Ben Murdochc5610432016-08-08 18:44:38 +01009413 // [to_number_raw]: Cached raw to_number computed at startup.
9414 inline double to_number_raw() const;
9415 inline void set_to_number_raw(double value);
9416
Steve Blocka7e24c12009-10-30 11:49:00 +00009417 // [to_string]: Cached to_string computed at startup.
9418 DECL_ACCESSORS(to_string, String)
9419
9420 // [to_number]: Cached to_number computed at startup.
9421 DECL_ACCESSORS(to_number, Object)
9422
Ben Murdochda12d292016-06-02 14:46:10 +01009423 // [to_number]: Cached to_boolean computed at startup.
9424 DECL_ACCESSORS(to_boolean, Oddball)
9425
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009426 // [typeof]: Cached type_of computed at startup.
9427 DECL_ACCESSORS(type_of, String)
9428
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009429 inline byte kind() const;
Steve Block44f0eee2011-05-26 01:26:41 +01009430 inline void set_kind(byte kind);
9431
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009432 // ES6 section 7.1.3 ToNumber for Boolean, Null, Undefined.
9433 MUST_USE_RESULT static inline Handle<Object> ToNumber(Handle<Oddball> input);
9434
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009435 DECLARE_CAST(Oddball)
Steve Blocka7e24c12009-10-30 11:49:00 +00009436
9437 // Dispatched behavior.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009438 DECLARE_VERIFIER(Oddball)
Steve Blocka7e24c12009-10-30 11:49:00 +00009439
9440 // Initialize the fields.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009441 static void Initialize(Isolate* isolate, Handle<Oddball> oddball,
9442 const char* to_string, Handle<Object> to_number,
Ben Murdochda12d292016-06-02 14:46:10 +01009443 bool to_boolean, const char* type_of, byte kind);
Steve Blocka7e24c12009-10-30 11:49:00 +00009444
9445 // Layout description.
Ben Murdochc5610432016-08-08 18:44:38 +01009446 static const int kToNumberRawOffset = HeapObject::kHeaderSize;
9447 static const int kToStringOffset = kToNumberRawOffset + kDoubleSize;
Steve Blocka7e24c12009-10-30 11:49:00 +00009448 static const int kToNumberOffset = kToStringOffset + kPointerSize;
Ben Murdochda12d292016-06-02 14:46:10 +01009449 static const int kToBooleanOffset = kToNumberOffset + kPointerSize;
9450 static const int kTypeOfOffset = kToBooleanOffset + kPointerSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009451 static const int kKindOffset = kTypeOfOffset + kPointerSize;
Steve Block44f0eee2011-05-26 01:26:41 +01009452 static const int kSize = kKindOffset + kPointerSize;
9453
9454 static const byte kFalse = 0;
9455 static const byte kTrue = 1;
9456 static const byte kNotBooleanMask = ~1;
9457 static const byte kTheHole = 2;
9458 static const byte kNull = 3;
Ben Murdoch097c5b22016-05-18 11:27:45 +01009459 static const byte kArgumentsMarker = 4;
Steve Block44f0eee2011-05-26 01:26:41 +01009460 static const byte kUndefined = 5;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009461 static const byte kUninitialized = 6;
9462 static const byte kOther = 7;
9463 static const byte kException = 8;
Ben Murdochda12d292016-06-02 14:46:10 +01009464 static const byte kOptimizedOut = 9;
Ben Murdochc5610432016-08-08 18:44:38 +01009465 static const byte kStaleRegister = 10;
Steve Blocka7e24c12009-10-30 11:49:00 +00009466
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009467 typedef FixedBodyDescriptor<kToStringOffset, kTypeOfOffset + kPointerSize,
Iain Merrick75681382010-08-19 15:07:18 +01009468 kSize> BodyDescriptor;
9469
Ben Murdochc5610432016-08-08 18:44:38 +01009470 STATIC_ASSERT(kToNumberRawOffset == HeapNumber::kValueOffset);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009471 STATIC_ASSERT(kKindOffset == Internals::kOddballKindOffset);
9472 STATIC_ASSERT(kNull == Internals::kNullOddballKind);
9473 STATIC_ASSERT(kUndefined == Internals::kUndefinedOddballKind);
9474
Steve Blocka7e24c12009-10-30 11:49:00 +00009475 private:
9476 DISALLOW_IMPLICIT_CONSTRUCTORS(Oddball);
9477};
9478
9479
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009480class Cell: public HeapObject {
Steve Blocka7e24c12009-10-30 11:49:00 +00009481 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009482 // [value]: value of the cell.
Steve Blocka7e24c12009-10-30 11:49:00 +00009483 DECL_ACCESSORS(value, Object)
9484
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009485 DECLARE_CAST(Cell)
Steve Blocka7e24c12009-10-30 11:49:00 +00009486
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009487 static inline Cell* FromValueAddress(Address value) {
9488 Object* result = FromAddress(value - kValueOffset);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009489 return static_cast<Cell*>(result);
Ben Murdochb0fe1622011-05-05 13:52:32 +01009490 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009491
9492 inline Address ValueAddress() {
9493 return address() + kValueOffset;
9494 }
9495
9496 // Dispatched behavior.
9497 DECLARE_PRINTER(Cell)
9498 DECLARE_VERIFIER(Cell)
Steve Blocka7e24c12009-10-30 11:49:00 +00009499
9500 // Layout description.
9501 static const int kValueOffset = HeapObject::kHeaderSize;
9502 static const int kSize = kValueOffset + kPointerSize;
9503
Iain Merrick75681382010-08-19 15:07:18 +01009504 typedef FixedBodyDescriptor<kValueOffset,
9505 kValueOffset + kPointerSize,
9506 kSize> BodyDescriptor;
9507
Steve Blocka7e24c12009-10-30 11:49:00 +00009508 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009509 DISALLOW_IMPLICIT_CONSTRUCTORS(Cell);
9510};
9511
9512
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009513class PropertyCell : public HeapObject {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009514 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009515 // [property_details]: details of the global property.
9516 DECL_ACCESSORS(property_details_raw, Object)
9517 // [value]: value of the global property.
9518 DECL_ACCESSORS(value, Object)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009519 // [dependent_code]: dependent code that depends on the type of the global
9520 // property.
9521 DECL_ACCESSORS(dependent_code, DependentCode)
9522
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009523 inline PropertyDetails property_details();
9524 inline void set_property_details(PropertyDetails details);
9525
9526 PropertyCellConstantType GetConstantType();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009527
9528 // Computes the new type of the cell's contents for the given value, but
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009529 // without actually modifying the details.
9530 static PropertyCellType UpdatedType(Handle<PropertyCell> cell,
9531 Handle<Object> value,
9532 PropertyDetails details);
9533 static void UpdateCell(Handle<GlobalDictionary> dictionary, int entry,
9534 Handle<Object> value, PropertyDetails details);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009535
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009536 static Handle<PropertyCell> InvalidateEntry(
9537 Handle<GlobalDictionary> dictionary, int entry);
9538
9539 static void SetValueWithInvalidation(Handle<PropertyCell> cell,
9540 Handle<Object> new_value);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009541
9542 DECLARE_CAST(PropertyCell)
9543
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009544 // Dispatched behavior.
9545 DECLARE_PRINTER(PropertyCell)
9546 DECLARE_VERIFIER(PropertyCell)
9547
9548 // Layout description.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009549 static const int kDetailsOffset = HeapObject::kHeaderSize;
9550 static const int kValueOffset = kDetailsOffset + kPointerSize;
9551 static const int kDependentCodeOffset = kValueOffset + kPointerSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009552 static const int kSize = kDependentCodeOffset + kPointerSize;
9553
9554 static const int kPointerFieldsBeginOffset = kValueOffset;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009555 static const int kPointerFieldsEndOffset = kSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009556
9557 typedef FixedBodyDescriptor<kValueOffset,
9558 kSize,
9559 kSize> BodyDescriptor;
9560
9561 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009562 DISALLOW_IMPLICIT_CONSTRUCTORS(PropertyCell);
Steve Blocka7e24c12009-10-30 11:49:00 +00009563};
9564
9565
Emily Bernierd0a1eb72015-03-24 16:35:39 -04009566class WeakCell : public HeapObject {
9567 public:
9568 inline Object* value() const;
9569
9570 // This should not be called by anyone except GC.
9571 inline void clear();
9572
9573 // This should not be called by anyone except allocator.
9574 inline void initialize(HeapObject* value);
9575
9576 inline bool cleared() const;
9577
9578 DECL_ACCESSORS(next, Object)
9579
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009580 inline void clear_next(Object* the_hole_value);
9581
9582 inline bool next_cleared();
9583
Emily Bernierd0a1eb72015-03-24 16:35:39 -04009584 DECLARE_CAST(WeakCell)
9585
9586 DECLARE_PRINTER(WeakCell)
9587 DECLARE_VERIFIER(WeakCell)
9588
9589 // Layout description.
9590 static const int kValueOffset = HeapObject::kHeaderSize;
9591 static const int kNextOffset = kValueOffset + kPointerSize;
9592 static const int kSize = kNextOffset + kPointerSize;
9593
9594 typedef FixedBodyDescriptor<kValueOffset, kSize, kSize> BodyDescriptor;
9595
9596 private:
9597 DISALLOW_IMPLICIT_CONSTRUCTORS(WeakCell);
9598};
9599
9600
Ben Murdoch257744e2011-11-30 15:57:28 +00009601// The JSProxy describes EcmaScript Harmony proxies
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00009602class JSProxy: public JSReceiver {
Steve Blocka7e24c12009-10-30 11:49:00 +00009603 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009604 MUST_USE_RESULT static MaybeHandle<JSProxy> New(Isolate* isolate,
9605 Handle<Object>,
9606 Handle<Object>);
9607
Ben Murdoch257744e2011-11-30 15:57:28 +00009608 // [handler]: The handler property.
9609 DECL_ACCESSORS(handler, Object)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009610 // [target]: The target property.
9611 DECL_ACCESSORS(target, JSReceiver)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01009612 // [hash]: The hash code property (undefined if not initialized yet).
9613 DECL_ACCESSORS(hash, Object)
9614
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009615 static MaybeHandle<Context> GetFunctionRealm(Handle<JSProxy> proxy);
9616
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009617 DECLARE_CAST(JSProxy)
Steve Blocka7e24c12009-10-30 11:49:00 +00009618
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009619 INLINE(bool IsRevoked() const);
9620 static void Revoke(Handle<JSProxy> proxy);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00009621
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009622 // ES6 9.5.1
9623 static MaybeHandle<Object> GetPrototype(Handle<JSProxy> receiver);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01009624
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009625 // ES6 9.5.2
9626 MUST_USE_RESULT static Maybe<bool> SetPrototype(Handle<JSProxy> proxy,
9627 Handle<Object> value,
9628 bool from_javascript,
9629 ShouldThrow should_throw);
9630 // ES6 9.5.3
9631 MUST_USE_RESULT static Maybe<bool> IsExtensible(Handle<JSProxy> proxy);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00009632
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009633 // ES6 9.5.4 (when passed DONT_THROW)
9634 MUST_USE_RESULT static Maybe<bool> PreventExtensions(
9635 Handle<JSProxy> proxy, ShouldThrow should_throw);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00009636
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009637 // ES6 9.5.5
9638 MUST_USE_RESULT static Maybe<bool> GetOwnPropertyDescriptor(
9639 Isolate* isolate, Handle<JSProxy> proxy, Handle<Name> name,
9640 PropertyDescriptor* desc);
Ben Murdoch589d6972011-11-30 16:04:58 +00009641
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009642 // ES6 9.5.6
9643 MUST_USE_RESULT static Maybe<bool> DefineOwnProperty(
9644 Isolate* isolate, Handle<JSProxy> object, Handle<Object> key,
9645 PropertyDescriptor* desc, ShouldThrow should_throw);
9646
9647 // ES6 9.5.7
9648 MUST_USE_RESULT static Maybe<bool> HasProperty(Isolate* isolate,
9649 Handle<JSProxy> proxy,
9650 Handle<Name> name);
9651
9652 // ES6 9.5.8
9653 MUST_USE_RESULT static MaybeHandle<Object> GetProperty(
9654 Isolate* isolate, Handle<JSProxy> proxy, Handle<Name> name,
Ben Murdochda12d292016-06-02 14:46:10 +01009655 Handle<Object> receiver, bool* was_found);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009656
9657 // ES6 9.5.9
9658 MUST_USE_RESULT static Maybe<bool> SetProperty(Handle<JSProxy> proxy,
9659 Handle<Name> name,
9660 Handle<Object> value,
9661 Handle<Object> receiver,
9662 LanguageMode language_mode);
9663
9664 // ES6 9.5.10 (when passed SLOPPY)
9665 MUST_USE_RESULT static Maybe<bool> DeletePropertyOrElement(
9666 Handle<JSProxy> proxy, Handle<Name> name, LanguageMode language_mode);
9667
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009668 // ES6 9.5.12
9669 MUST_USE_RESULT static Maybe<bool> OwnPropertyKeys(
9670 Isolate* isolate, Handle<JSReceiver> receiver, Handle<JSProxy> proxy,
9671 PropertyFilter filter, KeyAccumulator* accumulator);
9672
9673 MUST_USE_RESULT static Maybe<PropertyAttributes> GetPropertyAttributes(
9674 LookupIterator* it);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01009675
Steve Blocka7e24c12009-10-30 11:49:00 +00009676 // Dispatched behavior.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009677 DECLARE_PRINTER(JSProxy)
9678 DECLARE_VERIFIER(JSProxy)
Ben Murdoch257744e2011-11-30 15:57:28 +00009679
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009680 // Layout description.
9681 static const int kTargetOffset = JSReceiver::kHeaderSize;
9682 static const int kHandlerOffset = kTargetOffset + kPointerSize;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01009683 static const int kHashOffset = kHandlerOffset + kPointerSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009684 static const int kSize = kHashOffset + kPointerSize;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00009685
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009686 typedef FixedBodyDescriptor<JSReceiver::kPropertiesOffset, kSize, kSize>
9687 BodyDescriptor;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009688
Ben Murdochda12d292016-06-02 14:46:10 +01009689 static Handle<Object> GetIdentityHash(Isolate* isolate,
9690 Handle<JSProxy> receiver);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009691
9692 static Handle<Smi> GetOrCreateIdentityHash(Handle<JSProxy> proxy);
9693
Ben Murdoch097c5b22016-05-18 11:27:45 +01009694 static Maybe<bool> SetPrivateProperty(Isolate* isolate, Handle<JSProxy> proxy,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009695 Handle<Symbol> private_name,
9696 PropertyDescriptor* desc,
9697 ShouldThrow should_throw);
9698
Ben Murdoch097c5b22016-05-18 11:27:45 +01009699 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009700 DISALLOW_IMPLICIT_CONSTRUCTORS(JSProxy);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00009701};
9702
Ben Murdoch257744e2011-11-30 15:57:28 +00009703
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009704class JSCollection : public JSObject {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01009705 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009706 // [table]: the backing hash table
Ben Murdoch3ef787d2012-04-12 10:51:47 +01009707 DECL_ACCESSORS(table, Object)
9708
Ben Murdoch3ef787d2012-04-12 10:51:47 +01009709 static const int kTableOffset = JSObject::kHeaderSize;
9710 static const int kSize = kTableOffset + kPointerSize;
9711
9712 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009713 DISALLOW_IMPLICIT_CONSTRUCTORS(JSCollection);
9714};
9715
9716
9717// The JSSet describes EcmaScript Harmony sets
9718class JSSet : public JSCollection {
9719 public:
9720 DECLARE_CAST(JSSet)
9721
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009722 static void Initialize(Handle<JSSet> set, Isolate* isolate);
9723 static void Clear(Handle<JSSet> set);
9724
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009725 // Dispatched behavior.
9726 DECLARE_PRINTER(JSSet)
9727 DECLARE_VERIFIER(JSSet)
9728
9729 private:
Ben Murdoch3ef787d2012-04-12 10:51:47 +01009730 DISALLOW_IMPLICIT_CONSTRUCTORS(JSSet);
9731};
9732
9733
9734// The JSMap describes EcmaScript Harmony maps
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009735class JSMap : public JSCollection {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01009736 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009737 DECLARE_CAST(JSMap)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01009738
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009739 static void Initialize(Handle<JSMap> map, Isolate* isolate);
9740 static void Clear(Handle<JSMap> map);
9741
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009742 // Dispatched behavior.
9743 DECLARE_PRINTER(JSMap)
9744 DECLARE_VERIFIER(JSMap)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01009745
9746 private:
9747 DISALLOW_IMPLICIT_CONSTRUCTORS(JSMap);
9748};
9749
9750
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009751// OrderedHashTableIterator is an iterator that iterates over the keys and
9752// values of an OrderedHashTable.
9753//
9754// The iterator has a reference to the underlying OrderedHashTable data,
9755// [table], as well as the current [index] the iterator is at.
9756//
9757// When the OrderedHashTable is rehashed it adds a reference from the old table
9758// to the new table as well as storing enough data about the changes so that the
9759// iterator [index] can be adjusted accordingly.
9760//
9761// When the [Next] result from the iterator is requested, the iterator checks if
9762// there is a newer table that it needs to transition to.
9763template<class Derived, class TableType>
9764class OrderedHashTableIterator: public JSObject {
9765 public:
9766 // [table]: the backing hash table mapping keys to values.
9767 DECL_ACCESSORS(table, Object)
9768
9769 // [index]: The index into the data table.
9770 DECL_ACCESSORS(index, Object)
9771
9772 // [kind]: The kind of iteration this is. One of the [Kind] enum values.
9773 DECL_ACCESSORS(kind, Object)
9774
9775#ifdef OBJECT_PRINT
Emily Bernierd0a1eb72015-03-24 16:35:39 -04009776 void OrderedHashTableIteratorPrint(std::ostream& os); // NOLINT
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009777#endif
9778
9779 static const int kTableOffset = JSObject::kHeaderSize;
9780 static const int kIndexOffset = kTableOffset + kPointerSize;
9781 static const int kKindOffset = kIndexOffset + kPointerSize;
9782 static const int kSize = kKindOffset + kPointerSize;
9783
9784 enum Kind {
9785 kKindKeys = 1,
9786 kKindValues = 2,
9787 kKindEntries = 3
9788 };
9789
9790 // Whether the iterator has more elements. This needs to be called before
9791 // calling |CurrentKey| and/or |CurrentValue|.
9792 bool HasMore();
9793
9794 // Move the index forward one.
9795 void MoveNext() {
9796 set_index(Smi::FromInt(Smi::cast(index())->value() + 1));
9797 }
9798
9799 // Populates the array with the next key and value and then moves the iterator
9800 // forward.
9801 // This returns the |kind| or 0 if the iterator is already at the end.
9802 Smi* Next(JSArray* value_array);
9803
9804 // Returns the current key of the iterator. This should only be called when
9805 // |HasMore| returns true.
9806 inline Object* CurrentKey();
9807
9808 private:
9809 // Transitions the iterator to the non obsolete backing store. This is a NOP
9810 // if the [table] is not obsolete.
9811 void Transition();
9812
9813 DISALLOW_IMPLICIT_CONSTRUCTORS(OrderedHashTableIterator);
9814};
9815
9816
9817class JSSetIterator: public OrderedHashTableIterator<JSSetIterator,
9818 OrderedHashSet> {
9819 public:
9820 // Dispatched behavior.
9821 DECLARE_PRINTER(JSSetIterator)
9822 DECLARE_VERIFIER(JSSetIterator)
9823
9824 DECLARE_CAST(JSSetIterator)
9825
9826 // Called by |Next| to populate the array. This allows the subclasses to
9827 // populate the array differently.
9828 inline void PopulateValueArray(FixedArray* array);
9829
9830 private:
9831 DISALLOW_IMPLICIT_CONSTRUCTORS(JSSetIterator);
9832};
9833
9834
9835class JSMapIterator: public OrderedHashTableIterator<JSMapIterator,
9836 OrderedHashMap> {
9837 public:
9838 // Dispatched behavior.
9839 DECLARE_PRINTER(JSMapIterator)
9840 DECLARE_VERIFIER(JSMapIterator)
9841
9842 DECLARE_CAST(JSMapIterator)
9843
9844 // Called by |Next| to populate the array. This allows the subclasses to
9845 // populate the array differently.
9846 inline void PopulateValueArray(FixedArray* array);
9847
9848 private:
9849 // Returns the current value of the iterator. This should only be called when
9850 // |HasMore| returns true.
9851 inline Object* CurrentValue();
9852
9853 DISALLOW_IMPLICIT_CONSTRUCTORS(JSMapIterator);
9854};
9855
9856
9857// Base class for both JSWeakMap and JSWeakSet
9858class JSWeakCollection: public JSObject {
Ben Murdoch69a99ed2011-11-30 16:03:39 +00009859 public:
9860 // [table]: the backing hash table mapping keys to values.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01009861 DECL_ACCESSORS(table, Object)
Ben Murdoch69a99ed2011-11-30 16:03:39 +00009862
9863 // [next]: linked list of encountered weak maps during GC.
9864 DECL_ACCESSORS(next, Object)
9865
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009866 static void Initialize(Handle<JSWeakCollection> collection, Isolate* isolate);
9867 static void Set(Handle<JSWeakCollection> collection, Handle<Object> key,
9868 Handle<Object> value, int32_t hash);
9869 static bool Delete(Handle<JSWeakCollection> collection, Handle<Object> key,
9870 int32_t hash);
9871
Ben Murdoch69a99ed2011-11-30 16:03:39 +00009872 static const int kTableOffset = JSObject::kHeaderSize;
9873 static const int kNextOffset = kTableOffset + kPointerSize;
9874 static const int kSize = kNextOffset + kPointerSize;
9875
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009876 // Visiting policy defines whether the table and next collection fields
9877 // should be visited or not.
9878 enum BodyVisitingPolicy { kVisitStrong, kVisitWeak };
9879
9880 // Iterates the function object according to the visiting policy.
9881 template <BodyVisitingPolicy>
9882 class BodyDescriptorImpl;
9883
9884 // Visit the whole object.
9885 typedef BodyDescriptorImpl<kVisitStrong> BodyDescriptor;
9886
9887 // Don't visit table and next collection fields.
9888 typedef BodyDescriptorImpl<kVisitWeak> BodyDescriptorWeak;
9889
Ben Murdoch69a99ed2011-11-30 16:03:39 +00009890 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009891 DISALLOW_IMPLICIT_CONSTRUCTORS(JSWeakCollection);
9892};
9893
9894
9895// The JSWeakMap describes EcmaScript Harmony weak maps
9896class JSWeakMap: public JSWeakCollection {
9897 public:
9898 DECLARE_CAST(JSWeakMap)
9899
9900 // Dispatched behavior.
9901 DECLARE_PRINTER(JSWeakMap)
9902 DECLARE_VERIFIER(JSWeakMap)
9903
9904 private:
Ben Murdoch69a99ed2011-11-30 16:03:39 +00009905 DISALLOW_IMPLICIT_CONSTRUCTORS(JSWeakMap);
9906};
9907
9908
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009909// The JSWeakSet describes EcmaScript Harmony weak sets
9910class JSWeakSet: public JSWeakCollection {
9911 public:
9912 DECLARE_CAST(JSWeakSet)
9913
9914 // Dispatched behavior.
9915 DECLARE_PRINTER(JSWeakSet)
9916 DECLARE_VERIFIER(JSWeakSet)
9917
9918 private:
9919 DISALLOW_IMPLICIT_CONSTRUCTORS(JSWeakSet);
9920};
9921
9922
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009923// Whether a JSArrayBuffer is a SharedArrayBuffer or not.
9924enum class SharedFlag { kNotShared, kShared };
9925
9926
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009927class JSArrayBuffer: public JSObject {
9928 public:
9929 // [backing_store]: backing memory for this array
9930 DECL_ACCESSORS(backing_store, void)
9931
9932 // [byte_length]: length in bytes
9933 DECL_ACCESSORS(byte_length, Object)
9934
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009935 inline uint32_t bit_field() const;
9936 inline void set_bit_field(uint32_t bits);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009937
9938 inline bool is_external();
9939 inline void set_is_external(bool value);
9940
Emily Bernierd0a1eb72015-03-24 16:35:39 -04009941 inline bool is_neuterable();
9942 inline void set_is_neuterable(bool value);
9943
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009944 inline bool was_neutered();
9945 inline void set_was_neutered(bool value);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009946
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009947 inline bool is_shared();
9948 inline void set_is_shared(bool value);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009949
9950 DECLARE_CAST(JSArrayBuffer)
9951
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009952 void Neuter();
9953
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009954 static void Setup(Handle<JSArrayBuffer> array_buffer, Isolate* isolate,
9955 bool is_external, void* data, size_t allocated_length,
9956 SharedFlag shared = SharedFlag::kNotShared);
9957
9958 static bool SetupAllocatingData(Handle<JSArrayBuffer> array_buffer,
9959 Isolate* isolate, size_t allocated_length,
9960 bool initialize = true,
9961 SharedFlag shared = SharedFlag::kNotShared);
9962
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009963 // Dispatched behavior.
9964 DECLARE_PRINTER(JSArrayBuffer)
9965 DECLARE_VERIFIER(JSArrayBuffer)
9966
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009967 static const int kByteLengthOffset = JSObject::kHeaderSize;
9968 static const int kBackingStoreOffset = kByteLengthOffset + kPointerSize;
9969 static const int kBitFieldSlot = kBackingStoreOffset + kPointerSize;
9970#if V8_TARGET_LITTLE_ENDIAN || !V8_HOST_ARCH_64_BIT
9971 static const int kBitFieldOffset = kBitFieldSlot;
9972#else
9973 static const int kBitFieldOffset = kBitFieldSlot + kIntSize;
9974#endif
9975 static const int kSize = kBitFieldSlot + kPointerSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009976
9977 static const int kSizeWithInternalFields =
9978 kSize + v8::ArrayBuffer::kInternalFieldCount * kPointerSize;
9979
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009980 // Iterates all fields in the object including internal ones except
9981 // kBackingStoreOffset and kBitFieldSlot.
9982 class BodyDescriptor;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009983
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009984 class IsExternal : public BitField<bool, 1, 1> {};
9985 class IsNeuterable : public BitField<bool, 2, 1> {};
9986 class WasNeutered : public BitField<bool, 3, 1> {};
9987 class IsShared : public BitField<bool, 4, 1> {};
9988
9989 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009990 DISALLOW_IMPLICIT_CONSTRUCTORS(JSArrayBuffer);
9991};
9992
9993
9994class JSArrayBufferView: public JSObject {
9995 public:
9996 // [buffer]: ArrayBuffer that this typed array views.
9997 DECL_ACCESSORS(buffer, Object)
9998
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009999 // [byte_offset]: offset of typed array in bytes.
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010000 DECL_ACCESSORS(byte_offset, Object)
10001
10002 // [byte_length]: length of typed array in bytes.
10003 DECL_ACCESSORS(byte_length, Object)
10004
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010005 DECLARE_CAST(JSArrayBufferView)
10006
10007 DECLARE_VERIFIER(JSArrayBufferView)
10008
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010009 inline bool WasNeutered() const;
10010
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010011 static const int kBufferOffset = JSObject::kHeaderSize;
10012 static const int kByteOffsetOffset = kBufferOffset + kPointerSize;
10013 static const int kByteLengthOffset = kByteOffsetOffset + kPointerSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010014 static const int kViewSize = kByteLengthOffset + kPointerSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010015
10016 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010017#ifdef VERIFY_HEAP
10018 DECL_ACCESSORS(raw_byte_offset, Object)
10019 DECL_ACCESSORS(raw_byte_length, Object)
10020#endif
10021
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010022 DISALLOW_IMPLICIT_CONSTRUCTORS(JSArrayBufferView);
10023};
10024
10025
10026class JSTypedArray: public JSArrayBufferView {
10027 public:
10028 // [length]: length of typed array in elements.
10029 DECL_ACCESSORS(length, Object)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010030 inline uint32_t length_value() const;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010031
10032 DECLARE_CAST(JSTypedArray)
10033
10034 ExternalArrayType type();
10035 size_t element_size();
10036
10037 Handle<JSArrayBuffer> GetBuffer();
10038
10039 // Dispatched behavior.
10040 DECLARE_PRINTER(JSTypedArray)
10041 DECLARE_VERIFIER(JSTypedArray)
10042
10043 static const int kLengthOffset = kViewSize + kPointerSize;
10044 static const int kSize = kLengthOffset + kPointerSize;
10045
10046 static const int kSizeWithInternalFields =
10047 kSize + v8::ArrayBufferView::kInternalFieldCount * kPointerSize;
10048
10049 private:
10050 static Handle<JSArrayBuffer> MaterializeArrayBuffer(
10051 Handle<JSTypedArray> typed_array);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010052#ifdef VERIFY_HEAP
10053 DECL_ACCESSORS(raw_length, Object)
10054#endif
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010055
10056 DISALLOW_IMPLICIT_CONSTRUCTORS(JSTypedArray);
10057};
10058
10059
10060class JSDataView: public JSArrayBufferView {
10061 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010062 DECLARE_CAST(JSDataView)
10063
10064 // Dispatched behavior.
10065 DECLARE_PRINTER(JSDataView)
10066 DECLARE_VERIFIER(JSDataView)
10067
10068 static const int kSize = kViewSize;
10069
10070 static const int kSizeWithInternalFields =
10071 kSize + v8::ArrayBufferView::kInternalFieldCount * kPointerSize;
10072
10073 private:
10074 DISALLOW_IMPLICIT_CONSTRUCTORS(JSDataView);
10075};
10076
10077
Ben Murdoch257744e2011-11-30 15:57:28 +000010078// Foreign describes objects pointing from JavaScript to C structures.
Ben Murdoch257744e2011-11-30 15:57:28 +000010079class Foreign: public HeapObject {
10080 public:
10081 // [address]: field containing the address.
Ben Murdoch3ef787d2012-04-12 10:51:47 +010010082 inline Address foreign_address();
10083 inline void set_foreign_address(Address value);
Ben Murdoch257744e2011-11-30 15:57:28 +000010084
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010085 DECLARE_CAST(Foreign)
Ben Murdoch257744e2011-11-30 15:57:28 +000010086
10087 // Dispatched behavior.
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010088 DECLARE_PRINTER(Foreign)
10089 DECLARE_VERIFIER(Foreign)
Steve Blocka7e24c12009-10-30 11:49:00 +000010090
10091 // Layout description.
10092
Ben Murdoch3ef787d2012-04-12 10:51:47 +010010093 static const int kForeignAddressOffset = HeapObject::kHeaderSize;
10094 static const int kSize = kForeignAddressOffset + kPointerSize;
Steve Blocka7e24c12009-10-30 11:49:00 +000010095
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010096 STATIC_ASSERT(kForeignAddressOffset == Internals::kForeignAddressOffset);
Steve Blocka7e24c12009-10-30 11:49:00 +000010097
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010098 class BodyDescriptor;
10099
Steve Blocka7e24c12009-10-30 11:49:00 +000010100 private:
Ben Murdoch257744e2011-11-30 15:57:28 +000010101 DISALLOW_IMPLICIT_CONSTRUCTORS(Foreign);
Steve Blocka7e24c12009-10-30 11:49:00 +000010102};
10103
10104
10105// The JSArray describes JavaScript Arrays
10106// Such an array can be in one of two modes:
10107// - fast, backing storage is a FixedArray and length <= elements.length();
10108// Please note: push and pop can be used to grow and shrink the array.
10109// - slow, backing storage is a HashTable with numbers as keys.
10110class JSArray: public JSObject {
10111 public:
10112 // [length]: The length property.
10113 DECL_ACCESSORS(length, Object)
10114
Leon Clarke4515c472010-02-03 11:58:03 +000010115 // Overload the length setter to skip write barrier when the length
10116 // is set to a smi. This matches the set function on FixedArray.
10117 inline void set_length(Smi* length);
10118
Emily Bernierd0a1eb72015-03-24 16:35:39 -040010119 static bool HasReadOnlyLength(Handle<JSArray> array);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010120 static bool WouldChangeReadOnlyLength(Handle<JSArray> array, uint32_t index);
Emily Bernierd0a1eb72015-03-24 16:35:39 -040010121
Steve Blocka7e24c12009-10-30 11:49:00 +000010122 // Initialize the array with the given capacity. The function may
10123 // fail due to out-of-memory situations, but only if the requested
10124 // capacity is non-zero.
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010125 static void Initialize(Handle<JSArray> array, int capacity, int length = 0);
Steve Blocka7e24c12009-10-30 11:49:00 +000010126
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010127 // If the JSArray has fast elements, and new_length would result in
10128 // normalization, returns true.
10129 bool SetLengthWouldNormalize(uint32_t new_length);
10130 static inline bool SetLengthWouldNormalize(Heap* heap, uint32_t new_length);
10131
Ben Murdoch3ef787d2012-04-12 10:51:47 +010010132 // Initializes the array to a certain length.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010133 inline bool AllowsSetLength();
10134
10135 static void SetLength(Handle<JSArray> array, uint32_t length);
Ben Murdoch3ef787d2012-04-12 10:51:47 +010010136
Steve Blocka7e24c12009-10-30 11:49:00 +000010137 // Set the content of the array to the content of storage.
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010138 static inline void SetContent(Handle<JSArray> array,
10139 Handle<FixedArrayBase> storage);
Steve Blocka7e24c12009-10-30 11:49:00 +000010140
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010141 // ES6 9.4.2.1
10142 MUST_USE_RESULT static Maybe<bool> DefineOwnProperty(
10143 Isolate* isolate, Handle<JSArray> o, Handle<Object> name,
10144 PropertyDescriptor* desc, ShouldThrow should_throw);
10145
10146 static bool AnythingToArrayLength(Isolate* isolate,
10147 Handle<Object> length_object,
10148 uint32_t* output);
10149 MUST_USE_RESULT static Maybe<bool> ArraySetLength(Isolate* isolate,
10150 Handle<JSArray> a,
10151 PropertyDescriptor* desc,
10152 ShouldThrow should_throw);
10153
Ben Murdochda12d292016-06-02 14:46:10 +010010154 // Checks whether the Array has the current realm's Array.prototype as its
10155 // prototype. This function is best-effort and only gives a conservative
10156 // approximation, erring on the side of false, in particular with respect
10157 // to Proxies and objects with a hidden prototype.
10158 inline bool HasArrayPrototype(Isolate* isolate);
10159
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010160 DECLARE_CAST(JSArray)
Steve Blocka7e24c12009-10-30 11:49:00 +000010161
Steve Blocka7e24c12009-10-30 11:49:00 +000010162 // Dispatched behavior.
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010163 DECLARE_PRINTER(JSArray)
10164 DECLARE_VERIFIER(JSArray)
Steve Blocka7e24c12009-10-30 11:49:00 +000010165
10166 // Number of element slots to pre-allocate for an empty array.
10167 static const int kPreallocatedArrayElements = 4;
10168
10169 // Layout description.
10170 static const int kLengthOffset = JSObject::kHeaderSize;
10171 static const int kSize = kLengthOffset + kPointerSize;
10172
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010173 // 600 * KB is the Page::kMaxRegularHeapObjectSize defined in spaces.h which
10174 // we do not want to include in objects.h
10175 // Note that Page::kMaxRegularHeapObjectSize has to be in sync with
10176 // kInitialMaxFastElementArray which is checked in a DCHECK in heap.cc.
10177 static const int kInitialMaxFastElementArray =
10178 (600 * KB - FixedArray::kHeaderSize - kSize - AllocationMemento::kSize) /
10179 kPointerSize;
10180
Steve Blocka7e24c12009-10-30 11:49:00 +000010181 private:
Steve Blocka7e24c12009-10-30 11:49:00 +000010182 DISALLOW_IMPLICIT_CONSTRUCTORS(JSArray);
10183};
10184
10185
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010186Handle<Object> CacheInitialJSArrayMaps(Handle<Context> native_context,
10187 Handle<Map> initial_map);
10188
10189
Steve Block6ded16b2010-05-10 14:33:55 +010010190// JSRegExpResult is just a JSArray with a specific initial map.
10191// This initial map adds in-object properties for "index" and "input"
10192// properties, as assigned by RegExp.prototype.exec, which allows
10193// faster creation of RegExp exec results.
10194// This class just holds constants used when creating the result.
10195// After creation the result must be treated as a JSArray in all regards.
10196class JSRegExpResult: public JSArray {
10197 public:
10198 // Offsets of object fields.
10199 static const int kIndexOffset = JSArray::kSize;
10200 static const int kInputOffset = kIndexOffset + kPointerSize;
10201 static const int kSize = kInputOffset + kPointerSize;
10202 // Indices of in-object properties.
10203 static const int kIndexIndex = 0;
10204 static const int kInputIndex = 1;
10205 private:
10206 DISALLOW_IMPLICIT_CONSTRUCTORS(JSRegExpResult);
10207};
10208
10209
Ben Murdoch097c5b22016-05-18 11:27:45 +010010210// An accessor must have a getter, but can have no setter.
10211//
10212// When setting a property, V8 searches accessors in prototypes.
10213// If an accessor was found and it does not have a setter,
10214// the request is ignored.
10215//
10216// If the accessor in the prototype has the READ_ONLY property attribute, then
10217// a new value is added to the derived object when the property is set.
10218// This shadows the accessor in the prototype.
Steve Blocka7e24c12009-10-30 11:49:00 +000010219class AccessorInfo: public Struct {
10220 public:
Steve Blocka7e24c12009-10-30 11:49:00 +000010221 DECL_ACCESSORS(name, Object)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010222 DECL_INT_ACCESSORS(flag)
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010223 DECL_ACCESSORS(expected_receiver_type, Object)
Ben Murdochc5610432016-08-08 18:44:38 +010010224 // This directly points at a foreign C function to be used from the runtime.
Ben Murdoch097c5b22016-05-18 11:27:45 +010010225 DECL_ACCESSORS(getter, Object)
10226 DECL_ACCESSORS(setter, Object)
Ben Murdochc5610432016-08-08 18:44:38 +010010227 // This either points at the same as above, or a trampoline in case we are
10228 // running with the simulator. Use these entries from generated code.
10229 DECL_ACCESSORS(js_getter, Object)
Ben Murdoch097c5b22016-05-18 11:27:45 +010010230 DECL_ACCESSORS(data, Object)
10231
Ben Murdochc5610432016-08-08 18:44:38 +010010232 static Address redirect(Isolate* isolate, Address address,
10233 AccessorComponent component);
10234 Address redirected_getter() const;
10235
Ben Murdoch097c5b22016-05-18 11:27:45 +010010236 // Dispatched behavior.
10237 DECLARE_PRINTER(AccessorInfo)
Steve Blocka7e24c12009-10-30 11:49:00 +000010238
10239 inline bool all_can_read();
10240 inline void set_all_can_read(bool value);
10241
10242 inline bool all_can_write();
10243 inline void set_all_can_write(bool value);
10244
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010245 inline bool is_special_data_property();
10246 inline void set_is_special_data_property(bool value);
10247
Ben Murdochda12d292016-06-02 14:46:10 +010010248 inline bool is_sloppy();
10249 inline void set_is_sloppy(bool value);
10250
Steve Blocka7e24c12009-10-30 11:49:00 +000010251 inline PropertyAttributes property_attributes();
10252 inline void set_property_attributes(PropertyAttributes attributes);
10253
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010254 // Checks whether the given receiver is compatible with this accessor.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010255 static bool IsCompatibleReceiverMap(Isolate* isolate,
10256 Handle<AccessorInfo> info,
10257 Handle<Map> map);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010258 inline bool IsCompatibleReceiver(Object* receiver);
Steve Blocka7e24c12009-10-30 11:49:00 +000010259
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010260 DECLARE_CAST(AccessorInfo)
Steve Blocka7e24c12009-10-30 11:49:00 +000010261
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010262 // Dispatched behavior.
10263 DECLARE_VERIFIER(AccessorInfo)
10264
10265 // Append all descriptors to the array that are not already there.
10266 // Return number added.
10267 static int AppendUnique(Handle<Object> descriptors,
10268 Handle<FixedArray> array,
10269 int valid_descriptors);
10270
10271 static const int kNameOffset = HeapObject::kHeaderSize;
Steve Blocka7e24c12009-10-30 11:49:00 +000010272 static const int kFlagOffset = kNameOffset + kPointerSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010273 static const int kExpectedReceiverTypeOffset = kFlagOffset + kPointerSize;
Ben Murdochc5610432016-08-08 18:44:38 +010010274 static const int kSetterOffset = kExpectedReceiverTypeOffset + kPointerSize;
10275 static const int kGetterOffset = kSetterOffset + kPointerSize;
10276 static const int kJsGetterOffset = kGetterOffset + kPointerSize;
10277 static const int kDataOffset = kJsGetterOffset + kPointerSize;
Ben Murdoch097c5b22016-05-18 11:27:45 +010010278 static const int kSize = kDataOffset + kPointerSize;
10279
Steve Blocka7e24c12009-10-30 11:49:00 +000010280
10281 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010282 inline bool HasExpectedReceiverType();
10283
Steve Blocka7e24c12009-10-30 11:49:00 +000010284 // Bit positions in flag.
10285 static const int kAllCanReadBit = 0;
10286 static const int kAllCanWriteBit = 1;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010287 static const int kSpecialDataProperty = 2;
Ben Murdochda12d292016-06-02 14:46:10 +010010288 static const int kIsSloppy = 3;
10289 class AttributesField : public BitField<PropertyAttributes, 4, 3> {};
Steve Blocka7e24c12009-10-30 11:49:00 +000010290
10291 DISALLOW_IMPLICIT_CONSTRUCTORS(AccessorInfo);
10292};
10293
10294
Ben Murdoch3ef787d2012-04-12 10:51:47 +010010295// Support for JavaScript accessors: A pair of a getter and a setter. Each
10296// accessor can either be
10297// * a pointer to a JavaScript function or proxy: a real accessor
10298// * undefined: considered an accessor by the spec, too, strangely enough
10299// * the hole: an accessor which has not been set
10300// * a pointer to a map: a transition used to ensure map sharing
10301class AccessorPair: public Struct {
10302 public:
10303 DECL_ACCESSORS(getter, Object)
10304 DECL_ACCESSORS(setter, Object)
10305
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010306 DECLARE_CAST(AccessorPair)
Ben Murdoch3ef787d2012-04-12 10:51:47 +010010307
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010308 static Handle<AccessorPair> Copy(Handle<AccessorPair> pair);
10309
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010310 inline Object* get(AccessorComponent component);
10311 inline void set(AccessorComponent component, Object* value);
Ben Murdoch3ef787d2012-04-12 10:51:47 +010010312
10313 // Note: Returns undefined instead in case of a hole.
Ben Murdoch097c5b22016-05-18 11:27:45 +010010314 static Handle<Object> GetComponent(Handle<AccessorPair> accessor_pair,
10315 AccessorComponent component);
Ben Murdoch3ef787d2012-04-12 10:51:47 +010010316
10317 // Set both components, skipping arguments which are a JavaScript null.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010318 inline void SetComponents(Object* getter, Object* setter);
Ben Murdoch3ef787d2012-04-12 10:51:47 +010010319
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010320 inline bool Equals(AccessorPair* pair);
10321 inline bool Equals(Object* getter_value, Object* setter_value);
10322
10323 inline bool ContainsAccessor();
Ben Murdoch3ef787d2012-04-12 10:51:47 +010010324
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010325 // Dispatched behavior.
10326 DECLARE_PRINTER(AccessorPair)
10327 DECLARE_VERIFIER(AccessorPair)
Ben Murdoch3ef787d2012-04-12 10:51:47 +010010328
10329 static const int kGetterOffset = HeapObject::kHeaderSize;
10330 static const int kSetterOffset = kGetterOffset + kPointerSize;
10331 static const int kSize = kSetterOffset + kPointerSize;
10332
10333 private:
10334 // Strangely enough, in addition to functions and harmony proxies, the spec
10335 // requires us to consider undefined as a kind of accessor, too:
10336 // var obj = {};
10337 // Object.defineProperty(obj, "foo", {get: undefined});
10338 // assertTrue("foo" in obj);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010339 inline bool IsJSAccessor(Object* obj);
Ben Murdoch3ef787d2012-04-12 10:51:47 +010010340
10341 DISALLOW_IMPLICIT_CONSTRUCTORS(AccessorPair);
10342};
10343
10344
Steve Blocka7e24c12009-10-30 11:49:00 +000010345class AccessCheckInfo: public Struct {
10346 public:
10347 DECL_ACCESSORS(named_callback, Object)
10348 DECL_ACCESSORS(indexed_callback, Object)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010349 DECL_ACCESSORS(callback, Object)
Steve Blocka7e24c12009-10-30 11:49:00 +000010350 DECL_ACCESSORS(data, Object)
10351
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010352 DECLARE_CAST(AccessCheckInfo)
Steve Blocka7e24c12009-10-30 11:49:00 +000010353
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010354 // Dispatched behavior.
10355 DECLARE_PRINTER(AccessCheckInfo)
10356 DECLARE_VERIFIER(AccessCheckInfo)
Steve Blocka7e24c12009-10-30 11:49:00 +000010357
10358 static const int kNamedCallbackOffset = HeapObject::kHeaderSize;
10359 static const int kIndexedCallbackOffset = kNamedCallbackOffset + kPointerSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010360 static const int kCallbackOffset = kIndexedCallbackOffset + kPointerSize;
10361 static const int kDataOffset = kCallbackOffset + kPointerSize;
Steve Blocka7e24c12009-10-30 11:49:00 +000010362 static const int kSize = kDataOffset + kPointerSize;
10363
10364 private:
10365 DISALLOW_IMPLICIT_CONSTRUCTORS(AccessCheckInfo);
10366};
10367
10368
10369class InterceptorInfo: public Struct {
10370 public:
10371 DECL_ACCESSORS(getter, Object)
10372 DECL_ACCESSORS(setter, Object)
10373 DECL_ACCESSORS(query, Object)
10374 DECL_ACCESSORS(deleter, Object)
10375 DECL_ACCESSORS(enumerator, Object)
10376 DECL_ACCESSORS(data, Object)
Emily Bernierd0a1eb72015-03-24 16:35:39 -040010377 DECL_BOOLEAN_ACCESSORS(can_intercept_symbols)
10378 DECL_BOOLEAN_ACCESSORS(all_can_read)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010379 DECL_BOOLEAN_ACCESSORS(non_masking)
Emily Bernierd0a1eb72015-03-24 16:35:39 -040010380
10381 inline int flags() const;
10382 inline void set_flags(int flags);
Steve Blocka7e24c12009-10-30 11:49:00 +000010383
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010384 DECLARE_CAST(InterceptorInfo)
Steve Blocka7e24c12009-10-30 11:49:00 +000010385
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010386 // Dispatched behavior.
10387 DECLARE_PRINTER(InterceptorInfo)
10388 DECLARE_VERIFIER(InterceptorInfo)
Steve Blocka7e24c12009-10-30 11:49:00 +000010389
10390 static const int kGetterOffset = HeapObject::kHeaderSize;
10391 static const int kSetterOffset = kGetterOffset + kPointerSize;
10392 static const int kQueryOffset = kSetterOffset + kPointerSize;
10393 static const int kDeleterOffset = kQueryOffset + kPointerSize;
10394 static const int kEnumeratorOffset = kDeleterOffset + kPointerSize;
10395 static const int kDataOffset = kEnumeratorOffset + kPointerSize;
Emily Bernierd0a1eb72015-03-24 16:35:39 -040010396 static const int kFlagsOffset = kDataOffset + kPointerSize;
10397 static const int kSize = kFlagsOffset + kPointerSize;
10398
10399 static const int kCanInterceptSymbolsBit = 0;
10400 static const int kAllCanReadBit = 1;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010401 static const int kNonMasking = 2;
Steve Blocka7e24c12009-10-30 11:49:00 +000010402
10403 private:
10404 DISALLOW_IMPLICIT_CONSTRUCTORS(InterceptorInfo);
10405};
10406
10407
10408class CallHandlerInfo: public Struct {
10409 public:
10410 DECL_ACCESSORS(callback, Object)
10411 DECL_ACCESSORS(data, Object)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010412 DECL_ACCESSORS(fast_handler, Object)
Steve Blocka7e24c12009-10-30 11:49:00 +000010413
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010414 DECLARE_CAST(CallHandlerInfo)
Steve Blocka7e24c12009-10-30 11:49:00 +000010415
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010416 // Dispatched behavior.
10417 DECLARE_PRINTER(CallHandlerInfo)
10418 DECLARE_VERIFIER(CallHandlerInfo)
Steve Blocka7e24c12009-10-30 11:49:00 +000010419
10420 static const int kCallbackOffset = HeapObject::kHeaderSize;
10421 static const int kDataOffset = kCallbackOffset + kPointerSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010422 static const int kFastHandlerOffset = kDataOffset + kPointerSize;
10423 static const int kSize = kFastHandlerOffset + kPointerSize;
Steve Blocka7e24c12009-10-30 11:49:00 +000010424
10425 private:
10426 DISALLOW_IMPLICIT_CONSTRUCTORS(CallHandlerInfo);
10427};
10428
10429
10430class TemplateInfo: public Struct {
10431 public:
10432 DECL_ACCESSORS(tag, Object)
Ben Murdoch097c5b22016-05-18 11:27:45 +010010433 DECL_ACCESSORS(serial_number, Object)
10434 DECL_INT_ACCESSORS(number_of_properties)
Steve Blocka7e24c12009-10-30 11:49:00 +000010435 DECL_ACCESSORS(property_list, Object)
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010436 DECL_ACCESSORS(property_accessors, Object)
Steve Blocka7e24c12009-10-30 11:49:00 +000010437
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010438 DECLARE_VERIFIER(TemplateInfo)
Steve Blocka7e24c12009-10-30 11:49:00 +000010439
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010440 static const int kTagOffset = HeapObject::kHeaderSize;
Ben Murdoch097c5b22016-05-18 11:27:45 +010010441 static const int kSerialNumberOffset = kTagOffset + kPointerSize;
10442 static const int kNumberOfProperties = kSerialNumberOffset + kPointerSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010443 static const int kPropertyListOffset = kNumberOfProperties + kPointerSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010444 static const int kPropertyAccessorsOffset =
10445 kPropertyListOffset + kPointerSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010446 static const int kPropertyIntrinsicsOffset =
10447 kPropertyAccessorsOffset + kPointerSize;
10448 static const int kHeaderSize = kPropertyIntrinsicsOffset + kPointerSize;
Ben Murdoch3ef787d2012-04-12 10:51:47 +010010449
10450 private:
Steve Blocka7e24c12009-10-30 11:49:00 +000010451 DISALLOW_IMPLICIT_CONSTRUCTORS(TemplateInfo);
10452};
10453
10454
10455class FunctionTemplateInfo: public TemplateInfo {
10456 public:
Steve Blocka7e24c12009-10-30 11:49:00 +000010457 DECL_ACCESSORS(call_code, Object)
Steve Blocka7e24c12009-10-30 11:49:00 +000010458 DECL_ACCESSORS(prototype_template, Object)
10459 DECL_ACCESSORS(parent_template, Object)
10460 DECL_ACCESSORS(named_property_handler, Object)
10461 DECL_ACCESSORS(indexed_property_handler, Object)
10462 DECL_ACCESSORS(instance_template, Object)
10463 DECL_ACCESSORS(class_name, Object)
10464 DECL_ACCESSORS(signature, Object)
10465 DECL_ACCESSORS(instance_call_handler, Object)
10466 DECL_ACCESSORS(access_check_info, Object)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010467 DECL_INT_ACCESSORS(flag)
Steve Blocka7e24c12009-10-30 11:49:00 +000010468
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010469 inline int length() const;
10470 inline void set_length(int value);
10471
Steve Blocka7e24c12009-10-30 11:49:00 +000010472 // Following properties use flag bits.
10473 DECL_BOOLEAN_ACCESSORS(hidden_prototype)
10474 DECL_BOOLEAN_ACCESSORS(undetectable)
10475 // If the bit is set, object instances created by this function
10476 // requires access check.
10477 DECL_BOOLEAN_ACCESSORS(needs_access_check)
Ben Murdoch69a99ed2011-11-30 16:03:39 +000010478 DECL_BOOLEAN_ACCESSORS(read_only_prototype)
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010479 DECL_BOOLEAN_ACCESSORS(remove_prototype)
10480 DECL_BOOLEAN_ACCESSORS(do_not_cache)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010481 DECL_BOOLEAN_ACCESSORS(instantiated)
10482 DECL_BOOLEAN_ACCESSORS(accept_any_receiver)
Steve Blocka7e24c12009-10-30 11:49:00 +000010483
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010484 DECLARE_CAST(FunctionTemplateInfo)
Steve Blocka7e24c12009-10-30 11:49:00 +000010485
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010486 // Dispatched behavior.
10487 DECLARE_PRINTER(FunctionTemplateInfo)
10488 DECLARE_VERIFIER(FunctionTemplateInfo)
Steve Blocka7e24c12009-10-30 11:49:00 +000010489
Ben Murdoch097c5b22016-05-18 11:27:45 +010010490 static const int kCallCodeOffset = TemplateInfo::kHeaderSize;
Steve Blocka7e24c12009-10-30 11:49:00 +000010491 static const int kPrototypeTemplateOffset =
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010492 kCallCodeOffset + kPointerSize;
Steve Blocka7e24c12009-10-30 11:49:00 +000010493 static const int kParentTemplateOffset =
10494 kPrototypeTemplateOffset + kPointerSize;
10495 static const int kNamedPropertyHandlerOffset =
10496 kParentTemplateOffset + kPointerSize;
10497 static const int kIndexedPropertyHandlerOffset =
10498 kNamedPropertyHandlerOffset + kPointerSize;
10499 static const int kInstanceTemplateOffset =
10500 kIndexedPropertyHandlerOffset + kPointerSize;
10501 static const int kClassNameOffset = kInstanceTemplateOffset + kPointerSize;
10502 static const int kSignatureOffset = kClassNameOffset + kPointerSize;
10503 static const int kInstanceCallHandlerOffset = kSignatureOffset + kPointerSize;
10504 static const int kAccessCheckInfoOffset =
10505 kInstanceCallHandlerOffset + kPointerSize;
10506 static const int kFlagOffset = kAccessCheckInfoOffset + kPointerSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010507 static const int kLengthOffset = kFlagOffset + kPointerSize;
10508 static const int kSize = kLengthOffset + kPointerSize;
10509
10510 // Returns true if |object| is an instance of this function template.
10511 bool IsTemplateFor(Object* object);
10512 bool IsTemplateFor(Map* map);
Steve Blocka7e24c12009-10-30 11:49:00 +000010513
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010514 // Returns the holder JSObject if the function can legally be called with this
10515 // receiver. Returns Heap::null_value() if the call is illegal.
10516 Object* GetCompatibleReceiver(Isolate* isolate, Object* receiver);
10517
Steve Blocka7e24c12009-10-30 11:49:00 +000010518 private:
10519 // Bit position in the flag, from least significant bit position.
10520 static const int kHiddenPrototypeBit = 0;
10521 static const int kUndetectableBit = 1;
10522 static const int kNeedsAccessCheckBit = 2;
Ben Murdoch69a99ed2011-11-30 16:03:39 +000010523 static const int kReadOnlyPrototypeBit = 3;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010524 static const int kRemovePrototypeBit = 4;
10525 static const int kDoNotCacheBit = 5;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010526 static const int kInstantiatedBit = 6;
10527 static const int kAcceptAnyReceiver = 7;
Steve Blocka7e24c12009-10-30 11:49:00 +000010528
10529 DISALLOW_IMPLICIT_CONSTRUCTORS(FunctionTemplateInfo);
10530};
10531
10532
10533class ObjectTemplateInfo: public TemplateInfo {
10534 public:
10535 DECL_ACCESSORS(constructor, Object)
10536 DECL_ACCESSORS(internal_field_count, Object)
10537
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010538 DECLARE_CAST(ObjectTemplateInfo)
Steve Blocka7e24c12009-10-30 11:49:00 +000010539
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010540 // Dispatched behavior.
10541 DECLARE_PRINTER(ObjectTemplateInfo)
10542 DECLARE_VERIFIER(ObjectTemplateInfo)
Steve Blocka7e24c12009-10-30 11:49:00 +000010543
10544 static const int kConstructorOffset = TemplateInfo::kHeaderSize;
10545 static const int kInternalFieldCountOffset =
10546 kConstructorOffset + kPointerSize;
10547 static const int kSize = kInternalFieldCountOffset + kPointerSize;
10548};
10549
10550
Steve Blocka7e24c12009-10-30 11:49:00 +000010551// The DebugInfo class holds additional information for a function being
10552// debugged.
10553class DebugInfo: public Struct {
10554 public:
10555 // The shared function info for the source being debugged.
10556 DECL_ACCESSORS(shared, SharedFunctionInfo)
Steve Blocka7e24c12009-10-30 11:49:00 +000010557 // Code object for the patched code. This code object is the code object
10558 // currently active for the function.
Ben Murdoch097c5b22016-05-18 11:27:45 +010010559 DECL_ACCESSORS(abstract_code, AbstractCode)
Steve Blocka7e24c12009-10-30 11:49:00 +000010560 // Fixed array holding status information for each active break point.
10561 DECL_ACCESSORS(break_points, FixedArray)
10562
Ben Murdoch097c5b22016-05-18 11:27:45 +010010563 // Check if there is a break point at a code offset.
10564 bool HasBreakPoint(int code_offset);
10565 // Get the break point info object for a code offset.
10566 Object* GetBreakPointInfo(int code_offset);
Steve Blocka7e24c12009-10-30 11:49:00 +000010567 // Clear a break point.
Ben Murdoch097c5b22016-05-18 11:27:45 +010010568 static void ClearBreakPoint(Handle<DebugInfo> debug_info, int code_offset,
Steve Blocka7e24c12009-10-30 11:49:00 +000010569 Handle<Object> break_point_object);
10570 // Set a break point.
Ben Murdoch097c5b22016-05-18 11:27:45 +010010571 static void SetBreakPoint(Handle<DebugInfo> debug_info, int code_offset,
Steve Blocka7e24c12009-10-30 11:49:00 +000010572 int source_position, int statement_position,
10573 Handle<Object> break_point_object);
Ben Murdoch097c5b22016-05-18 11:27:45 +010010574 // Get the break point objects for a code offset.
10575 Handle<Object> GetBreakPointObjects(int code_offset);
Steve Blocka7e24c12009-10-30 11:49:00 +000010576 // Find the break point info holding this break point object.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010577 static Handle<Object> FindBreakPointInfo(Handle<DebugInfo> debug_info,
10578 Handle<Object> break_point_object);
Steve Blocka7e24c12009-10-30 11:49:00 +000010579 // Get the number of break points for this function.
10580 int GetBreakPointCount();
10581
Ben Murdoch097c5b22016-05-18 11:27:45 +010010582 static Smi* uninitialized() { return Smi::FromInt(0); }
10583
10584 inline BytecodeArray* original_bytecode_array();
10585
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010586 DECLARE_CAST(DebugInfo)
Steve Blocka7e24c12009-10-30 11:49:00 +000010587
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010588 // Dispatched behavior.
10589 DECLARE_PRINTER(DebugInfo)
10590 DECLARE_VERIFIER(DebugInfo)
Steve Blocka7e24c12009-10-30 11:49:00 +000010591
10592 static const int kSharedFunctionInfoIndex = Struct::kHeaderSize;
Ben Murdoch097c5b22016-05-18 11:27:45 +010010593 static const int kAbstractCodeIndex = kSharedFunctionInfoIndex + kPointerSize;
10594 static const int kBreakPointsStateIndex = kAbstractCodeIndex + kPointerSize;
Steve Blocka7e24c12009-10-30 11:49:00 +000010595 static const int kSize = kBreakPointsStateIndex + kPointerSize;
10596
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010597 static const int kEstimatedNofBreakPointsInFunction = 16;
10598
Steve Blocka7e24c12009-10-30 11:49:00 +000010599 private:
10600 static const int kNoBreakPointInfo = -1;
10601
Ben Murdoch097c5b22016-05-18 11:27:45 +010010602 // Lookup the index in the break_points array for a code offset.
10603 int GetBreakPointInfoIndex(int code_offset);
Steve Blocka7e24c12009-10-30 11:49:00 +000010604
10605 DISALLOW_IMPLICIT_CONSTRUCTORS(DebugInfo);
10606};
10607
10608
10609// The BreakPointInfo class holds information for break points set in a
10610// function. The DebugInfo object holds a BreakPointInfo object for each code
10611// position with one or more break points.
10612class BreakPointInfo: public Struct {
10613 public:
Ben Murdoch097c5b22016-05-18 11:27:45 +010010614 // The code offset for the break point.
10615 DECL_INT_ACCESSORS(code_offset)
Steve Blocka7e24c12009-10-30 11:49:00 +000010616 // The position in the source for the break position.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010617 DECL_INT_ACCESSORS(source_position)
Steve Blocka7e24c12009-10-30 11:49:00 +000010618 // The position in the source for the last statement before this break
10619 // position.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010620 DECL_INT_ACCESSORS(statement_position)
Steve Blocka7e24c12009-10-30 11:49:00 +000010621 // List of related JavaScript break points.
10622 DECL_ACCESSORS(break_point_objects, Object)
10623
10624 // Removes a break point.
10625 static void ClearBreakPoint(Handle<BreakPointInfo> info,
10626 Handle<Object> break_point_object);
10627 // Set a break point.
10628 static void SetBreakPoint(Handle<BreakPointInfo> info,
10629 Handle<Object> break_point_object);
10630 // Check if break point info has this break point object.
10631 static bool HasBreakPointObject(Handle<BreakPointInfo> info,
10632 Handle<Object> break_point_object);
Ben Murdoch097c5b22016-05-18 11:27:45 +010010633 // Get the number of break points for this code offset.
Steve Blocka7e24c12009-10-30 11:49:00 +000010634 int GetBreakPointCount();
10635
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010636 DECLARE_CAST(BreakPointInfo)
Steve Blocka7e24c12009-10-30 11:49:00 +000010637
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010638 // Dispatched behavior.
10639 DECLARE_PRINTER(BreakPointInfo)
10640 DECLARE_VERIFIER(BreakPointInfo)
Steve Blocka7e24c12009-10-30 11:49:00 +000010641
Ben Murdoch097c5b22016-05-18 11:27:45 +010010642 static const int kCodeOffsetIndex = Struct::kHeaderSize;
10643 static const int kSourcePositionIndex = kCodeOffsetIndex + kPointerSize;
Steve Blocka7e24c12009-10-30 11:49:00 +000010644 static const int kStatementPositionIndex =
10645 kSourcePositionIndex + kPointerSize;
10646 static const int kBreakPointObjectsIndex =
10647 kStatementPositionIndex + kPointerSize;
10648 static const int kSize = kBreakPointObjectsIndex + kPointerSize;
10649
10650 private:
10651 DISALLOW_IMPLICIT_CONSTRUCTORS(BreakPointInfo);
10652};
Steve Blocka7e24c12009-10-30 11:49:00 +000010653
10654
10655#undef DECL_BOOLEAN_ACCESSORS
10656#undef DECL_ACCESSORS
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010657#undef DECLARE_CAST
10658#undef DECLARE_VERIFIER
Steve Blocka7e24c12009-10-30 11:49:00 +000010659
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010660#define VISITOR_SYNCHRONIZATION_TAGS_LIST(V) \
10661 V(kStringTable, "string_table", "(Internalized strings)") \
Ben Murdoch3ef787d2012-04-12 10:51:47 +010010662 V(kExternalStringsTable, "external_strings_table", "(External strings)") \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010663 V(kStrongRootList, "strong_root_list", "(Strong roots)") \
10664 V(kSmiRootList, "smi_root_list", "(Smi roots)") \
10665 V(kBootstrapper, "bootstrapper", "(Bootstrapper)") \
10666 V(kTop, "top", "(Isolate)") \
10667 V(kRelocatable, "relocatable", "(Relocatable)") \
10668 V(kDebug, "debug", "(Debugger)") \
10669 V(kCompilationCache, "compilationcache", "(Compilation cache)") \
10670 V(kHandleScope, "handlescope", "(Handle scope)") \
Ben Murdoch097c5b22016-05-18 11:27:45 +010010671 V(kDispatchTable, "dispatchtable", "(Dispatch table)") \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010672 V(kBuiltins, "builtins", "(Builtins)") \
10673 V(kGlobalHandles, "globalhandles", "(Global handles)") \
10674 V(kEternalHandles, "eternalhandles", "(Eternal handles)") \
10675 V(kThreadManager, "threadmanager", "(Thread manager)") \
10676 V(kStrongRoots, "strong roots", "(Strong roots)") \
Ben Murdoch3ef787d2012-04-12 10:51:47 +010010677 V(kExtensions, "Extensions", "(Extensions)")
10678
10679class VisitorSynchronization : public AllStatic {
10680 public:
10681#define DECLARE_ENUM(enum_item, ignore1, ignore2) enum_item,
10682 enum SyncTag {
10683 VISITOR_SYNCHRONIZATION_TAGS_LIST(DECLARE_ENUM)
10684 kNumberOfSyncTags
10685 };
10686#undef DECLARE_ENUM
10687
10688 static const char* const kTags[kNumberOfSyncTags];
10689 static const char* const kTagNames[kNumberOfSyncTags];
10690};
Steve Blocka7e24c12009-10-30 11:49:00 +000010691
10692// Abstract base class for visiting, and optionally modifying, the
10693// pointers contained in Objects. Used in GC and serialization/deserialization.
10694class ObjectVisitor BASE_EMBEDDED {
10695 public:
10696 virtual ~ObjectVisitor() {}
10697
10698 // Visits a contiguous arrays of pointers in the half-open range
10699 // [start, end). Any or all of the values may be modified on return.
10700 virtual void VisitPointers(Object** start, Object** end) = 0;
10701
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010702 // Handy shorthand for visiting a single pointer.
10703 virtual void VisitPointer(Object** p) { VisitPointers(p, p + 1); }
10704
10705 // Visit weak next_code_link in Code object.
10706 virtual void VisitNextCodeLink(Object** p) { VisitPointers(p, p + 1); }
10707
Steve Blocka7e24c12009-10-30 11:49:00 +000010708 // To allow lazy clearing of inline caches the visitor has
10709 // a rich interface for iterating over Code objects..
10710
10711 // Visits a code target in the instruction stream.
10712 virtual void VisitCodeTarget(RelocInfo* rinfo);
10713
Steve Block791712a2010-08-27 10:21:07 +010010714 // Visits a code entry in a JS function.
10715 virtual void VisitCodeEntry(Address entry_address);
10716
Ben Murdochb0fe1622011-05-05 13:52:32 +010010717 // Visits a global property cell reference in the instruction stream.
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010718 virtual void VisitCell(RelocInfo* rinfo);
Ben Murdochb0fe1622011-05-05 13:52:32 +010010719
Steve Blocka7e24c12009-10-30 11:49:00 +000010720 // Visits a runtime entry in the instruction stream.
10721 virtual void VisitRuntimeEntry(RelocInfo* rinfo) {}
10722
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010723 // Visits the resource of an one-byte or two-byte string.
10724 virtual void VisitExternalOneByteString(
10725 v8::String::ExternalOneByteStringResource** resource) {}
Steve Blockd0582a62009-12-15 09:54:21 +000010726 virtual void VisitExternalTwoByteString(
10727 v8::String::ExternalStringResource** resource) {}
10728
Steve Blocka7e24c12009-10-30 11:49:00 +000010729 // Visits a debug call target in the instruction stream.
10730 virtual void VisitDebugTarget(RelocInfo* rinfo);
10731
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010732 // Visits the byte sequence in a function's prologue that contains information
10733 // about the code's age.
10734 virtual void VisitCodeAgeSequence(RelocInfo* rinfo);
Steve Blocka7e24c12009-10-30 11:49:00 +000010735
Ben Murdoch3ef787d2012-04-12 10:51:47 +010010736 // Visit pointer embedded into a code object.
10737 virtual void VisitEmbeddedPointer(RelocInfo* rinfo);
10738
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010739 // Visits an external reference embedded into a code object.
Ben Murdoch3ef787d2012-04-12 10:51:47 +010010740 virtual void VisitExternalReference(RelocInfo* rinfo);
10741
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010742 // Visits an external reference.
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010743 virtual void VisitExternalReference(Address* p) {}
Steve Blocka7e24c12009-10-30 11:49:00 +000010744
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010745 // Visits an (encoded) internal reference.
10746 virtual void VisitInternalReference(RelocInfo* rinfo) {}
10747
Steve Block44f0eee2011-05-26 01:26:41 +010010748 // Visits a handle that has an embedder-assigned class ID.
10749 virtual void VisitEmbedderReference(Object** p, uint16_t class_id) {}
10750
Steve Blocka7e24c12009-10-30 11:49:00 +000010751 // Intended for serialization/deserialization checking: insert, or
10752 // check for the presence of, a tag at this position in the stream.
Ben Murdoch3ef787d2012-04-12 10:51:47 +010010753 // Also used for marking up GC roots in heap snapshots.
10754 virtual void Synchronize(VisitorSynchronization::SyncTag tag) {}
Steve Blocka7e24c12009-10-30 11:49:00 +000010755};
10756
10757
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010758// BooleanBit is a helper class for setting and getting a bit in an integer.
Steve Blocka7e24c12009-10-30 11:49:00 +000010759class BooleanBit : public AllStatic {
10760 public:
Steve Blocka7e24c12009-10-30 11:49:00 +000010761 static inline bool get(int value, int bit_position) {
10762 return (value & (1 << bit_position)) != 0;
10763 }
10764
Steve Blocka7e24c12009-10-30 11:49:00 +000010765 static inline int set(int value, int bit_position, bool v) {
10766 if (v) {
10767 value |= (1 << bit_position);
10768 } else {
10769 value &= ~(1 << bit_position);
10770 }
10771 return value;
10772 }
10773};
10774
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010775
10776} // NOLINT, false-positive due to second-order macros.
10777} // NOLINT, false-positive due to second-order macros.
Steve Blocka7e24c12009-10-30 11:49:00 +000010778
10779#endif // V8_OBJECTS_H_