blob: e37b9bdb1d8d195d92da7c60aed018a13b8255ba [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) \
Ben Murdoch61f157c2016-09-16 13:49:30 +0100418 V(JS_ARGUMENTS_TYPE) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000419 V(JS_CONTEXT_EXTENSION_OBJECT_TYPE) \
420 V(JS_GENERATOR_OBJECT_TYPE) \
421 V(JS_MODULE_TYPE) \
422 V(JS_GLOBAL_OBJECT_TYPE) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000423 V(JS_GLOBAL_PROXY_TYPE) \
Ben Murdochc5610432016-08-08 18:44:38 +0100424 V(JS_API_OBJECT_TYPE) \
Ben Murdochda12d292016-06-02 14:46:10 +0100425 V(JS_SPECIAL_API_OBJECT_TYPE) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000426 V(JS_ARRAY_TYPE) \
427 V(JS_ARRAY_BUFFER_TYPE) \
428 V(JS_TYPED_ARRAY_TYPE) \
429 V(JS_DATA_VIEW_TYPE) \
430 V(JS_PROXY_TYPE) \
431 V(JS_SET_TYPE) \
432 V(JS_MAP_TYPE) \
433 V(JS_SET_ITERATOR_TYPE) \
434 V(JS_MAP_ITERATOR_TYPE) \
435 V(JS_WEAK_MAP_TYPE) \
436 V(JS_WEAK_SET_TYPE) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000437 V(JS_PROMISE_TYPE) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000438 V(JS_REGEXP_TYPE) \
Ben Murdoch61f157c2016-09-16 13:49:30 +0100439 V(JS_ERROR_TYPE) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000440 \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000441 V(JS_BOUND_FUNCTION_TYPE) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000442 V(JS_FUNCTION_TYPE) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000443 V(DEBUG_INFO_TYPE) \
Steve Blocka7e24c12009-10-30 11:49:00 +0000444 V(BREAK_POINT_INFO_TYPE)
Steve Blocka7e24c12009-10-30 11:49:00 +0000445
Steve Blocka7e24c12009-10-30 11:49:00 +0000446// Since string types are not consecutive, this macro is used to
447// iterate over them.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000448#define STRING_TYPE_LIST(V) \
449 V(STRING_TYPE, kVariableSizeSentinel, string, String) \
450 V(ONE_BYTE_STRING_TYPE, kVariableSizeSentinel, one_byte_string, \
451 OneByteString) \
452 V(CONS_STRING_TYPE, ConsString::kSize, cons_string, ConsString) \
453 V(CONS_ONE_BYTE_STRING_TYPE, ConsString::kSize, cons_one_byte_string, \
454 ConsOneByteString) \
455 V(SLICED_STRING_TYPE, SlicedString::kSize, sliced_string, SlicedString) \
456 V(SLICED_ONE_BYTE_STRING_TYPE, SlicedString::kSize, sliced_one_byte_string, \
457 SlicedOneByteString) \
458 V(EXTERNAL_STRING_TYPE, ExternalTwoByteString::kSize, external_string, \
459 ExternalString) \
460 V(EXTERNAL_ONE_BYTE_STRING_TYPE, ExternalOneByteString::kSize, \
461 external_one_byte_string, ExternalOneByteString) \
462 V(EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE, ExternalTwoByteString::kSize, \
463 external_string_with_one_byte_data, ExternalStringWithOneByteData) \
464 V(SHORT_EXTERNAL_STRING_TYPE, ExternalTwoByteString::kShortSize, \
465 short_external_string, ShortExternalString) \
466 V(SHORT_EXTERNAL_ONE_BYTE_STRING_TYPE, ExternalOneByteString::kShortSize, \
467 short_external_one_byte_string, ShortExternalOneByteString) \
468 V(SHORT_EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE, \
469 ExternalTwoByteString::kShortSize, \
470 short_external_string_with_one_byte_data, \
471 ShortExternalStringWithOneByteData) \
472 \
473 V(INTERNALIZED_STRING_TYPE, kVariableSizeSentinel, internalized_string, \
474 InternalizedString) \
475 V(ONE_BYTE_INTERNALIZED_STRING_TYPE, kVariableSizeSentinel, \
476 one_byte_internalized_string, OneByteInternalizedString) \
477 V(EXTERNAL_INTERNALIZED_STRING_TYPE, ExternalTwoByteString::kSize, \
478 external_internalized_string, ExternalInternalizedString) \
479 V(EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE, ExternalOneByteString::kSize, \
480 external_one_byte_internalized_string, ExternalOneByteInternalizedString) \
481 V(EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE, \
482 ExternalTwoByteString::kSize, \
483 external_internalized_string_with_one_byte_data, \
484 ExternalInternalizedStringWithOneByteData) \
485 V(SHORT_EXTERNAL_INTERNALIZED_STRING_TYPE, \
486 ExternalTwoByteString::kShortSize, short_external_internalized_string, \
487 ShortExternalInternalizedString) \
488 V(SHORT_EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE, \
489 ExternalOneByteString::kShortSize, \
490 short_external_one_byte_internalized_string, \
491 ShortExternalOneByteInternalizedString) \
492 V(SHORT_EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE, \
493 ExternalTwoByteString::kShortSize, \
494 short_external_internalized_string_with_one_byte_data, \
495 ShortExternalInternalizedStringWithOneByteData)
Steve Blocka7e24c12009-10-30 11:49:00 +0000496
497// A struct is a simple object a set of object-valued fields. Including an
498// object type in this causes the compiler to generate most of the boilerplate
499// code for the class including allocation and garbage collection routines,
500// casts and predicates. All you need to define is the class, methods and
501// object verification routines. Easy, no?
502//
503// Note that for subtle reasons related to the ordering or numerical values of
504// type tags, elements in this list have to be added to the INSTANCE_TYPE_LIST
505// manually.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000506#define STRUCT_LIST(V) \
507 V(BOX, Box, box) \
Ben Murdoch097c5b22016-05-18 11:27:45 +0100508 V(ACCESSOR_INFO, AccessorInfo, accessor_info) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000509 V(ACCESSOR_PAIR, AccessorPair, accessor_pair) \
510 V(ACCESS_CHECK_INFO, AccessCheckInfo, access_check_info) \
511 V(INTERCEPTOR_INFO, InterceptorInfo, interceptor_info) \
512 V(CALL_HANDLER_INFO, CallHandlerInfo, call_handler_info) \
513 V(FUNCTION_TEMPLATE_INFO, FunctionTemplateInfo, function_template_info) \
514 V(OBJECT_TEMPLATE_INFO, ObjectTemplateInfo, object_template_info) \
515 V(SCRIPT, Script, script) \
516 V(ALLOCATION_SITE, AllocationSite, allocation_site) \
517 V(ALLOCATION_MEMENTO, AllocationMemento, allocation_memento) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000518 V(TYPE_FEEDBACK_INFO, TypeFeedbackInfo, type_feedback_info) \
519 V(ALIASED_ARGUMENTS_ENTRY, AliasedArgumentsEntry, aliased_arguments_entry) \
520 V(DEBUG_INFO, DebugInfo, debug_info) \
521 V(BREAK_POINT_INFO, BreakPointInfo, break_point_info) \
522 V(PROTOTYPE_INFO, PrototypeInfo, prototype_info) \
523 V(SLOPPY_BLOCK_WITH_EVAL_CONTEXT_EXTENSION, \
524 SloppyBlockWithEvalContextExtension, \
525 sloppy_block_with_eval_context_extension)
Steve Blocka7e24c12009-10-30 11:49:00 +0000526
527// We use the full 8 bits of the instance_type field to encode heap object
528// instance types. The high-order bit (bit 7) is set if the object is not a
529// string, and cleared if it is a string.
530const uint32_t kIsNotStringMask = 0x80;
531const uint32_t kStringTag = 0x0;
532const uint32_t kNotStringTag = 0x80;
533
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000534// Bit 6 indicates that the object is an internalized string (if set) or not.
535// Bit 7 has to be clear as well.
536const uint32_t kIsNotInternalizedMask = 0x40;
537const uint32_t kNotInternalizedTag = 0x40;
538const uint32_t kInternalizedTag = 0x0;
Steve Blocka7e24c12009-10-30 11:49:00 +0000539
Steve Blocka7e24c12009-10-30 11:49:00 +0000540// If bit 7 is clear then bit 2 indicates whether the string consists of
541// two-byte characters or one-byte characters.
542const uint32_t kStringEncodingMask = 0x4;
543const uint32_t kTwoByteStringTag = 0x0;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000544const uint32_t kOneByteStringTag = 0x4;
Steve Blocka7e24c12009-10-30 11:49:00 +0000545
546// If bit 7 is clear, the low-order 2 bits indicate the representation
547// of the string.
548const uint32_t kStringRepresentationMask = 0x03;
549enum StringRepresentationTag {
550 kSeqStringTag = 0x0,
551 kConsStringTag = 0x1,
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000552 kExternalStringTag = 0x2,
553 kSlicedStringTag = 0x3
Steve Blocka7e24c12009-10-30 11:49:00 +0000554};
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000555const uint32_t kIsIndirectStringMask = 0x1;
556const uint32_t kIsIndirectStringTag = 0x1;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000557STATIC_ASSERT((kSeqStringTag & kIsIndirectStringMask) == 0); // NOLINT
558STATIC_ASSERT((kExternalStringTag & kIsIndirectStringMask) == 0); // NOLINT
559STATIC_ASSERT((kConsStringTag &
560 kIsIndirectStringMask) == kIsIndirectStringTag); // NOLINT
561STATIC_ASSERT((kSlicedStringTag &
562 kIsIndirectStringMask) == kIsIndirectStringTag); // NOLINT
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000563
564// Use this mask to distinguish between cons and slice only after making
565// sure that the string is one of the two (an indirect string).
566const uint32_t kSlicedNotConsMask = kSlicedStringTag & ~kConsStringTag;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000567STATIC_ASSERT(IS_POWER_OF_TWO(kSlicedNotConsMask));
Steve Blocka7e24c12009-10-30 11:49:00 +0000568
Kristian Monsen9dcf7e22010-06-28 14:14:28 +0100569// If bit 7 is clear, then bit 3 indicates whether this two-byte
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000570// string actually contains one byte data.
571const uint32_t kOneByteDataHintMask = 0x08;
572const uint32_t kOneByteDataHintTag = 0x08;
Kristian Monsen9dcf7e22010-06-28 14:14:28 +0100573
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100574// If bit 7 is clear and string representation indicates an external string,
575// then bit 4 indicates whether the data pointer is cached.
576const uint32_t kShortExternalStringMask = 0x10;
577const uint32_t kShortExternalStringTag = 0x10;
578
Steve Blocka7e24c12009-10-30 11:49:00 +0000579
580// A ConsString with an empty string as the right side is a candidate
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000581// for being shortcut by the garbage collector. We don't allocate any
582// non-flat internalized strings, so we do not shortcut them thereby
583// avoiding turning internalized strings into strings. The bit-masks
584// below contain the internalized bit as additional safety.
585// See heap.cc, mark-compact.cc and objects-visiting.cc.
Steve Blocka7e24c12009-10-30 11:49:00 +0000586const uint32_t kShortcutTypeMask =
587 kIsNotStringMask |
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000588 kIsNotInternalizedMask |
Steve Blocka7e24c12009-10-30 11:49:00 +0000589 kStringRepresentationMask;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000590const uint32_t kShortcutTypeTag = kConsStringTag | kNotInternalizedTag;
591
592static inline bool IsShortcutCandidate(int type) {
593 return ((type & kShortcutTypeMask) == kShortcutTypeTag);
594}
Steve Blocka7e24c12009-10-30 11:49:00 +0000595
Steve Blocka7e24c12009-10-30 11:49:00 +0000596enum InstanceType {
Leon Clarkee46be812010-01-19 14:06:41 +0000597 // String types.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000598 INTERNALIZED_STRING_TYPE = kTwoByteStringTag | kSeqStringTag |
599 kInternalizedTag, // FIRST_PRIMITIVE_TYPE
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000600 ONE_BYTE_INTERNALIZED_STRING_TYPE =
601 kOneByteStringTag | kSeqStringTag | kInternalizedTag,
602 EXTERNAL_INTERNALIZED_STRING_TYPE =
603 kTwoByteStringTag | kExternalStringTag | kInternalizedTag,
604 EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE =
605 kOneByteStringTag | kExternalStringTag | kInternalizedTag,
606 EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE =
607 EXTERNAL_INTERNALIZED_STRING_TYPE | kOneByteDataHintTag |
608 kInternalizedTag,
609 SHORT_EXTERNAL_INTERNALIZED_STRING_TYPE = EXTERNAL_INTERNALIZED_STRING_TYPE |
610 kShortExternalStringTag |
611 kInternalizedTag,
612 SHORT_EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE =
613 EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE | kShortExternalStringTag |
614 kInternalizedTag,
615 SHORT_EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE =
616 EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE |
617 kShortExternalStringTag | kInternalizedTag,
618 STRING_TYPE = INTERNALIZED_STRING_TYPE | kNotInternalizedTag,
619 ONE_BYTE_STRING_TYPE =
620 ONE_BYTE_INTERNALIZED_STRING_TYPE | kNotInternalizedTag,
621 CONS_STRING_TYPE = kTwoByteStringTag | kConsStringTag | kNotInternalizedTag,
622 CONS_ONE_BYTE_STRING_TYPE =
623 kOneByteStringTag | kConsStringTag | kNotInternalizedTag,
624 SLICED_STRING_TYPE =
625 kTwoByteStringTag | kSlicedStringTag | kNotInternalizedTag,
626 SLICED_ONE_BYTE_STRING_TYPE =
627 kOneByteStringTag | kSlicedStringTag | kNotInternalizedTag,
628 EXTERNAL_STRING_TYPE =
629 EXTERNAL_INTERNALIZED_STRING_TYPE | kNotInternalizedTag,
630 EXTERNAL_ONE_BYTE_STRING_TYPE =
631 EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE | kNotInternalizedTag,
632 EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE =
633 EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE |
634 kNotInternalizedTag,
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100635 SHORT_EXTERNAL_STRING_TYPE =
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000636 SHORT_EXTERNAL_INTERNALIZED_STRING_TYPE | kNotInternalizedTag,
637 SHORT_EXTERNAL_ONE_BYTE_STRING_TYPE =
638 SHORT_EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE | kNotInternalizedTag,
639 SHORT_EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE =
640 SHORT_EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE |
641 kNotInternalizedTag,
642
643 // Non-string names
644 SYMBOL_TYPE = kNotStringTag, // FIRST_NONSTRING_TYPE, LAST_NAME_TYPE
Steve Blocka7e24c12009-10-30 11:49:00 +0000645
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000646 // Other primitives (cannot contain non-map-word pointers to heap objects).
647 HEAP_NUMBER_TYPE,
648 SIMD128_VALUE_TYPE,
649 ODDBALL_TYPE, // LAST_PRIMITIVE_TYPE
650
Leon Clarkee46be812010-01-19 14:06:41 +0000651 // Objects allocated in their own spaces (never in new space).
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000652 MAP_TYPE,
Steve Blocka7e24c12009-10-30 11:49:00 +0000653 CODE_TYPE,
Leon Clarkee46be812010-01-19 14:06:41 +0000654
655 // "Data", objects that cannot contain non-map-word pointers to heap
656 // objects.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000657 MUTABLE_HEAP_NUMBER_TYPE,
Ben Murdoch257744e2011-11-30 15:57:28 +0000658 FOREIGN_TYPE,
Steve Blocka7e24c12009-10-30 11:49:00 +0000659 BYTE_ARRAY_TYPE,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000660 BYTECODE_ARRAY_TYPE,
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100661 FREE_SPACE_TYPE,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000662 FIXED_INT8_ARRAY_TYPE, // FIRST_FIXED_TYPED_ARRAY_TYPE
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000663 FIXED_UINT8_ARRAY_TYPE,
664 FIXED_INT16_ARRAY_TYPE,
665 FIXED_UINT16_ARRAY_TYPE,
666 FIXED_INT32_ARRAY_TYPE,
667 FIXED_UINT32_ARRAY_TYPE,
668 FIXED_FLOAT32_ARRAY_TYPE,
669 FIXED_FLOAT64_ARRAY_TYPE,
670 FIXED_UINT8_CLAMPED_ARRAY_TYPE, // LAST_FIXED_TYPED_ARRAY_TYPE
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000671 FIXED_DOUBLE_ARRAY_TYPE,
Leon Clarkee46be812010-01-19 14:06:41 +0000672 FILLER_TYPE, // LAST_DATA_TYPE
Steve Blocka7e24c12009-10-30 11:49:00 +0000673
Leon Clarkee46be812010-01-19 14:06:41 +0000674 // Structs.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100675 ACCESSOR_INFO_TYPE,
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100676 ACCESSOR_PAIR_TYPE,
Steve Blocka7e24c12009-10-30 11:49:00 +0000677 ACCESS_CHECK_INFO_TYPE,
678 INTERCEPTOR_INFO_TYPE,
Steve Blocka7e24c12009-10-30 11:49:00 +0000679 CALL_HANDLER_INFO_TYPE,
680 FUNCTION_TEMPLATE_INFO_TYPE,
681 OBJECT_TEMPLATE_INFO_TYPE,
682 SIGNATURE_INFO_TYPE,
683 TYPE_SWITCH_INFO_TYPE,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000684 ALLOCATION_SITE_TYPE,
685 ALLOCATION_MEMENTO_TYPE,
Leon Clarkee46be812010-01-19 14:06:41 +0000686 SCRIPT_TYPE,
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100687 TYPE_FEEDBACK_INFO_TYPE,
688 ALIASED_ARGUMENTS_ENTRY_TYPE,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000689 BOX_TYPE,
Steve Blocka7e24c12009-10-30 11:49:00 +0000690 DEBUG_INFO_TYPE,
691 BREAK_POINT_INFO_TYPE,
Leon Clarkee46be812010-01-19 14:06:41 +0000692 FIXED_ARRAY_TYPE,
693 SHARED_FUNCTION_INFO_TYPE,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000694 CELL_TYPE,
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400695 WEAK_CELL_TYPE,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000696 TRANSITION_ARRAY_TYPE,
697 PROPERTY_CELL_TYPE,
698 PROTOTYPE_INFO_TYPE,
699 SLOPPY_BLOCK_WITH_EVAL_CONTEXT_EXTENSION_TYPE,
Leon Clarkee46be812010-01-19 14:06:41 +0000700
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100701 // All the following types are subtypes of JSReceiver, which corresponds to
702 // objects in the JS sense. The first and the last type in this range are
703 // the two forms of function. This organization enables using the same
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000704 // compares for checking the JS_RECEIVER and the NONCALLABLE_JS_OBJECT range.
Ben Murdochda12d292016-06-02 14:46:10 +0100705 JS_PROXY_TYPE, // FIRST_JS_RECEIVER_TYPE
706 JS_GLOBAL_OBJECT_TYPE, // FIRST_JS_OBJECT_TYPE
707 JS_GLOBAL_PROXY_TYPE,
Ben Murdochc5610432016-08-08 18:44:38 +0100708 // Like JS_API_OBJECT_TYPE, but requires access checks and/or has
709 // interceptors.
Ben Murdochda12d292016-06-02 14:46:10 +0100710 JS_SPECIAL_API_OBJECT_TYPE, // LAST_SPECIAL_RECEIVER_TYPE
711 JS_VALUE_TYPE, // LAST_CUSTOM_ELEMENTS_RECEIVER
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000712 JS_MESSAGE_OBJECT_TYPE,
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100713 JS_DATE_TYPE,
Ben Murdochc5610432016-08-08 18:44:38 +0100714 // Like JS_OBJECT_TYPE, but created from API function.
715 JS_API_OBJECT_TYPE,
Steve Blocka7e24c12009-10-30 11:49:00 +0000716 JS_OBJECT_TYPE,
Ben Murdoch61f157c2016-09-16 13:49:30 +0100717 JS_ARGUMENTS_TYPE,
Steve Blocka7e24c12009-10-30 11:49:00 +0000718 JS_CONTEXT_EXTENSION_OBJECT_TYPE,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000719 JS_GENERATOR_OBJECT_TYPE,
720 JS_MODULE_TYPE,
Steve Blocka7e24c12009-10-30 11:49:00 +0000721 JS_ARRAY_TYPE,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000722 JS_ARRAY_BUFFER_TYPE,
723 JS_TYPED_ARRAY_TYPE,
724 JS_DATA_VIEW_TYPE,
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100725 JS_SET_TYPE,
726 JS_MAP_TYPE,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000727 JS_SET_ITERATOR_TYPE,
728 JS_MAP_ITERATOR_TYPE,
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000729 JS_WEAK_MAP_TYPE,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000730 JS_WEAK_SET_TYPE,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000731 JS_PROMISE_TYPE,
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100732 JS_REGEXP_TYPE,
Ben Murdoch61f157c2016-09-16 13:49:30 +0100733 JS_ERROR_TYPE,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000734 JS_BOUND_FUNCTION_TYPE,
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100735 JS_FUNCTION_TYPE, // LAST_JS_OBJECT_TYPE, LAST_JS_RECEIVER_TYPE
Steve Blocka7e24c12009-10-30 11:49:00 +0000736
737 // Pseudo-types
Steve Blocka7e24c12009-10-30 11:49:00 +0000738 FIRST_TYPE = 0x0,
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100739 LAST_TYPE = JS_FUNCTION_TYPE,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000740 FIRST_NAME_TYPE = FIRST_TYPE,
741 LAST_NAME_TYPE = SYMBOL_TYPE,
742 FIRST_UNIQUE_NAME_TYPE = INTERNALIZED_STRING_TYPE,
743 LAST_UNIQUE_NAME_TYPE = SYMBOL_TYPE,
744 FIRST_NONSTRING_TYPE = SYMBOL_TYPE,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000745 FIRST_PRIMITIVE_TYPE = FIRST_NAME_TYPE,
746 LAST_PRIMITIVE_TYPE = ODDBALL_TYPE,
747 FIRST_FUNCTION_TYPE = JS_BOUND_FUNCTION_TYPE,
748 LAST_FUNCTION_TYPE = JS_FUNCTION_TYPE,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000749 // Boundaries for testing for a fixed typed array.
750 FIRST_FIXED_TYPED_ARRAY_TYPE = FIXED_INT8_ARRAY_TYPE,
751 LAST_FIXED_TYPED_ARRAY_TYPE = FIXED_UINT8_CLAMPED_ARRAY_TYPE,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000752 // Boundary for promotion to old space.
Leon Clarkee46be812010-01-19 14:06:41 +0000753 LAST_DATA_TYPE = FILLER_TYPE,
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000754 // Boundary for objects represented as JSReceiver (i.e. JSObject or JSProxy).
755 // Note that there is no range for JSObject or JSProxy, since their subtypes
756 // are not continuous in this enum! The enum ranges instead reflect the
757 // external class names, where proxies are treated as either ordinary objects,
758 // or functions.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000759 FIRST_JS_RECEIVER_TYPE = JS_PROXY_TYPE,
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000760 LAST_JS_RECEIVER_TYPE = LAST_TYPE,
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100761 // Boundaries for testing the types represented as JSObject
Ben Murdochda12d292016-06-02 14:46:10 +0100762 FIRST_JS_OBJECT_TYPE = JS_GLOBAL_OBJECT_TYPE,
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100763 LAST_JS_OBJECT_TYPE = LAST_TYPE,
Ben Murdochda12d292016-06-02 14:46:10 +0100764 // Boundary for testing JSReceivers that need special property lookup handling
765 LAST_SPECIAL_RECEIVER_TYPE = JS_SPECIAL_API_OBJECT_TYPE,
766 // Boundary case for testing JSReceivers that may have elements while having
767 // an empty fixed array as elements backing store. This is true for string
768 // wrappers.
769 LAST_CUSTOM_ELEMENTS_RECEIVER = JS_VALUE_TYPE,
Steve Blocka7e24c12009-10-30 11:49:00 +0000770};
771
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000772STATIC_ASSERT(JS_OBJECT_TYPE == Internals::kJSObjectType);
Ben Murdochc5610432016-08-08 18:44:38 +0100773STATIC_ASSERT(JS_API_OBJECT_TYPE == Internals::kJSApiObjectType);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000774STATIC_ASSERT(FIRST_NONSTRING_TYPE == Internals::kFirstNonstringType);
775STATIC_ASSERT(ODDBALL_TYPE == Internals::kOddballType);
776STATIC_ASSERT(FOREIGN_TYPE == Internals::kForeignType);
777
778
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000779std::ostream& operator<<(std::ostream& os, InstanceType instance_type);
780
781
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000782#define FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(V) \
783 V(FAST_ELEMENTS_SUB_TYPE) \
784 V(DICTIONARY_ELEMENTS_SUB_TYPE) \
785 V(FAST_PROPERTIES_SUB_TYPE) \
786 V(DICTIONARY_PROPERTIES_SUB_TYPE) \
787 V(MAP_CODE_CACHE_SUB_TYPE) \
788 V(SCOPE_INFO_SUB_TYPE) \
789 V(STRING_TABLE_SUB_TYPE) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000790 V(DESCRIPTOR_ARRAY_SUB_TYPE)
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000791
792enum FixedArraySubInstanceType {
793#define DEFINE_FIXED_ARRAY_SUB_INSTANCE_TYPE(name) name,
794 FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(DEFINE_FIXED_ARRAY_SUB_INSTANCE_TYPE)
795#undef DEFINE_FIXED_ARRAY_SUB_INSTANCE_TYPE
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000796 LAST_FIXED_ARRAY_SUB_TYPE = DESCRIPTOR_ARRAY_SUB_TYPE
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000797};
Kristian Monsen9dcf7e22010-06-28 14:14:28 +0100798
799
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000800// TODO(bmeurer): Remove this in favor of the ComparisonResult below.
Steve Blocka7e24c12009-10-30 11:49:00 +0000801enum CompareResult {
802 LESS = -1,
803 EQUAL = 0,
804 GREATER = 1,
805
806 NOT_EQUAL = GREATER
807};
808
809
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000810// Result of an abstract relational comparison of x and y, implemented according
811// to ES6 section 7.2.11 Abstract Relational Comparison.
812enum class ComparisonResult {
813 kLessThan, // x < y
814 kEqual, // x = y
815 kGreaterThan, // x > y
816 kUndefined // at least one of x or y was undefined or NaN
817};
818
819
820#define DECL_BOOLEAN_ACCESSORS(name) \
821 inline bool name() const; \
822 inline void set_##name(bool value);
823
824#define DECL_INT_ACCESSORS(name) \
825 inline int name() const; \
826 inline void set_##name(int value);
Steve Blocka7e24c12009-10-30 11:49:00 +0000827
828
829#define DECL_ACCESSORS(name, type) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000830 inline type* name() const; \
Steve Blocka7e24c12009-10-30 11:49:00 +0000831 inline void set_##name(type* value, \
832 WriteBarrierMode mode = UPDATE_WRITE_BARRIER); \
833
834
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000835#define DECLARE_CAST(type) \
836 INLINE(static type* cast(Object* object)); \
837 INLINE(static const type* cast(const Object* object));
838
839
840class AccessorPair;
841class AllocationSite;
842class AllocationSiteCreationContext;
843class AllocationSiteUsageContext;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000844class Cell;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400845class ConsString;
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000846class ElementsAccessor;
847class FixedArrayBase;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000848class FunctionLiteral;
849class JSGlobalObject;
850class KeyAccumulator;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400851class LayoutDescriptor;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000852class LiteralsArray;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000853class LookupIterator;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100854class FieldType;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000855class ObjectHashTable;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400856class ObjectVisitor;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000857class PropertyCell;
858class PropertyDescriptor;
859class SafepointEntry;
860class SharedFunctionInfo;
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000861class StringStream;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000862class TypeFeedbackInfo;
Ben Murdoch61f157c2016-09-16 13:49:30 +0100863class TypeFeedbackMetadata;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000864class TypeFeedbackVector;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400865class WeakCell;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000866class TransitionArray;
867
Steve Blocka7e24c12009-10-30 11:49:00 +0000868
869// A template-ized version of the IsXXX functions.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000870template <class C> inline bool Is(Object* obj);
Steve Blocka7e24c12009-10-30 11:49:00 +0000871
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000872#ifdef VERIFY_HEAP
873#define DECLARE_VERIFIER(Name) void Name##Verify();
874#else
875#define DECLARE_VERIFIER(Name)
876#endif
Steve Block053d10c2011-06-13 19:13:29 +0100877
Ben Murdochb0fe1622011-05-05 13:52:32 +0100878#ifdef OBJECT_PRINT
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400879#define DECLARE_PRINTER(Name) void Name##Print(std::ostream& os); // NOLINT
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000880#else
881#define DECLARE_PRINTER(Name)
Ben Murdochb0fe1622011-05-05 13:52:32 +0100882#endif
Steve Blocka7e24c12009-10-30 11:49:00 +0000883
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000884#define OBJECT_TYPE_LIST(V) \
885 V(Smi) \
Ben Murdoch097c5b22016-05-18 11:27:45 +0100886 V(LayoutDescriptor) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000887 V(HeapObject) \
Ben Murdoch097c5b22016-05-18 11:27:45 +0100888 V(Primitive) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000889 V(Number)
Ben Murdochb8e0da22011-05-16 14:20:40 +0100890
Ben Murdoch61f157c2016-09-16 13:49:30 +0100891#define HEAP_OBJECT_TYPE_LIST(V) \
892 V(HeapNumber) \
893 V(MutableHeapNumber) \
894 V(Simd128Value) \
895 V(Float32x4) \
896 V(Int32x4) \
897 V(Uint32x4) \
898 V(Bool32x4) \
899 V(Int16x8) \
900 V(Uint16x8) \
901 V(Bool16x8) \
902 V(Int8x16) \
903 V(Uint8x16) \
904 V(Bool8x16) \
905 V(Name) \
906 V(UniqueName) \
907 V(String) \
908 V(SeqString) \
909 V(ExternalString) \
910 V(ConsString) \
911 V(SlicedString) \
912 V(ExternalTwoByteString) \
913 V(ExternalOneByteString) \
914 V(SeqTwoByteString) \
915 V(SeqOneByteString) \
916 V(InternalizedString) \
917 V(Symbol) \
918 \
919 V(FixedTypedArrayBase) \
920 V(FixedUint8Array) \
921 V(FixedInt8Array) \
922 V(FixedUint16Array) \
923 V(FixedInt16Array) \
924 V(FixedUint32Array) \
925 V(FixedInt32Array) \
926 V(FixedFloat32Array) \
927 V(FixedFloat64Array) \
928 V(FixedUint8ClampedArray) \
929 V(ByteArray) \
930 V(BytecodeArray) \
931 V(FreeSpace) \
932 V(JSReceiver) \
933 V(JSObject) \
934 V(JSContextExtensionObject) \
935 V(JSGeneratorObject) \
936 V(JSModule) \
937 V(Map) \
938 V(DescriptorArray) \
939 V(TransitionArray) \
940 V(LiteralsArray) \
941 V(TypeFeedbackMetadata) \
942 V(TypeFeedbackVector) \
943 V(DeoptimizationInputData) \
944 V(DeoptimizationOutputData) \
945 V(DependentCode) \
946 V(HandlerTable) \
947 V(FixedArray) \
948 V(FixedDoubleArray) \
949 V(WeakFixedArray) \
950 V(ArrayList) \
951 V(Context) \
952 V(ScriptContextTable) \
953 V(NativeContext) \
954 V(ScopeInfo) \
955 V(JSBoundFunction) \
956 V(JSFunction) \
957 V(Code) \
958 V(AbstractCode) \
959 V(Oddball) \
960 V(SharedFunctionInfo) \
961 V(JSValue) \
962 V(JSDate) \
963 V(JSMessageObject) \
964 V(StringWrapper) \
965 V(Foreign) \
966 V(Boolean) \
967 V(JSArray) \
968 V(JSArrayBuffer) \
969 V(JSArrayBufferView) \
970 V(JSTypedArray) \
971 V(JSDataView) \
972 V(JSProxy) \
973 V(JSError) \
974 V(JSPromise) \
975 V(JSSet) \
976 V(JSMap) \
977 V(JSSetIterator) \
978 V(JSMapIterator) \
979 V(JSWeakCollection) \
980 V(JSWeakMap) \
981 V(JSWeakSet) \
982 V(JSRegExp) \
983 V(HashTable) \
984 V(Dictionary) \
985 V(StringTable) \
986 V(StringSet) \
987 V(NormalizedMapCache) \
988 V(CompilationCacheTable) \
989 V(CodeCacheHashTable) \
990 V(MapCache) \
991 V(JSGlobalObject) \
992 V(JSGlobalProxy) \
993 V(Undetectable) \
994 V(AccessCheckNeeded) \
995 V(Callable) \
996 V(Function) \
997 V(Constructor) \
998 V(TemplateInfo) \
999 V(Filler) \
1000 V(FixedArrayBase) \
1001 V(External) \
1002 V(Struct) \
1003 V(Cell) \
1004 V(PropertyCell) \
1005 V(WeakCell) \
1006 V(ObjectHashTable) \
1007 V(WeakHashTable) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001008 V(OrderedHashTable)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001009
Ben Murdoch61f157c2016-09-16 13:49:30 +01001010#define ODDBALL_LIST(V) \
1011 V(Undefined, undefined_value) \
1012 V(Null, null_value) \
1013 V(TheHole, the_hole_value) \
1014 V(Exception, exception) \
1015 V(Uninitialized, uninitialized_value) \
1016 V(True, true_value) \
1017 V(False, false_value) \
1018 V(ArgumentsMarker, arguments_marker) \
1019 V(OptimizedOut, optimized_out) \
1020 V(StaleRegister, stale_register)
Ben Murdoch097c5b22016-05-18 11:27:45 +01001021
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001022// The element types selection for CreateListFromArrayLike.
1023enum class ElementTypes { kAll, kStringAndSymbol };
1024
Steve Blocka7e24c12009-10-30 11:49:00 +00001025// Object is the abstract superclass for all classes in the
1026// object hierarchy.
1027// Object does not use any virtual functions to avoid the
1028// allocation of the C++ vtable.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001029// Since both Smi and HeapObject are subclasses of Object no
Steve Blocka7e24c12009-10-30 11:49:00 +00001030// data members can be present in Object.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001031class Object {
Steve Blocka7e24c12009-10-30 11:49:00 +00001032 public:
1033 // Type testing.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001034 bool IsObject() const { return true; }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001035
Ben Murdoch61f157c2016-09-16 13:49:30 +01001036#define IS_TYPE_FUNCTION_DECL(Type) INLINE(bool Is##Type() const);
Ben Murdochb8e0da22011-05-16 14:20:40 +01001037 OBJECT_TYPE_LIST(IS_TYPE_FUNCTION_DECL)
1038 HEAP_OBJECT_TYPE_LIST(IS_TYPE_FUNCTION_DECL)
Ben Murdoch61f157c2016-09-16 13:49:30 +01001039#undef IS_TYPE_FUNCTION_DECL
1040#define IS_TYPE_FUNCTION_DECL(Type, Value) \
1041 INLINE(bool Is##Type(Isolate* isolate) const);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001042 ODDBALL_LIST(IS_TYPE_FUNCTION_DECL)
Ben Murdochb8e0da22011-05-16 14:20:40 +01001043#undef IS_TYPE_FUNCTION_DECL
Steve Blocka7e24c12009-10-30 11:49:00 +00001044
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001045 // A non-keyed store is of the form a.x = foo or a["x"] = foo whereas
1046 // a keyed store is of the form a[expression] = foo.
1047 enum StoreFromKeyed {
1048 MAY_BE_STORE_FROM_KEYED,
1049 CERTAINLY_NOT_STORE_FROM_KEYED
1050 };
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001051
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001052 enum ShouldThrow { THROW_ON_ERROR, DONT_THROW };
1053
1054#define RETURN_FAILURE(isolate, should_throw, call) \
1055 do { \
1056 if ((should_throw) == DONT_THROW) { \
1057 return Just(false); \
1058 } else { \
1059 isolate->Throw(*isolate->factory()->call); \
1060 return Nothing<bool>(); \
1061 } \
1062 } while (false)
1063
1064#define MAYBE_RETURN(call, value) \
1065 do { \
1066 if ((call).IsNothing()) return value; \
1067 } while (false)
1068
1069#define MAYBE_RETURN_NULL(call) MAYBE_RETURN(call, MaybeHandle<Object>())
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001070
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001071#define DECLARE_STRUCT_PREDICATE(NAME, Name, name) \
1072 INLINE(bool Is##Name() const);
Steve Blocka7e24c12009-10-30 11:49:00 +00001073 STRUCT_LIST(DECLARE_STRUCT_PREDICATE)
1074#undef DECLARE_STRUCT_PREDICATE
1075
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001076 // ES6, section 7.2.2 IsArray. NOT to be confused with %_IsArray.
1077 MUST_USE_RESULT static Maybe<bool> IsArray(Handle<Object> object);
1078
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001079 INLINE(bool IsNameDictionary() const);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001080 INLINE(bool IsGlobalDictionary() const);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001081 INLINE(bool IsSeededNumberDictionary() const);
1082 INLINE(bool IsUnseededNumberDictionary() const);
1083 INLINE(bool IsOrderedHashSet() const);
1084 INLINE(bool IsOrderedHashMap() const);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001085
Steve Blocka7e24c12009-10-30 11:49:00 +00001086 // Extract the number.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001087 inline double Number() const;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001088 INLINE(bool IsNaN() const);
1089 INLINE(bool IsMinusZero() const);
1090 bool ToInt32(int32_t* value);
Ben Murdochda12d292016-06-02 14:46:10 +01001091 inline bool ToUint32(uint32_t* value);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001092
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001093 inline Representation OptimalRepresentation();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001094
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001095 inline ElementsKind OptimalElementsKind();
1096
1097 inline bool FitsRepresentation(Representation representation);
1098
1099 // Checks whether two valid primitive encodings of a property name resolve to
1100 // the same logical property. E.g., the smi 1, the string "1" and the double
1101 // 1 all refer to the same property, so this helper will return true.
1102 inline bool KeyEquals(Object* other);
1103
1104 inline bool FilterKey(PropertyFilter filter);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001105
Ben Murdoch097c5b22016-05-18 11:27:45 +01001106 Handle<FieldType> OptimalType(Isolate* isolate,
1107 Representation representation);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001108
1109 inline static Handle<Object> NewStorageFor(Isolate* isolate,
1110 Handle<Object> object,
1111 Representation representation);
1112
1113 inline static Handle<Object> WrapForRead(Isolate* isolate,
1114 Handle<Object> object,
1115 Representation representation);
Steve Blocka7e24c12009-10-30 11:49:00 +00001116
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001117 // Returns true if the object is of the correct type to be used as a
1118 // implementation of a JSObject's elements.
1119 inline bool HasValidElements();
1120
Steve Blocka7e24c12009-10-30 11:49:00 +00001121 inline bool HasSpecificClassOf(String* name);
1122
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001123 bool BooleanValue(); // ECMA-262 9.2.
Steve Blocka7e24c12009-10-30 11:49:00 +00001124
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001125 // ES6 section 7.2.11 Abstract Relational Comparison
Ben Murdoch097c5b22016-05-18 11:27:45 +01001126 MUST_USE_RESULT static Maybe<ComparisonResult> Compare(Handle<Object> x,
1127 Handle<Object> y);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001128
1129 // ES6 section 7.2.12 Abstract Equality Comparison
1130 MUST_USE_RESULT static Maybe<bool> Equals(Handle<Object> x, Handle<Object> y);
1131
1132 // ES6 section 7.2.13 Strict Equality Comparison
1133 bool StrictEquals(Object* that);
1134
Steve Blocka7e24c12009-10-30 11:49:00 +00001135 // Convert to a JSObject if needed.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001136 // native_context is used when creating wrapper object.
Ben Murdoch097c5b22016-05-18 11:27:45 +01001137 MUST_USE_RESULT static inline MaybeHandle<JSReceiver> ToObject(
1138 Isolate* isolate, Handle<Object> object);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001139 MUST_USE_RESULT static MaybeHandle<JSReceiver> ToObject(
1140 Isolate* isolate, Handle<Object> object, Handle<Context> context);
Steve Blocka7e24c12009-10-30 11:49:00 +00001141
Ben Murdochda12d292016-06-02 14:46:10 +01001142 // ES6 section 9.2.1.2, OrdinaryCallBindThis for sloppy callee.
1143 MUST_USE_RESULT static MaybeHandle<JSReceiver> ConvertReceiver(
1144 Isolate* isolate, Handle<Object> object);
1145
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001146 // ES6 section 7.1.14 ToPropertyKey
Ben Murdochda12d292016-06-02 14:46:10 +01001147 MUST_USE_RESULT static inline MaybeHandle<Name> ToName(Isolate* isolate,
1148 Handle<Object> input);
Steve Blocka7e24c12009-10-30 11:49:00 +00001149
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001150 // ES6 section 7.1.1 ToPrimitive
1151 MUST_USE_RESULT static inline MaybeHandle<Object> ToPrimitive(
1152 Handle<Object> input, ToPrimitiveHint hint = ToPrimitiveHint::kDefault);
Steve Blocka7e24c12009-10-30 11:49:00 +00001153
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001154 // ES6 section 7.1.3 ToNumber
1155 MUST_USE_RESULT static MaybeHandle<Object> ToNumber(Handle<Object> input);
1156
1157 // ES6 section 7.1.4 ToInteger
1158 MUST_USE_RESULT static MaybeHandle<Object> ToInteger(Isolate* isolate,
1159 Handle<Object> input);
1160
1161 // ES6 section 7.1.5 ToInt32
1162 MUST_USE_RESULT static MaybeHandle<Object> ToInt32(Isolate* isolate,
1163 Handle<Object> input);
1164
1165 // ES6 section 7.1.6 ToUint32
1166 MUST_USE_RESULT static MaybeHandle<Object> ToUint32(Isolate* isolate,
1167 Handle<Object> input);
1168
1169 // ES6 section 7.1.12 ToString
1170 MUST_USE_RESULT static MaybeHandle<String> ToString(Isolate* isolate,
1171 Handle<Object> input);
1172
Ben Murdochc5610432016-08-08 18:44:38 +01001173 // ES6 section 7.1.14 ToPropertyKey
1174 MUST_USE_RESULT static MaybeHandle<Object> ToPropertyKey(
1175 Isolate* isolate, Handle<Object> value);
1176
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001177 // ES6 section 7.1.15 ToLength
1178 MUST_USE_RESULT static MaybeHandle<Object> ToLength(Isolate* isolate,
1179 Handle<Object> input);
1180
1181 // ES6 section 7.3.9 GetMethod
1182 MUST_USE_RESULT static MaybeHandle<Object> GetMethod(
1183 Handle<JSReceiver> receiver, Handle<Name> name);
1184
1185 // ES6 section 7.3.17 CreateListFromArrayLike
1186 MUST_USE_RESULT static MaybeHandle<FixedArray> CreateListFromArrayLike(
1187 Isolate* isolate, Handle<Object> object, ElementTypes element_types);
1188
Ben Murdoch61f157c2016-09-16 13:49:30 +01001189 // Get length property and apply ToLength.
1190 MUST_USE_RESULT static MaybeHandle<Object> GetLengthFromArrayLike(
1191 Isolate* isolate, Handle<Object> object);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001192
1193 // ES6 section 12.5.6 The typeof Operator
1194 static Handle<String> TypeOf(Isolate* isolate, Handle<Object> object);
1195
1196 // ES6 section 12.6 Multiplicative Operators
Ben Murdoch097c5b22016-05-18 11:27:45 +01001197 MUST_USE_RESULT static MaybeHandle<Object> Multiply(Isolate* isolate,
1198 Handle<Object> lhs,
1199 Handle<Object> rhs);
1200 MUST_USE_RESULT static MaybeHandle<Object> Divide(Isolate* isolate,
1201 Handle<Object> lhs,
1202 Handle<Object> rhs);
1203 MUST_USE_RESULT static MaybeHandle<Object> Modulus(Isolate* isolate,
1204 Handle<Object> lhs,
1205 Handle<Object> rhs);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001206
1207 // ES6 section 12.7 Additive Operators
Ben Murdoch097c5b22016-05-18 11:27:45 +01001208 MUST_USE_RESULT static MaybeHandle<Object> Add(Isolate* isolate,
1209 Handle<Object> lhs,
1210 Handle<Object> rhs);
1211 MUST_USE_RESULT static MaybeHandle<Object> Subtract(Isolate* isolate,
1212 Handle<Object> lhs,
1213 Handle<Object> rhs);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001214
1215 // ES6 section 12.8 Bitwise Shift Operators
Ben Murdoch097c5b22016-05-18 11:27:45 +01001216 MUST_USE_RESULT static MaybeHandle<Object> ShiftLeft(Isolate* isolate,
1217 Handle<Object> lhs,
1218 Handle<Object> rhs);
1219 MUST_USE_RESULT static MaybeHandle<Object> ShiftRight(Isolate* isolate,
1220 Handle<Object> lhs,
1221 Handle<Object> rhs);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001222 MUST_USE_RESULT static MaybeHandle<Object> ShiftRightLogical(
Ben Murdoch097c5b22016-05-18 11:27:45 +01001223 Isolate* isolate, Handle<Object> lhs, Handle<Object> rhs);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001224
1225 // ES6 section 12.9 Relational Operators
Ben Murdoch097c5b22016-05-18 11:27:45 +01001226 MUST_USE_RESULT static inline Maybe<bool> GreaterThan(Handle<Object> x,
1227 Handle<Object> y);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001228 MUST_USE_RESULT static inline Maybe<bool> GreaterThanOrEqual(
Ben Murdoch097c5b22016-05-18 11:27:45 +01001229 Handle<Object> x, Handle<Object> y);
1230 MUST_USE_RESULT static inline Maybe<bool> LessThan(Handle<Object> x,
1231 Handle<Object> y);
1232 MUST_USE_RESULT static inline Maybe<bool> LessThanOrEqual(Handle<Object> x,
1233 Handle<Object> y);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001234
1235 // ES6 section 12.11 Binary Bitwise Operators
Ben Murdoch097c5b22016-05-18 11:27:45 +01001236 MUST_USE_RESULT static MaybeHandle<Object> BitwiseAnd(Isolate* isolate,
1237 Handle<Object> lhs,
1238 Handle<Object> rhs);
1239 MUST_USE_RESULT static MaybeHandle<Object> BitwiseOr(Isolate* isolate,
1240 Handle<Object> lhs,
1241 Handle<Object> rhs);
1242 MUST_USE_RESULT static MaybeHandle<Object> BitwiseXor(Isolate* isolate,
1243 Handle<Object> lhs,
1244 Handle<Object> rhs);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001245
Ben Murdochc5610432016-08-08 18:44:38 +01001246 // ES6 section 7.3.19 OrdinaryHasInstance (C, O).
1247 MUST_USE_RESULT static MaybeHandle<Object> OrdinaryHasInstance(
1248 Isolate* isolate, Handle<Object> callable, Handle<Object> object);
1249
1250 // ES6 section 12.10.4 Runtime Semantics: InstanceofOperator(O, C)
1251 MUST_USE_RESULT static MaybeHandle<Object> InstanceOf(
1252 Isolate* isolate, Handle<Object> object, Handle<Object> callable);
1253
Ben Murdoch097c5b22016-05-18 11:27:45 +01001254 MUST_USE_RESULT static MaybeHandle<Object> GetProperty(LookupIterator* it);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001255
1256 // ES6 [[Set]] (when passed DONT_THROW)
1257 // Invariants for this and related functions (unless stated otherwise):
1258 // 1) When the result is Nothing, an exception is pending.
1259 // 2) When passed THROW_ON_ERROR, the result is never Just(false).
1260 // In some cases, an exception is thrown regardless of the ShouldThrow
1261 // argument. These cases are either in accordance with the spec or not
1262 // covered by it (eg., concerning API callbacks).
1263 MUST_USE_RESULT static Maybe<bool> SetProperty(LookupIterator* it,
1264 Handle<Object> value,
1265 LanguageMode language_mode,
1266 StoreFromKeyed store_mode);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001267 MUST_USE_RESULT static MaybeHandle<Object> SetProperty(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001268 Handle<Object> object, Handle<Name> name, Handle<Object> value,
1269 LanguageMode language_mode,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001270 StoreFromKeyed store_mode = MAY_BE_STORE_FROM_KEYED);
Ben Murdochda12d292016-06-02 14:46:10 +01001271 MUST_USE_RESULT static inline MaybeHandle<Object> SetPropertyOrElement(
1272 Handle<Object> object, Handle<Name> name, Handle<Object> value,
1273 LanguageMode language_mode,
1274 StoreFromKeyed store_mode = MAY_BE_STORE_FROM_KEYED);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001275
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001276 MUST_USE_RESULT static Maybe<bool> SetSuperProperty(
1277 LookupIterator* it, Handle<Object> value, LanguageMode language_mode,
1278 StoreFromKeyed store_mode);
1279
1280 MUST_USE_RESULT static MaybeHandle<Object> ReadAbsentProperty(
Ben Murdoch097c5b22016-05-18 11:27:45 +01001281 LookupIterator* it);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001282 MUST_USE_RESULT static MaybeHandle<Object> ReadAbsentProperty(
Ben Murdoch097c5b22016-05-18 11:27:45 +01001283 Isolate* isolate, Handle<Object> receiver, Handle<Object> name);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001284 MUST_USE_RESULT static Maybe<bool> CannotCreateProperty(
1285 Isolate* isolate, Handle<Object> receiver, Handle<Object> name,
1286 Handle<Object> value, ShouldThrow should_throw);
1287 MUST_USE_RESULT static Maybe<bool> WriteToReadOnlyProperty(
1288 LookupIterator* it, Handle<Object> value, ShouldThrow should_throw);
1289 MUST_USE_RESULT static Maybe<bool> WriteToReadOnlyProperty(
1290 Isolate* isolate, Handle<Object> receiver, Handle<Object> name,
1291 Handle<Object> value, ShouldThrow should_throw);
1292 MUST_USE_RESULT static Maybe<bool> RedefineIncompatibleProperty(
1293 Isolate* isolate, Handle<Object> name, Handle<Object> value,
1294 ShouldThrow should_throw);
1295 MUST_USE_RESULT static Maybe<bool> SetDataProperty(LookupIterator* it,
1296 Handle<Object> value);
1297 MUST_USE_RESULT static Maybe<bool> AddDataProperty(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001298 LookupIterator* it, Handle<Object> value, PropertyAttributes attributes,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001299 ShouldThrow should_throw, StoreFromKeyed store_mode);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001300 MUST_USE_RESULT static inline MaybeHandle<Object> GetPropertyOrElement(
Ben Murdoch097c5b22016-05-18 11:27:45 +01001301 Handle<Object> object, Handle<Name> name);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001302 MUST_USE_RESULT static inline MaybeHandle<Object> GetPropertyOrElement(
Ben Murdoch097c5b22016-05-18 11:27:45 +01001303 Handle<Object> receiver, Handle<Name> name, Handle<JSReceiver> holder);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001304 MUST_USE_RESULT static inline MaybeHandle<Object> GetProperty(
Ben Murdoch097c5b22016-05-18 11:27:45 +01001305 Handle<Object> object, Handle<Name> name);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001306
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001307 MUST_USE_RESULT static MaybeHandle<Object> GetPropertyWithAccessor(
Ben Murdoch097c5b22016-05-18 11:27:45 +01001308 LookupIterator* it);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001309 MUST_USE_RESULT static Maybe<bool> SetPropertyWithAccessor(
1310 LookupIterator* it, Handle<Object> value, ShouldThrow should_throw);
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001311
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001312 MUST_USE_RESULT static MaybeHandle<Object> GetPropertyWithDefinedGetter(
1313 Handle<Object> receiver,
1314 Handle<JSReceiver> getter);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001315 MUST_USE_RESULT static Maybe<bool> SetPropertyWithDefinedSetter(
1316 Handle<Object> receiver, Handle<JSReceiver> setter, Handle<Object> value,
1317 ShouldThrow should_throw);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001318
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001319 MUST_USE_RESULT static inline MaybeHandle<Object> GetElement(
Ben Murdoch097c5b22016-05-18 11:27:45 +01001320 Isolate* isolate, Handle<Object> object, uint32_t index);
Steve Blocka7e24c12009-10-30 11:49:00 +00001321
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001322 MUST_USE_RESULT static inline MaybeHandle<Object> SetElement(
1323 Isolate* isolate, Handle<Object> object, uint32_t index,
1324 Handle<Object> value, LanguageMode language_mode);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001325
1326 // Returns the permanent hash code associated with this object. May return
1327 // undefined if not yet created.
1328 Object* GetHash();
Steve Blocka7e24c12009-10-30 11:49:00 +00001329
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001330 // Returns the permanent hash code associated with this object depending on
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001331 // the actual object type. May create and store a hash code if needed and none
1332 // exists.
Ben Murdoch61f157c2016-09-16 13:49:30 +01001333 static Smi* GetOrCreateHash(Isolate* isolate, Handle<Object> object);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001334
1335 // Checks whether this object has the same value as the given one. This
1336 // function is implemented according to ES5, section 9.12 and can be used
1337 // to implement the Harmony "egal" function.
1338 bool SameValue(Object* other);
1339
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001340 // Checks whether this object has the same value as the given one.
1341 // +0 and -0 are treated equal. Everything else is the same as SameValue.
1342 // This function is implemented according to ES6, section 7.2.4 and is used
1343 // by ES6 Map and Set.
1344 bool SameValueZero(Object* other);
1345
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001346 // ES6 section 9.4.2.3 ArraySpeciesCreate (part of it)
1347 MUST_USE_RESULT static MaybeHandle<Object> ArraySpeciesConstructor(
1348 Isolate* isolate, Handle<Object> original_array);
1349
1350 // Tries to convert an object to an array length. Returns true and sets the
1351 // output parameter if it succeeds.
1352 inline bool ToArrayLength(uint32_t* index);
1353
1354 // Tries to convert an object to an array index. Returns true and sets the
1355 // output parameter if it succeeds. Equivalent to ToArrayLength, but does not
1356 // allow kMaxUInt32.
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01001357 inline bool ToArrayIndex(uint32_t* index);
1358
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001359 DECLARE_VERIFIER(Object)
1360#ifdef VERIFY_HEAP
Steve Blocka7e24c12009-10-30 11:49:00 +00001361 // Verify a pointer is a valid object pointer.
1362 static void VerifyPointer(Object* p);
1363#endif
1364
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001365 inline void VerifyApiCallResultType();
1366
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001367 // ES6 19.1.3.6 Object.prototype.toString
1368 MUST_USE_RESULT static MaybeHandle<String> ObjectProtoToString(
1369 Isolate* isolate, Handle<Object> object);
1370
Steve Blocka7e24c12009-10-30 11:49:00 +00001371 // Prints this object without details.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001372 void ShortPrint(FILE* out = stdout);
Steve Blocka7e24c12009-10-30 11:49:00 +00001373
1374 // Prints this object without details to a message accumulator.
1375 void ShortPrint(StringStream* accumulator);
1376
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001377 void ShortPrint(std::ostream& os); // NOLINT
1378
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001379 DECLARE_CAST(Object)
Steve Blocka7e24c12009-10-30 11:49:00 +00001380
1381 // Layout description.
1382 static const int kHeaderSize = 0; // Object does not take up any space.
1383
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001384#ifdef OBJECT_PRINT
1385 // For our gdb macros, we should perhaps change these in the future.
1386 void Print();
1387
1388 // Prints this object with details.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001389 void Print(std::ostream& os); // NOLINT
1390#else
1391 void Print() { ShortPrint(); }
1392 void Print(std::ostream& os) { ShortPrint(os); } // NOLINT
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001393#endif
1394
Steve Blocka7e24c12009-10-30 11:49:00 +00001395 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001396 friend class LookupIterator;
Ben Murdoch097c5b22016-05-18 11:27:45 +01001397 friend class StringStream;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001398
1399 // Return the map of the root of object's prototype chain.
1400 Map* GetRootMap(Isolate* isolate);
1401
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001402 // Helper for SetProperty and SetSuperProperty.
1403 // Return value is only meaningful if [found] is set to true on return.
1404 MUST_USE_RESULT static Maybe<bool> SetPropertyInternal(
1405 LookupIterator* it, Handle<Object> value, LanguageMode language_mode,
1406 StoreFromKeyed store_mode, bool* found);
1407
Ben Murdochda12d292016-06-02 14:46:10 +01001408 MUST_USE_RESULT static MaybeHandle<Name> ConvertToName(Isolate* isolate,
1409 Handle<Object> input);
1410
Steve Blocka7e24c12009-10-30 11:49:00 +00001411 DISALLOW_IMPLICIT_CONSTRUCTORS(Object);
1412};
1413
1414
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001415// In objects.h to be usable without objects-inl.h inclusion.
1416bool Object::IsSmi() const { return HAS_SMI_TAG(this); }
1417bool Object::IsHeapObject() const { return Internals::HasHeapObjectTag(this); }
1418
1419
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001420struct Brief {
1421 explicit Brief(const Object* const v) : value(v) {}
1422 const Object* value;
1423};
1424
1425
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001426std::ostream& operator<<(std::ostream& os, const Brief& v);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001427
1428
Steve Blocka7e24c12009-10-30 11:49:00 +00001429// Smi represents integer Numbers that can be stored in 31 bits.
1430// Smis are immediate which means they are NOT allocated in the heap.
Steve Blocka7e24c12009-10-30 11:49:00 +00001431// The this pointer has the following format: [31 bit signed int] 0
Steve Block3ce2e202009-11-05 08:53:23 +00001432// For long smis it has the following format:
1433// [32 bit signed int] [31 bits zero padding] 0
1434// Smi stands for small integer.
Steve Blocka7e24c12009-10-30 11:49:00 +00001435class Smi: public Object {
1436 public:
1437 // Returns the integer value.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001438 inline int value() const { return Internals::SmiValue(this); }
Steve Blocka7e24c12009-10-30 11:49:00 +00001439
1440 // Convert a value to a Smi object.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001441 static inline Smi* FromInt(int value) {
1442 DCHECK(Smi::IsValid(value));
1443 return reinterpret_cast<Smi*>(Internals::IntToSmi(value));
1444 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001445
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001446 static inline Smi* FromIntptr(intptr_t value) {
1447 DCHECK(Smi::IsValid(value));
1448 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
1449 return reinterpret_cast<Smi*>((value << smi_shift_bits) | kSmiTag);
1450 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001451
1452 // Returns whether value can be represented in a Smi.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001453 static inline bool IsValid(intptr_t value) {
1454 bool result = Internals::IsValidSmi(value);
1455 DCHECK_EQ(result, value >= kMinValue && value <= kMaxValue);
1456 return result;
1457 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001458
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001459 DECLARE_CAST(Smi)
Steve Blocka7e24c12009-10-30 11:49:00 +00001460
1461 // Dispatched behavior.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001462 void SmiPrint(std::ostream& os) const; // NOLINT
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001463 DECLARE_VERIFIER(Smi)
Steve Blocka7e24c12009-10-30 11:49:00 +00001464
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001465 static const int kMinValue =
1466 (static_cast<unsigned int>(-1)) << (kSmiValueSize - 1);
Steve Block3ce2e202009-11-05 08:53:23 +00001467 static const int kMaxValue = -(kMinValue + 1);
Steve Blocka7e24c12009-10-30 11:49:00 +00001468
1469 private:
1470 DISALLOW_IMPLICIT_CONSTRUCTORS(Smi);
1471};
1472
1473
Steve Blocka7e24c12009-10-30 11:49:00 +00001474// Heap objects typically have a map pointer in their first word. However,
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001475// during GC other data (e.g. mark bits, forwarding addresses) is sometimes
Steve Blocka7e24c12009-10-30 11:49:00 +00001476// encoded in the first word. The class MapWord is an abstraction of the
1477// value in a heap object's first word.
1478class MapWord BASE_EMBEDDED {
1479 public:
1480 // Normal state: the map word contains a map pointer.
1481
1482 // Create a map word from a map pointer.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001483 static inline MapWord FromMap(const Map* map);
Steve Blocka7e24c12009-10-30 11:49:00 +00001484
1485 // View this map word as a map pointer.
1486 inline Map* ToMap();
1487
1488
1489 // Scavenge collection: the map word of live objects in the from space
1490 // contains a forwarding address (a heap object pointer in the to space).
1491
1492 // True if this map word is a forwarding address for a scavenge
1493 // collection. Only valid during a scavenge collection (specifically,
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001494 // when all map words are heap object pointers, i.e. not during a full GC).
Ben Murdochc5610432016-08-08 18:44:38 +01001495 inline bool IsForwardingAddress() const;
Steve Blocka7e24c12009-10-30 11:49:00 +00001496
1497 // Create a map word from a forwarding address.
1498 static inline MapWord FromForwardingAddress(HeapObject* object);
1499
1500 // View this map word as a forwarding address.
1501 inline HeapObject* ToForwardingAddress();
1502
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001503 static inline MapWord FromRawValue(uintptr_t value) {
1504 return MapWord(value);
1505 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001506
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001507 inline uintptr_t ToRawValue() {
1508 return value_;
1509 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001510
1511 private:
1512 // HeapObject calls the private constructor and directly reads the value.
1513 friend class HeapObject;
1514
1515 explicit MapWord(uintptr_t value) : value_(value) {}
1516
1517 uintptr_t value_;
1518};
1519
1520
1521// HeapObject is the superclass for all classes describing heap allocated
1522// objects.
1523class HeapObject: public Object {
1524 public:
1525 // [map]: Contains a map which contains the object's reflective
1526 // information.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001527 inline Map* map() const;
Steve Blocka7e24c12009-10-30 11:49:00 +00001528 inline void set_map(Map* value);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001529 // The no-write-barrier version. This is OK if the object is white and in
1530 // new space, or if the value is an immortal immutable object, like the maps
1531 // of primitive (non-JS) objects like strings, heap numbers etc.
1532 inline void set_map_no_write_barrier(Map* value);
Steve Blocka7e24c12009-10-30 11:49:00 +00001533
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001534 // Get the map using acquire load.
1535 inline Map* synchronized_map();
1536 inline MapWord synchronized_map_word() const;
1537
1538 // Set the map using release store
1539 inline void synchronized_set_map(Map* value);
1540 inline void synchronized_set_map_no_write_barrier(Map* value);
1541 inline void synchronized_set_map_word(MapWord map_word);
1542
Steve Blocka7e24c12009-10-30 11:49:00 +00001543 // During garbage collection, the map word of a heap object does not
1544 // necessarily contain a map pointer.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001545 inline MapWord map_word() const;
Steve Blocka7e24c12009-10-30 11:49:00 +00001546 inline void set_map_word(MapWord map_word);
1547
Steve Block44f0eee2011-05-26 01:26:41 +01001548 // The Heap the object was allocated in. Used also to access Isolate.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001549 inline Heap* GetHeap() const;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001550
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001551 // Convenience method to get current isolate.
1552 inline Isolate* GetIsolate() const;
Steve Block44f0eee2011-05-26 01:26:41 +01001553
Ben Murdoch61f157c2016-09-16 13:49:30 +01001554#define IS_TYPE_FUNCTION_DECL(Type) INLINE(bool Is##Type() const);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001555 HEAP_OBJECT_TYPE_LIST(IS_TYPE_FUNCTION_DECL)
Ben Murdoch61f157c2016-09-16 13:49:30 +01001556#undef IS_TYPE_FUNCTION_DECL
1557
1558#define IS_TYPE_FUNCTION_DECL(Type, Value) \
1559 INLINE(bool Is##Type(Isolate* isolate) const);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001560 ODDBALL_LIST(IS_TYPE_FUNCTION_DECL)
1561#undef IS_TYPE_FUNCTION_DECL
Ben Murdoch61f157c2016-09-16 13:49:30 +01001562
Ben Murdoch097c5b22016-05-18 11:27:45 +01001563#define DECLARE_STRUCT_PREDICATE(NAME, Name, name) \
1564 INLINE(bool Is##Name() const);
1565 STRUCT_LIST(DECLARE_STRUCT_PREDICATE)
1566#undef DECLARE_STRUCT_PREDICATE
1567
Steve Blocka7e24c12009-10-30 11:49:00 +00001568 // Converts an address to a HeapObject pointer.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001569 static inline HeapObject* FromAddress(Address address) {
1570 DCHECK_TAG_ALIGNED(address);
1571 return reinterpret_cast<HeapObject*>(address + kHeapObjectTag);
1572 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001573
1574 // Returns the address of this HeapObject.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001575 inline Address address() {
1576 return reinterpret_cast<Address>(this) - kHeapObjectTag;
1577 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001578
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001579 // Iterates over pointers contained in the object (including the Map).
1580 // If it's not performance critical iteration use the non-templatized
1581 // version.
Steve Blocka7e24c12009-10-30 11:49:00 +00001582 void Iterate(ObjectVisitor* v);
1583
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001584 template <typename ObjectVisitor>
1585 inline void IterateFast(ObjectVisitor* v);
1586
Steve Blocka7e24c12009-10-30 11:49:00 +00001587 // Iterates over all pointers contained in the object except the
1588 // first map pointer. The object type is given in the first
1589 // parameter. This function does not access the map pointer in the
1590 // object, and so is safe to call while the map pointer is modified.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001591 // If it's not performance critical iteration use the non-templatized
1592 // version.
1593 void IterateBody(ObjectVisitor* v);
Steve Blocka7e24c12009-10-30 11:49:00 +00001594 void IterateBody(InstanceType type, int object_size, ObjectVisitor* v);
1595
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001596 template <typename ObjectVisitor>
1597 inline void IterateBodyFast(ObjectVisitor* v);
1598
1599 template <typename ObjectVisitor>
1600 inline void IterateBodyFast(InstanceType type, int object_size,
1601 ObjectVisitor* v);
1602
1603 // Returns true if the object contains a tagged value at given offset.
1604 // It is used for invalid slots filtering. If the offset points outside
1605 // of the object or to the map word, the result is UNDEFINED (!!!).
1606 bool IsValidSlot(int offset);
1607
Steve Blocka7e24c12009-10-30 11:49:00 +00001608 // Returns the heap object's size in bytes
1609 inline int Size();
1610
1611 // Given a heap object's map pointer, returns the heap size in bytes
1612 // Useful when the map pointer field is used for other purposes.
1613 // GC internal.
1614 inline int SizeFromMap(Map* map);
1615
Steve Blocka7e24c12009-10-30 11:49:00 +00001616 // Returns the field at offset in obj, as a read/write Object* reference.
1617 // Does no checking, and is safe to use during GC, while maps are invalid.
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01001618 // Does not invoke write barrier, so should only be assigned to
Steve Blocka7e24c12009-10-30 11:49:00 +00001619 // during marking GC.
1620 static inline Object** RawField(HeapObject* obj, int offset);
1621
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001622 // Adds the |code| object related to |name| to the code cache of this map. If
1623 // this map is a dictionary map that is shared, the map copied and installed
1624 // onto the object.
1625 static void UpdateMapCodeCache(Handle<HeapObject> object,
1626 Handle<Name> name,
1627 Handle<Code> code);
1628
1629 DECLARE_CAST(HeapObject)
Steve Blocka7e24c12009-10-30 11:49:00 +00001630
Leon Clarke4515c472010-02-03 11:58:03 +00001631 // Return the write barrier mode for this. Callers of this function
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001632 // must be able to present a reference to an DisallowHeapAllocation
Leon Clarke4515c472010-02-03 11:58:03 +00001633 // object as a sign that they are not going to use this function
1634 // from code that allocates and thus invalidates the returned write
1635 // barrier mode.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001636 inline WriteBarrierMode GetWriteBarrierMode(
1637 const DisallowHeapAllocation& promise);
Steve Blocka7e24c12009-10-30 11:49:00 +00001638
1639 // Dispatched behavior.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001640 void HeapObjectShortPrint(std::ostream& os); // NOLINT
Ben Murdochb0fe1622011-05-05 13:52:32 +01001641#ifdef OBJECT_PRINT
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001642 void PrintHeader(std::ostream& os, const char* id); // NOLINT
Ben Murdoch85b71792012-04-11 18:30:58 +01001643#endif
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001644 DECLARE_PRINTER(HeapObject)
1645 DECLARE_VERIFIER(HeapObject)
1646#ifdef VERIFY_HEAP
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001647 inline void VerifyObjectField(int offset);
1648 inline void VerifySmiField(int offset);
1649
Steve Blocka7e24c12009-10-30 11:49:00 +00001650 // Verify a pointer is a valid HeapObject pointer that points to object
1651 // areas in the heap.
1652 static void VerifyHeapPointer(Object* p);
1653#endif
1654
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001655 inline AllocationAlignment RequiredAlignment();
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001656
Steve Blocka7e24c12009-10-30 11:49:00 +00001657 // Layout description.
1658 // First field in a heap object is map.
1659 static const int kMapOffset = Object::kHeaderSize;
1660 static const int kHeaderSize = kMapOffset + kPointerSize;
1661
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001662 STATIC_ASSERT(kMapOffset == Internals::kHeapObjectMapOffset);
Steve Blocka7e24c12009-10-30 11:49:00 +00001663
Steve Blocka7e24c12009-10-30 11:49:00 +00001664 private:
1665 DISALLOW_IMPLICIT_CONSTRUCTORS(HeapObject);
1666};
1667
1668
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001669template <int start_offset, int end_offset, int size>
1670class FixedBodyDescriptor;
Iain Merrick75681382010-08-19 15:07:18 +01001671
1672
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001673template <int start_offset>
1674class FlexibleBodyDescriptor;
Iain Merrick75681382010-08-19 15:07:18 +01001675
Iain Merrick75681382010-08-19 15:07:18 +01001676
Steve Blocka7e24c12009-10-30 11:49:00 +00001677// The HeapNumber class describes heap allocated numbers that cannot be
1678// represented in a Smi (small integer)
1679class HeapNumber: public HeapObject {
1680 public:
1681 // [value]: number value.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001682 inline double value() const;
Steve Blocka7e24c12009-10-30 11:49:00 +00001683 inline void set_value(double value);
1684
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001685 DECLARE_CAST(HeapNumber)
Steve Blocka7e24c12009-10-30 11:49:00 +00001686
1687 // Dispatched behavior.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001688 bool HeapNumberBooleanValue();
1689
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001690 void HeapNumberPrint(std::ostream& os); // NOLINT
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001691 DECLARE_VERIFIER(HeapNumber)
Steve Blocka7e24c12009-10-30 11:49:00 +00001692
Steve Block6ded16b2010-05-10 14:33:55 +01001693 inline int get_exponent();
1694 inline int get_sign();
1695
Steve Blocka7e24c12009-10-30 11:49:00 +00001696 // Layout description.
1697 static const int kValueOffset = HeapObject::kHeaderSize;
1698 // IEEE doubles are two 32 bit words. The first is just mantissa, the second
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001699 // is a mixture of sign, exponent and mantissa. The offsets of two 32 bit
1700 // words within double numbers are endian dependent and they are set
1701 // accordingly.
1702#if defined(V8_TARGET_LITTLE_ENDIAN)
Steve Blocka7e24c12009-10-30 11:49:00 +00001703 static const int kMantissaOffset = kValueOffset;
1704 static const int kExponentOffset = kValueOffset + 4;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001705#elif defined(V8_TARGET_BIG_ENDIAN)
1706 static const int kMantissaOffset = kValueOffset + 4;
1707 static const int kExponentOffset = kValueOffset;
1708#else
1709#error Unknown byte ordering
1710#endif
Ben Murdoch8b112d22011-06-08 16:22:53 +01001711
Steve Blocka7e24c12009-10-30 11:49:00 +00001712 static const int kSize = kValueOffset + kDoubleSize;
Steve Blocka7e24c12009-10-30 11:49:00 +00001713 static const uint32_t kSignMask = 0x80000000u;
1714 static const uint32_t kExponentMask = 0x7ff00000u;
1715 static const uint32_t kMantissaMask = 0xfffffu;
Steve Block6ded16b2010-05-10 14:33:55 +01001716 static const int kMantissaBits = 52;
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01001717 static const int kExponentBits = 11;
Steve Blocka7e24c12009-10-30 11:49:00 +00001718 static const int kExponentBias = 1023;
1719 static const int kExponentShift = 20;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001720 static const int kInfinityOrNanExponent =
1721 (kExponentMask >> kExponentShift) - kExponentBias;
Steve Blocka7e24c12009-10-30 11:49:00 +00001722 static const int kMantissaBitsInTopWord = 20;
1723 static const int kNonMantissaBitsInTopWord = 12;
1724
1725 private:
1726 DISALLOW_IMPLICIT_CONSTRUCTORS(HeapNumber);
1727};
1728
1729
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001730// The Simd128Value class describes heap allocated 128 bit SIMD values.
1731class Simd128Value : public HeapObject {
1732 public:
1733 DECLARE_CAST(Simd128Value)
1734
1735 DECLARE_PRINTER(Simd128Value)
1736 DECLARE_VERIFIER(Simd128Value)
1737
1738 static Handle<String> ToString(Handle<Simd128Value> input);
1739
1740 // Equality operations.
1741 inline bool Equals(Simd128Value* that);
1742 static inline bool Equals(Handle<Simd128Value> one, Handle<Simd128Value> two);
1743
1744 // Checks that another instance is bit-wise equal.
1745 bool BitwiseEquals(const Simd128Value* other) const;
1746 // Computes a hash from the 128 bit value, viewed as 4 32-bit integers.
1747 uint32_t Hash() const;
1748 // Copies the 16 bytes of SIMD data to the destination address.
1749 void CopyBits(void* destination) const;
1750
1751 // Layout description.
1752 static const int kValueOffset = HeapObject::kHeaderSize;
1753 static const int kSize = kValueOffset + kSimd128Size;
1754
1755 private:
1756 DISALLOW_IMPLICIT_CONSTRUCTORS(Simd128Value);
1757};
1758
1759
1760// V has parameters (TYPE, Type, type, lane count, lane type)
1761#define SIMD128_TYPES(V) \
1762 V(FLOAT32X4, Float32x4, float32x4, 4, float) \
1763 V(INT32X4, Int32x4, int32x4, 4, int32_t) \
1764 V(UINT32X4, Uint32x4, uint32x4, 4, uint32_t) \
1765 V(BOOL32X4, Bool32x4, bool32x4, 4, bool) \
1766 V(INT16X8, Int16x8, int16x8, 8, int16_t) \
1767 V(UINT16X8, Uint16x8, uint16x8, 8, uint16_t) \
1768 V(BOOL16X8, Bool16x8, bool16x8, 8, bool) \
1769 V(INT8X16, Int8x16, int8x16, 16, int8_t) \
1770 V(UINT8X16, Uint8x16, uint8x16, 16, uint8_t) \
1771 V(BOOL8X16, Bool8x16, bool8x16, 16, bool)
1772
1773#define SIMD128_VALUE_CLASS(TYPE, Type, type, lane_count, lane_type) \
1774 class Type final : public Simd128Value { \
1775 public: \
1776 inline lane_type get_lane(int lane) const; \
1777 inline void set_lane(int lane, lane_type value); \
1778 \
1779 DECLARE_CAST(Type) \
1780 \
1781 DECLARE_PRINTER(Type) \
1782 \
1783 static Handle<String> ToString(Handle<Type> input); \
1784 \
1785 inline bool Equals(Type* that); \
1786 \
1787 private: \
1788 DISALLOW_IMPLICIT_CONSTRUCTORS(Type); \
1789 };
1790SIMD128_TYPES(SIMD128_VALUE_CLASS)
1791#undef SIMD128_VALUE_CLASS
1792
1793
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001794enum EnsureElementsMode {
1795 DONT_ALLOW_DOUBLE_ELEMENTS,
1796 ALLOW_COPIED_DOUBLE_ELEMENTS,
1797 ALLOW_CONVERTED_DOUBLE_ELEMENTS
1798};
1799
1800
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001801// Indicator for one component of an AccessorPair.
1802enum AccessorComponent {
1803 ACCESSOR_GETTER,
1804 ACCESSOR_SETTER
1805};
1806
Ben Murdoch61f157c2016-09-16 13:49:30 +01001807enum class GetKeysConversion { kKeepNumbers, kConvertToString };
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001808
Ben Murdoch61f157c2016-09-16 13:49:30 +01001809enum class KeyCollectionMode {
1810 kOwnOnly = static_cast<int>(v8::KeyCollectionMode::kOwnOnly),
1811 kIncludePrototypes =
1812 static_cast<int>(v8::KeyCollectionMode::kIncludePrototypes)
1813};
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001814
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001815// JSReceiver includes types on which properties can be defined, i.e.,
1816// JSObject and JSProxy.
1817class JSReceiver: public HeapObject {
Steve Blocka7e24c12009-10-30 11:49:00 +00001818 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001819 // [properties]: Backing storage for properties.
1820 // properties is a FixedArray in the fast case and a Dictionary in the
1821 // slow case.
1822 DECL_ACCESSORS(properties, FixedArray) // Get and set fast properties.
1823 inline void initialize_properties();
1824 inline bool HasFastProperties();
1825 // Gets slow properties for non-global objects.
1826 inline NameDictionary* property_dictionary();
1827
1828 // Deletes an existing named property in a normalized object.
1829 static void DeleteNormalizedProperty(Handle<JSReceiver> object,
1830 Handle<Name> name, int entry);
Ben Murdoche0cee9b2011-05-25 10:26:03 +01001831
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001832 DECLARE_CAST(JSReceiver)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001833
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001834 // ES6 section 7.1.1 ToPrimitive
1835 MUST_USE_RESULT static MaybeHandle<Object> ToPrimitive(
1836 Handle<JSReceiver> receiver,
1837 ToPrimitiveHint hint = ToPrimitiveHint::kDefault);
1838 MUST_USE_RESULT static MaybeHandle<Object> OrdinaryToPrimitive(
1839 Handle<JSReceiver> receiver, OrdinaryToPrimitiveHint hint);
1840
1841 static MaybeHandle<Context> GetFunctionRealm(Handle<JSReceiver> receiver);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001842
Ben Murdoch097c5b22016-05-18 11:27:45 +01001843 // Get the first non-hidden prototype.
1844 static inline MaybeHandle<Object> GetPrototype(Isolate* isolate,
1845 Handle<JSReceiver> receiver);
1846
1847 MUST_USE_RESULT static Maybe<bool> HasInPrototypeChain(
1848 Isolate* isolate, Handle<JSReceiver> object, Handle<Object> proto);
1849
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001850 // Implementation of [[HasProperty]], ECMA-262 5th edition, section 8.12.6.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001851 MUST_USE_RESULT static Maybe<bool> HasProperty(LookupIterator* it);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001852 MUST_USE_RESULT static inline Maybe<bool> HasProperty(
1853 Handle<JSReceiver> object, Handle<Name> name);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001854 MUST_USE_RESULT static inline Maybe<bool> HasElement(
1855 Handle<JSReceiver> object, uint32_t index);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001856
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001857 MUST_USE_RESULT static inline Maybe<bool> HasOwnProperty(
1858 Handle<JSReceiver> object, Handle<Name> name);
Ben Murdochc5610432016-08-08 18:44:38 +01001859 MUST_USE_RESULT static inline Maybe<bool> HasOwnProperty(
1860 Handle<JSReceiver> object, uint32_t index);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001861
Ben Murdochda12d292016-06-02 14:46:10 +01001862 MUST_USE_RESULT static inline MaybeHandle<Object> GetProperty(
1863 Isolate* isolate, Handle<JSReceiver> receiver, const char* key);
1864 MUST_USE_RESULT static inline MaybeHandle<Object> GetProperty(
1865 Handle<JSReceiver> receiver, Handle<Name> name);
1866 MUST_USE_RESULT static inline MaybeHandle<Object> GetElement(
1867 Isolate* isolate, Handle<JSReceiver> receiver, uint32_t index);
1868
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001869 // Implementation of ES6 [[Delete]]
1870 MUST_USE_RESULT static Maybe<bool> DeletePropertyOrElement(
1871 Handle<JSReceiver> object, Handle<Name> name,
1872 LanguageMode language_mode = SLOPPY);
1873 MUST_USE_RESULT static Maybe<bool> DeleteProperty(
1874 Handle<JSReceiver> object, Handle<Name> name,
1875 LanguageMode language_mode = SLOPPY);
1876 MUST_USE_RESULT static Maybe<bool> DeleteProperty(LookupIterator* it,
1877 LanguageMode language_mode);
1878 MUST_USE_RESULT static Maybe<bool> DeleteElement(
1879 Handle<JSReceiver> object, uint32_t index,
1880 LanguageMode language_mode = SLOPPY);
1881
1882 MUST_USE_RESULT static Object* DefineProperty(Isolate* isolate,
1883 Handle<Object> object,
1884 Handle<Object> name,
1885 Handle<Object> attributes);
1886 MUST_USE_RESULT static MaybeHandle<Object> DefineProperties(
1887 Isolate* isolate, Handle<Object> object, Handle<Object> properties);
1888
1889 // "virtual" dispatcher to the correct [[DefineOwnProperty]] implementation.
1890 MUST_USE_RESULT static Maybe<bool> DefineOwnProperty(
1891 Isolate* isolate, Handle<JSReceiver> object, Handle<Object> key,
1892 PropertyDescriptor* desc, ShouldThrow should_throw);
1893
1894 // ES6 7.3.4 (when passed DONT_THROW)
1895 MUST_USE_RESULT static Maybe<bool> CreateDataProperty(
1896 LookupIterator* it, Handle<Object> value, ShouldThrow should_throw);
1897
1898 // ES6 9.1.6.1
1899 MUST_USE_RESULT static Maybe<bool> OrdinaryDefineOwnProperty(
1900 Isolate* isolate, Handle<JSObject> object, Handle<Object> key,
1901 PropertyDescriptor* desc, ShouldThrow should_throw);
1902 MUST_USE_RESULT static Maybe<bool> OrdinaryDefineOwnProperty(
1903 LookupIterator* it, PropertyDescriptor* desc, ShouldThrow should_throw);
1904 // ES6 9.1.6.2
1905 MUST_USE_RESULT static Maybe<bool> IsCompatiblePropertyDescriptor(
1906 Isolate* isolate, bool extensible, PropertyDescriptor* desc,
1907 PropertyDescriptor* current, Handle<Name> property_name,
1908 ShouldThrow should_throw);
1909 // ES6 9.1.6.3
1910 // |it| can be NULL in cases where the ES spec passes |undefined| as the
1911 // receiver. Exactly one of |it| and |property_name| must be provided.
1912 MUST_USE_RESULT static Maybe<bool> ValidateAndApplyPropertyDescriptor(
1913 Isolate* isolate, LookupIterator* it, bool extensible,
1914 PropertyDescriptor* desc, PropertyDescriptor* current,
1915 ShouldThrow should_throw, Handle<Name> property_name = Handle<Name>());
1916
1917 MUST_USE_RESULT static Maybe<bool> GetOwnPropertyDescriptor(
1918 Isolate* isolate, Handle<JSReceiver> object, Handle<Object> key,
1919 PropertyDescriptor* desc);
1920 MUST_USE_RESULT static Maybe<bool> GetOwnPropertyDescriptor(
1921 LookupIterator* it, PropertyDescriptor* desc);
1922
1923 typedef PropertyAttributes IntegrityLevel;
1924
1925 // ES6 7.3.14 (when passed DONT_THROW)
1926 // 'level' must be SEALED or FROZEN.
1927 MUST_USE_RESULT static Maybe<bool> SetIntegrityLevel(
1928 Handle<JSReceiver> object, IntegrityLevel lvl, ShouldThrow should_throw);
1929
1930 // ES6 7.3.15
1931 // 'level' must be SEALED or FROZEN.
1932 MUST_USE_RESULT static Maybe<bool> TestIntegrityLevel(
1933 Handle<JSReceiver> object, IntegrityLevel lvl);
1934
1935 // ES6 [[PreventExtensions]] (when passed DONT_THROW)
1936 MUST_USE_RESULT static Maybe<bool> PreventExtensions(
1937 Handle<JSReceiver> object, ShouldThrow should_throw);
1938
1939 MUST_USE_RESULT static Maybe<bool> IsExtensible(Handle<JSReceiver> object);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001940
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001941 // Returns the class name ([[Class]] property in the specification).
1942 String* class_name();
1943
1944 // Returns the constructor name (the name (possibly, inferred name) of the
1945 // function that was used to instantiate the object).
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001946 static Handle<String> GetConstructorName(Handle<JSReceiver> receiver);
1947
1948 Context* GetCreationContext();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001949
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001950 MUST_USE_RESULT static inline Maybe<PropertyAttributes> GetPropertyAttributes(
1951 Handle<JSReceiver> object, Handle<Name> name);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001952 MUST_USE_RESULT static inline Maybe<PropertyAttributes>
1953 GetOwnPropertyAttributes(Handle<JSReceiver> object, Handle<Name> name);
Ben Murdochc5610432016-08-08 18:44:38 +01001954 MUST_USE_RESULT static inline Maybe<PropertyAttributes>
1955 GetOwnPropertyAttributes(Handle<JSReceiver> object, uint32_t index);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001956
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001957 MUST_USE_RESULT static inline Maybe<PropertyAttributes> GetElementAttributes(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001958 Handle<JSReceiver> object, uint32_t index);
1959 MUST_USE_RESULT static inline Maybe<PropertyAttributes>
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001960 GetOwnElementAttributes(Handle<JSReceiver> object, uint32_t index);
1961
1962 MUST_USE_RESULT static Maybe<PropertyAttributes> GetPropertyAttributes(
1963 LookupIterator* it);
1964
1965 // Set the object's prototype (only JSReceiver and null are allowed values).
1966 MUST_USE_RESULT static Maybe<bool> SetPrototype(Handle<JSReceiver> object,
1967 Handle<Object> value,
1968 bool from_javascript,
1969 ShouldThrow should_throw);
1970
Ben Murdochda12d292016-06-02 14:46:10 +01001971 inline static Handle<Object> GetDataProperty(Handle<JSReceiver> object,
1972 Handle<Name> name);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001973 static Handle<Object> GetDataProperty(LookupIterator* it);
1974
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001975
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001976 // Retrieves a permanent object identity hash code. The undefined value might
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001977 // be returned in case no hash was created yet.
Ben Murdoch61f157c2016-09-16 13:49:30 +01001978 static inline Object* GetIdentityHash(Isolate* isolate,
1979 Handle<JSReceiver> object);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001980
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001981 // Retrieves a permanent object identity hash code. May create and store a
1982 // hash code if needed and none exists.
Ben Murdoch61f157c2016-09-16 13:49:30 +01001983 inline static Smi* GetOrCreateIdentityHash(Isolate* isolate,
1984 Handle<JSReceiver> object);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001985
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001986 // ES6 [[OwnPropertyKeys]] (modulo return type)
Ben Murdoch61f157c2016-09-16 13:49:30 +01001987 MUST_USE_RESULT static inline MaybeHandle<FixedArray> OwnPropertyKeys(
1988 Handle<JSReceiver> object);
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 Murdoch61f157c2016-09-16 13:49:30 +01002176 static void MakePrototypesFast(Handle<Object> receiver,
2177 WhereToStart where_to_start, Isolate* isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002178 static void LazyRegisterPrototypeUser(Handle<Map> user, Isolate* isolate);
2179 static void UpdatePrototypeUserRegistration(Handle<Map> old_map,
2180 Handle<Map> new_map,
2181 Isolate* isolate);
2182 static bool UnregisterPrototypeUser(Handle<Map> user, Isolate* isolate);
2183 static void InvalidatePrototypeChains(Map* map);
2184
2185 // Alternative implementation of WeakFixedArray::NullCallback.
2186 class PrototypeRegistryCompactionCallback {
2187 public:
2188 static void Callback(Object* value, int old_index, int new_index);
2189 };
Steve Blocka7e24c12009-10-30 11:49:00 +00002190
Steve Blocka7e24c12009-10-30 11:49:00 +00002191 // Retrieve interceptors.
Ben Murdochda12d292016-06-02 14:46:10 +01002192 inline InterceptorInfo* GetNamedInterceptor();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002193 inline InterceptorInfo* GetIndexedInterceptor();
Steve Blocka7e24c12009-10-30 11:49:00 +00002194
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002195 // Used from JSReceiver.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002196 MUST_USE_RESULT static Maybe<PropertyAttributes>
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002197 GetPropertyAttributesWithInterceptor(LookupIterator* it);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002198 MUST_USE_RESULT static Maybe<PropertyAttributes>
2199 GetPropertyAttributesWithFailedAccessCheck(LookupIterator* it);
Steve Blocka7e24c12009-10-30 11:49:00 +00002200
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002201 // Defines an AccessorPair property on the given object.
2202 // TODO(mstarzinger): Rename to SetAccessor().
2203 static MaybeHandle<Object> DefineAccessor(Handle<JSObject> object,
2204 Handle<Name> name,
2205 Handle<Object> getter,
2206 Handle<Object> setter,
2207 PropertyAttributes attributes);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002208 static MaybeHandle<Object> DefineAccessor(LookupIterator* it,
2209 Handle<Object> getter,
2210 Handle<Object> setter,
2211 PropertyAttributes attributes);
Leon Clarkef7060e22010-06-03 12:02:55 +01002212
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002213 // Defines an AccessorInfo property on the given object.
2214 MUST_USE_RESULT static MaybeHandle<Object> SetAccessor(
2215 Handle<JSObject> object,
2216 Handle<AccessorInfo> info);
2217
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002218 // The result must be checked first for exceptions. If there's no exception,
2219 // the output parameter |done| indicates whether the interceptor has a result
2220 // or not.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002221 MUST_USE_RESULT static MaybeHandle<Object> GetPropertyWithInterceptor(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002222 LookupIterator* it, bool* done);
Steve Blocka7e24c12009-10-30 11:49:00 +00002223
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002224 static void ValidateElements(Handle<JSObject> object);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002225
2226 // Makes sure that this object can contain HeapObject as elements.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002227 static inline void EnsureCanContainHeapObjectElements(Handle<JSObject> obj);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002228
2229 // Makes sure that this object can contain the specified elements.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002230 static inline void EnsureCanContainElements(
2231 Handle<JSObject> object,
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002232 Object** elements,
2233 uint32_t count,
2234 EnsureElementsMode mode);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002235 static inline void EnsureCanContainElements(
2236 Handle<JSObject> object,
2237 Handle<FixedArrayBase> elements,
2238 uint32_t length,
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002239 EnsureElementsMode mode);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002240 static void EnsureCanContainElements(
2241 Handle<JSObject> object,
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002242 Arguments* arguments,
2243 uint32_t first_arg,
2244 uint32_t arg_count,
2245 EnsureElementsMode mode);
Steve Blocka7e24c12009-10-30 11:49:00 +00002246
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002247 // Would we convert a fast elements array to dictionary mode given
2248 // an access at key?
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002249 bool WouldConvertToSlowElements(uint32_t index);
Andrei Popescu402d9372010-02-26 13:31:12 +00002250
Ben Murdoche0cee9b2011-05-25 10:26:03 +01002251 // Computes the new capacity when expanding the elements of a JSObject.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002252 static uint32_t NewElementsCapacity(uint32_t old_capacity) {
Ben Murdoche0cee9b2011-05-25 10:26:03 +01002253 // (old_capacity + 50%) + 16
2254 return old_capacity + (old_capacity >> 1) + 16;
2255 }
2256
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002257 // These methods do not perform access checks!
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002258 static void UpdateAllocationSite(Handle<JSObject> object,
2259 ElementsKind to_kind);
Steve Blocka7e24c12009-10-30 11:49:00 +00002260
2261 // Lookup interceptors are used for handling properties controlled by host
2262 // objects.
2263 inline bool HasNamedInterceptor();
2264 inline bool HasIndexedInterceptor();
2265
2266 // Support functions for v8 api (needed for correct interceptor behavior).
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002267 MUST_USE_RESULT static Maybe<bool> HasRealNamedProperty(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002268 Handle<JSObject> object, Handle<Name> name);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002269 MUST_USE_RESULT static Maybe<bool> HasRealElementProperty(
2270 Handle<JSObject> object, uint32_t index);
2271 MUST_USE_RESULT static Maybe<bool> HasRealNamedCallbackProperty(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002272 Handle<JSObject> object, Handle<Name> name);
Steve Blocka7e24c12009-10-30 11:49:00 +00002273
Steve Blocka7e24c12009-10-30 11:49:00 +00002274 // Get the header size for a JSObject. Used to compute the index of
2275 // internal fields as well as the number of internal fields.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002276 static inline int GetHeaderSize(InstanceType instance_type);
Steve Blocka7e24c12009-10-30 11:49:00 +00002277 inline int GetHeaderSize();
2278
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002279 static inline int GetInternalFieldCount(Map* map);
Steve Blocka7e24c12009-10-30 11:49:00 +00002280 inline int GetInternalFieldCount();
Steve Block44f0eee2011-05-26 01:26:41 +01002281 inline int GetInternalFieldOffset(int index);
Steve Blocka7e24c12009-10-30 11:49:00 +00002282 inline Object* GetInternalField(int index);
2283 inline void SetInternalField(int index, Object* value);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002284 inline void SetInternalField(int index, Smi* value);
Ben Murdochc5610432016-08-08 18:44:38 +01002285 bool WasConstructedFromApiFunction();
Ben Murdochda12d292016-06-02 14:46:10 +01002286
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002287 // Returns a new map with all transitions dropped from the object's current
2288 // map and the ElementsKind set.
2289 static Handle<Map> GetElementsTransitionMap(Handle<JSObject> object,
2290 ElementsKind to_kind);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002291 static void TransitionElementsKind(Handle<JSObject> object,
2292 ElementsKind to_kind);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002293
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002294 // Always use this to migrate an object to a new map.
2295 // |expected_additional_properties| is only used for fast-to-slow transitions
2296 // and ignored otherwise.
2297 static void MigrateToMap(Handle<JSObject> object, Handle<Map> new_map,
2298 int expected_additional_properties = 0);
Steve Blocka7e24c12009-10-30 11:49:00 +00002299
2300 // Convert the object to use the canonical dictionary
2301 // representation. If the object is expected to have additional properties
2302 // added this number can be indicated to have the backing store allocated to
2303 // an initial capacity for holding these properties.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002304 static void NormalizeProperties(Handle<JSObject> object,
2305 PropertyNormalizationMode mode,
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002306 int expected_additional_properties,
2307 const char* reason);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002308
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002309 // Convert and update the elements backing store to be a
2310 // SeededNumberDictionary dictionary. Returns the backing after conversion.
2311 static Handle<SeededNumberDictionary> NormalizeElements(
2312 Handle<JSObject> object);
2313
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002314 void RequireSlowElements(SeededNumberDictionary* dictionary);
2315
Steve Blocka7e24c12009-10-30 11:49:00 +00002316 // Transform slow named properties to fast variants.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002317 static void MigrateSlowToFast(Handle<JSObject> object,
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002318 int unused_property_fields, const char* reason);
2319
2320 inline bool IsUnboxedDoubleField(FieldIndex index);
Steve Blocka7e24c12009-10-30 11:49:00 +00002321
2322 // Access fast-case object properties at index.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002323 static Handle<Object> FastPropertyAt(Handle<JSObject> object,
2324 Representation representation,
2325 FieldIndex index);
2326 inline Object* RawFastPropertyAt(FieldIndex index);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002327 inline double RawFastDoublePropertyAt(FieldIndex index);
2328
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002329 inline void FastPropertyAtPut(FieldIndex index, Object* value);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002330 inline void RawFastPropertyAtPut(FieldIndex index, Object* value);
2331 inline void RawFastDoublePropertyAtPut(FieldIndex index, double value);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002332 inline void WriteToField(int descriptor, PropertyDetails details,
2333 Object* value);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002334 inline void WriteToField(int descriptor, Object* value);
Steve Blocka7e24c12009-10-30 11:49:00 +00002335
2336 // Access to in object properties.
Steve Block44f0eee2011-05-26 01:26:41 +01002337 inline int GetInObjectPropertyOffset(int index);
Steve Blocka7e24c12009-10-30 11:49:00 +00002338 inline Object* InObjectPropertyAt(int index);
2339 inline Object* InObjectPropertyAtPut(int index,
2340 Object* value,
2341 WriteBarrierMode mode
2342 = UPDATE_WRITE_BARRIER);
2343
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002344 // Set the object's prototype (only JSReceiver and null are allowed values).
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002345 MUST_USE_RESULT static Maybe<bool> SetPrototype(Handle<JSObject> object,
2346 Handle<Object> value,
2347 bool from_javascript,
2348 ShouldThrow should_throw);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002349
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002350 // Initializes the body starting at |start_offset|. It is responsibility of
2351 // the caller to initialize object header. Fill the pre-allocated fields with
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002352 // pre_allocated_value and the rest with filler_value.
2353 // Note: this call does not update write barrier, the caller is responsible
2354 // to ensure that |filler_value| can be collected without WB here.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002355 inline void InitializeBody(Map* map, int start_offset,
2356 Object* pre_allocated_value, Object* filler_value);
Steve Blocka7e24c12009-10-30 11:49:00 +00002357
2358 // Check whether this object references another object
2359 bool ReferencesObject(Object* obj);
2360
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002361 MUST_USE_RESULT static Maybe<bool> PreventExtensions(
2362 Handle<JSObject> object, ShouldThrow should_throw);
Steve Block8defd9f2010-07-08 12:39:36 +01002363
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002364 static bool IsExtensible(Handle<JSObject> object);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002365
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002366 // Copy object.
2367 enum DeepCopyHints { kNoHints = 0, kObjectIsShallow = 1 };
2368
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002369 MUST_USE_RESULT static MaybeHandle<JSObject> DeepCopy(
2370 Handle<JSObject> object,
2371 AllocationSiteUsageContext* site_context,
2372 DeepCopyHints hints = kNoHints);
2373 MUST_USE_RESULT static MaybeHandle<JSObject> DeepWalk(
2374 Handle<JSObject> object,
2375 AllocationSiteCreationContext* site_context);
2376
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002377 DECLARE_CAST(JSObject)
Steve Block8defd9f2010-07-08 12:39:36 +01002378
Steve Blocka7e24c12009-10-30 11:49:00 +00002379 // Dispatched behavior.
Steve Blocka7e24c12009-10-30 11:49:00 +00002380 void JSObjectShortPrint(StringStream* accumulator);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002381 DECLARE_PRINTER(JSObject)
2382 DECLARE_VERIFIER(JSObject)
Ben Murdochb0fe1622011-05-05 13:52:32 +01002383#ifdef OBJECT_PRINT
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002384 void PrintProperties(std::ostream& os); // NOLINT
2385 void PrintElements(std::ostream& os); // NOLINT
2386#endif
2387#if defined(DEBUG) || defined(OBJECT_PRINT)
2388 void PrintTransitions(std::ostream& os); // NOLINT
Ben Murdochb0fe1622011-05-05 13:52:32 +01002389#endif
2390
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002391 static void PrintElementsTransition(
2392 FILE* file, Handle<JSObject> object,
2393 ElementsKind from_kind, Handle<FixedArrayBase> from_elements,
2394 ElementsKind to_kind, Handle<FixedArrayBase> to_elements);
2395
2396 void PrintInstanceMigration(FILE* file, Map* original_map, Map* new_map);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002397
Ben Murdochb0fe1622011-05-05 13:52:32 +01002398#ifdef DEBUG
Steve Blocka7e24c12009-10-30 11:49:00 +00002399 // Structure for collecting spill information about JSObjects.
2400 class SpillInformation {
2401 public:
2402 void Clear();
2403 void Print();
2404 int number_of_objects_;
2405 int number_of_objects_with_fast_properties_;
2406 int number_of_objects_with_fast_elements_;
2407 int number_of_fast_used_fields_;
2408 int number_of_fast_unused_fields_;
2409 int number_of_slow_used_properties_;
2410 int number_of_slow_unused_properties_;
2411 int number_of_fast_used_elements_;
2412 int number_of_fast_unused_elements_;
2413 int number_of_slow_used_elements_;
2414 int number_of_slow_unused_elements_;
2415 };
2416
2417 void IncrementSpillStatistics(SpillInformation* info);
2418#endif
Steve Blocka7e24c12009-10-30 11:49:00 +00002419
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002420#ifdef VERIFY_HEAP
2421 // If a GC was caused while constructing this object, the elements pointer
2422 // may point to a one pointer filler map. The object won't be rooted, but
2423 // our heap verification code could stumble across it.
2424 bool ElementsAreSafeToExamine();
2425#endif
2426
2427 Object* SlowReverseLookup(Object* value);
Steve Block8defd9f2010-07-08 12:39:36 +01002428
Leon Clarkee46be812010-01-19 14:06:41 +00002429 // Maximal number of elements (numbered 0 .. kMaxElementCount - 1).
2430 // Also maximal value of JSArray's length property.
2431 static const uint32_t kMaxElementCount = 0xffffffffu;
2432
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002433 // Constants for heuristics controlling conversion of fast elements
2434 // to slow elements.
2435
2436 // Maximal gap that can be introduced by adding an element beyond
2437 // the current elements length.
Steve Blocka7e24c12009-10-30 11:49:00 +00002438 static const uint32_t kMaxGap = 1024;
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002439
2440 // Maximal length of fast elements array that won't be checked for
2441 // being dense enough on expansion.
2442 static const int kMaxUncheckedFastElementsLength = 5000;
2443
2444 // Same as above but for old arrays. This limit is more strict. We
2445 // don't want to be wasteful with long lived objects.
2446 static const int kMaxUncheckedOldFastElementsLength = 500;
2447
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002448 // This constant applies only to the initial map of "global.Object" and
2449 // not to arbitrary other JSObject maps.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002450 static const int kInitialGlobalObjectUnusedPropertiesCount = 4;
2451
Steve Blocka7e24c12009-10-30 11:49:00 +00002452 static const int kMaxInstanceSize = 255 * kPointerSize;
2453 // When extending the backing storage for property values, we increase
2454 // its size by more than the 1 entry necessary, so sequentially adding fields
2455 // to the same object requires fewer allocations and copies.
2456 static const int kFieldsAdded = 3;
2457
2458 // Layout description.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002459 static const int kElementsOffset = JSReceiver::kHeaderSize;
Steve Blocka7e24c12009-10-30 11:49:00 +00002460 static const int kHeaderSize = kElementsOffset + kPointerSize;
2461
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002462 STATIC_ASSERT(kHeaderSize == Internals::kJSObjectHeaderSize);
Steve Blocka7e24c12009-10-30 11:49:00 +00002463
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002464 typedef FlexibleBodyDescriptor<JSReceiver::kPropertiesOffset> BodyDescriptor;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002465
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002466 // Gets the number of currently used elements.
2467 int GetFastElementsUsage();
2468
2469 static bool AllCanRead(LookupIterator* it);
2470 static bool AllCanWrite(LookupIterator* it);
2471
Steve Blocka7e24c12009-10-30 11:49:00 +00002472 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002473 friend class JSReceiver;
2474 friend class Object;
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002475
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002476 // Used from Object::GetProperty().
2477 MUST_USE_RESULT static MaybeHandle<Object> GetPropertyWithFailedAccessCheck(
2478 LookupIterator* it);
2479
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002480 MUST_USE_RESULT static Maybe<bool> SetPropertyWithFailedAccessCheck(
2481 LookupIterator* it, Handle<Object> value, ShouldThrow should_throw);
Steve Blocka7e24c12009-10-30 11:49:00 +00002482
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002483 // Add a property to a slow-case object.
2484 static void AddSlowProperty(Handle<JSObject> object,
2485 Handle<Name> name,
2486 Handle<Object> value,
2487 PropertyAttributes attributes);
Steve Blocka7e24c12009-10-30 11:49:00 +00002488
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002489 MUST_USE_RESULT static Maybe<bool> DeletePropertyWithInterceptor(
Ben Murdoch097c5b22016-05-18 11:27:45 +01002490 LookupIterator* it, ShouldThrow should_throw);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002491
2492 bool ReferencesObjectFromElements(FixedArray* elements,
2493 ElementsKind kind,
2494 Object* object);
Steve Blocka7e24c12009-10-30 11:49:00 +00002495
Ben Murdoch61f157c2016-09-16 13:49:30 +01002496 static Object* GetIdentityHash(Isolate* isolate, Handle<JSObject> object);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002497
Ben Murdoch61f157c2016-09-16 13:49:30 +01002498 static Smi* GetOrCreateIdentityHash(Isolate* isolate,
2499 Handle<JSObject> object);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002500
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002501 // Helper for fast versions of preventExtensions, seal, and freeze.
2502 // attrs is one of NONE, SEALED, or FROZEN (depending on the operation).
2503 template <PropertyAttributes attrs>
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002504 MUST_USE_RESULT static Maybe<bool> PreventExtensionsWithTransition(
2505 Handle<JSObject> object, ShouldThrow should_throw);
2506
Steve Blocka7e24c12009-10-30 11:49:00 +00002507 DISALLOW_IMPLICIT_CONSTRUCTORS(JSObject);
2508};
2509
2510
Ben Murdoch097c5b22016-05-18 11:27:45 +01002511// JSAccessorPropertyDescriptor is just a JSObject with a specific initial
2512// map. This initial map adds in-object properties for "get", "set",
2513// "enumerable" and "configurable" properties, as assigned by the
2514// FromPropertyDescriptor function for regular accessor properties.
2515class JSAccessorPropertyDescriptor: public JSObject {
2516 public:
2517 // Offsets of object fields.
2518 static const int kGetOffset = JSObject::kHeaderSize;
2519 static const int kSetOffset = kGetOffset + kPointerSize;
2520 static const int kEnumerableOffset = kSetOffset + kPointerSize;
2521 static const int kConfigurableOffset = kEnumerableOffset + kPointerSize;
2522 static const int kSize = kConfigurableOffset + kPointerSize;
2523 // Indices of in-object properties.
2524 static const int kGetIndex = 0;
2525 static const int kSetIndex = 1;
2526 static const int kEnumerableIndex = 2;
2527 static const int kConfigurableIndex = 3;
2528
2529 private:
2530 DISALLOW_IMPLICIT_CONSTRUCTORS(JSAccessorPropertyDescriptor);
2531};
2532
2533
2534// JSDataPropertyDescriptor is just a JSObject with a specific initial map.
2535// This initial map adds in-object properties for "value", "writable",
2536// "enumerable" and "configurable" properties, as assigned by the
2537// FromPropertyDescriptor function for regular data properties.
2538class JSDataPropertyDescriptor: public JSObject {
2539 public:
2540 // Offsets of object fields.
2541 static const int kValueOffset = JSObject::kHeaderSize;
2542 static const int kWritableOffset = kValueOffset + kPointerSize;
2543 static const int kEnumerableOffset = kWritableOffset + kPointerSize;
2544 static const int kConfigurableOffset = kEnumerableOffset + kPointerSize;
2545 static const int kSize = kConfigurableOffset + kPointerSize;
2546 // Indices of in-object properties.
2547 static const int kValueIndex = 0;
2548 static const int kWritableIndex = 1;
2549 static const int kEnumerableIndex = 2;
2550 static const int kConfigurableIndex = 3;
2551
2552 private:
2553 DISALLOW_IMPLICIT_CONSTRUCTORS(JSDataPropertyDescriptor);
2554};
2555
2556
2557// JSIteratorResult is just a JSObject with a specific initial map.
2558// This initial map adds in-object properties for "done" and "value",
2559// as specified by ES6 section 25.1.1.3 The IteratorResult Interface
2560class JSIteratorResult: public JSObject {
2561 public:
2562 // Offsets of object fields.
2563 static const int kValueOffset = JSObject::kHeaderSize;
2564 static const int kDoneOffset = kValueOffset + kPointerSize;
2565 static const int kSize = kDoneOffset + kPointerSize;
2566 // Indices of in-object properties.
2567 static const int kValueIndex = 0;
2568 static const int kDoneIndex = 1;
2569
2570 private:
2571 DISALLOW_IMPLICIT_CONSTRUCTORS(JSIteratorResult);
2572};
2573
2574
2575// Common superclass for JSSloppyArgumentsObject and JSStrictArgumentsObject.
2576class JSArgumentsObject: public JSObject {
2577 public:
2578 // Offsets of object fields.
2579 static const int kLengthOffset = JSObject::kHeaderSize;
2580 static const int kHeaderSize = kLengthOffset + kPointerSize;
2581 // Indices of in-object properties.
2582 static const int kLengthIndex = 0;
2583
2584 private:
2585 DISALLOW_IMPLICIT_CONSTRUCTORS(JSArgumentsObject);
2586};
2587
2588
2589// JSSloppyArgumentsObject is just a JSObject with specific initial map.
2590// This initial map adds in-object properties for "length" and "callee".
2591class JSSloppyArgumentsObject: public JSArgumentsObject {
2592 public:
2593 // Offsets of object fields.
2594 static const int kCalleeOffset = JSArgumentsObject::kHeaderSize;
2595 static const int kSize = kCalleeOffset + kPointerSize;
2596 // Indices of in-object properties.
2597 static const int kCalleeIndex = 1;
2598
2599 private:
2600 DISALLOW_IMPLICIT_CONSTRUCTORS(JSSloppyArgumentsObject);
2601};
2602
2603
2604// JSStrictArgumentsObject is just a JSObject with specific initial map.
2605// This initial map adds an in-object property for "length".
2606class JSStrictArgumentsObject: public JSArgumentsObject {
2607 public:
2608 // Offsets of object fields.
2609 static const int kSize = JSArgumentsObject::kHeaderSize;
2610
2611 private:
2612 DISALLOW_IMPLICIT_CONSTRUCTORS(JSStrictArgumentsObject);
2613};
2614
2615
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002616// Common superclass for FixedArrays that allow implementations to share
2617// common accessors and some code paths.
2618class FixedArrayBase: public HeapObject {
Steve Blocka7e24c12009-10-30 11:49:00 +00002619 public:
2620 // [length]: length of the array.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002621 inline int length() const;
Steve Blocka7e24c12009-10-30 11:49:00 +00002622 inline void set_length(int value);
2623
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002624 // Get and set the length using acquire loads and release stores.
2625 inline int synchronized_length() const;
2626 inline void synchronized_set_length(int value);
2627
2628 DECLARE_CAST(FixedArrayBase)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002629
2630 // Layout description.
2631 // Length is smi tagged when it is stored.
2632 static const int kLengthOffset = HeapObject::kHeaderSize;
2633 static const int kHeaderSize = kLengthOffset + kPointerSize;
2634};
2635
2636
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002637class FixedDoubleArray;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002638class IncrementalMarking;
2639
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002640
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002641// FixedArray describes fixed-sized arrays with element type Object*.
2642class FixedArray: public FixedArrayBase {
2643 public:
Steve Blocka7e24c12009-10-30 11:49:00 +00002644 // Setter and getter for elements.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002645 inline Object* get(int index) const;
Ben Murdoch097c5b22016-05-18 11:27:45 +01002646 static inline Handle<Object> get(FixedArray* array, int index,
2647 Isolate* isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002648 // Setter that uses write barrier.
2649 inline void set(int index, Object* value);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002650 inline bool is_the_hole(int index);
Steve Blocka7e24c12009-10-30 11:49:00 +00002651
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002652 // Setter that doesn't need write barrier.
Steve Blocka7e24c12009-10-30 11:49:00 +00002653 inline void set(int index, Smi* value);
2654 // Setter with explicit barrier mode.
2655 inline void set(int index, Object* value, WriteBarrierMode mode);
2656
2657 // Setters for frequently used oddballs located in old space.
2658 inline void set_undefined(int index);
2659 inline void set_null(int index);
2660 inline void set_the_hole(int index);
2661
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002662 inline Object** GetFirstElementAddress();
2663 inline bool ContainsOnlySmisOrHoles();
2664
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002665 // Gives access to raw memory which stores the array's data.
2666 inline Object** data_start();
2667
2668 inline void FillWithHoles(int from, int to);
2669
2670 // Shrink length and insert filler objects.
2671 void Shrink(int length);
2672
Steve Blocka7e24c12009-10-30 11:49:00 +00002673 // Copy a sub array from the receiver to dest.
2674 void CopyTo(int pos, FixedArray* dest, int dest_pos, int len);
2675
2676 // Garbage collection support.
2677 static int SizeFor(int length) { return kHeaderSize + length * kPointerSize; }
2678
2679 // Code Generation support.
2680 static int OffsetOfElementAt(int index) { return SizeFor(index); }
2681
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002682 // Garbage collection support.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002683 inline Object** RawFieldOfElementAt(int index);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002684
2685 DECLARE_CAST(FixedArray)
Steve Blocka7e24c12009-10-30 11:49:00 +00002686
Leon Clarkee46be812010-01-19 14:06:41 +00002687 // Maximal allowed size, in bytes, of a single FixedArray.
2688 // Prevents overflowing size computations, as well as extreme memory
2689 // consumption.
Ben Murdoch692be652012-01-10 18:47:50 +00002690 static const int kMaxSize = 128 * MB * kPointerSize;
Leon Clarkee46be812010-01-19 14:06:41 +00002691 // Maximally allowed length of a FixedArray.
2692 static const int kMaxLength = (kMaxSize - kHeaderSize) / kPointerSize;
Steve Blocka7e24c12009-10-30 11:49:00 +00002693
2694 // Dispatched behavior.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002695 DECLARE_PRINTER(FixedArray)
2696 DECLARE_VERIFIER(FixedArray)
Steve Blocka7e24c12009-10-30 11:49:00 +00002697#ifdef DEBUG
Steve Blocka7e24c12009-10-30 11:49:00 +00002698 // Checks if two FixedArrays have identical contents.
2699 bool IsEqualTo(FixedArray* other);
2700#endif
2701
2702 // Swap two elements in a pair of arrays. If this array and the
2703 // numbers array are the same object, the elements are only swapped
2704 // once.
2705 void SwapPairs(FixedArray* numbers, int i, int j);
2706
2707 // Sort prefix of this array and the numbers array as pairs wrt. the
2708 // numbers. If the numbers array and the this array are the same
2709 // object, the prefix of this array is sorted.
2710 void SortPairs(FixedArray* numbers, uint32_t len);
2711
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002712 typedef FlexibleBodyDescriptor<kHeaderSize> BodyDescriptor;
Iain Merrick75681382010-08-19 15:07:18 +01002713
Steve Blocka7e24c12009-10-30 11:49:00 +00002714 protected:
Leon Clarke4515c472010-02-03 11:58:03 +00002715 // Set operation on FixedArray without using write barriers. Can
2716 // only be used for storing old space objects or smis.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002717 static inline void NoWriteBarrierSet(FixedArray* array,
2718 int index,
2719 Object* value);
2720
Steve Blocka7e24c12009-10-30 11:49:00 +00002721 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002722 STATIC_ASSERT(kHeaderSize == Internals::kFixedArrayHeaderSize);
2723
Steve Blocka7e24c12009-10-30 11:49:00 +00002724 DISALLOW_IMPLICIT_CONSTRUCTORS(FixedArray);
2725};
2726
2727
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002728// FixedDoubleArray describes fixed-sized arrays with element type double.
2729class FixedDoubleArray: public FixedArrayBase {
2730 public:
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002731 // Setter and getter for elements.
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002732 inline double get_scalar(int index);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002733 inline uint64_t get_representation(int index);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002734 static inline Handle<Object> get(FixedDoubleArray* array, int index,
2735 Isolate* isolate);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002736 inline void set(int index, double value);
2737 inline void set_the_hole(int index);
2738
2739 // Checking for the hole.
2740 inline bool is_the_hole(int index);
2741
2742 // Garbage collection support.
2743 inline static int SizeFor(int length) {
2744 return kHeaderSize + length * kDoubleSize;
2745 }
2746
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002747 // Gives access to raw memory which stores the array's data.
2748 inline double* data_start();
2749
2750 inline void FillWithHoles(int from, int to);
2751
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002752 // Code Generation support.
2753 static int OffsetOfElementAt(int index) { return SizeFor(index); }
2754
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002755 DECLARE_CAST(FixedDoubleArray)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002756
2757 // Maximal allowed size, in bytes, of a single FixedDoubleArray.
2758 // Prevents overflowing size computations, as well as extreme memory
2759 // consumption.
2760 static const int kMaxSize = 512 * MB;
2761 // Maximally allowed length of a FixedArray.
2762 static const int kMaxLength = (kMaxSize - kHeaderSize) / kDoubleSize;
2763
2764 // Dispatched behavior.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002765 DECLARE_PRINTER(FixedDoubleArray)
2766 DECLARE_VERIFIER(FixedDoubleArray)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002767
2768 private:
2769 DISALLOW_IMPLICIT_CONSTRUCTORS(FixedDoubleArray);
2770};
2771
2772
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002773class WeakFixedArray : public FixedArray {
2774 public:
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002775 // If |maybe_array| is not a WeakFixedArray, a fresh one will be allocated.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002776 // This function does not check if the value exists already, callers must
2777 // ensure this themselves if necessary.
2778 static Handle<WeakFixedArray> Add(Handle<Object> maybe_array,
2779 Handle<HeapObject> value,
2780 int* assigned_index = NULL);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002781
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002782 // Returns true if an entry was found and removed.
2783 bool Remove(Handle<HeapObject> value);
2784
2785 class NullCallback {
2786 public:
2787 static void Callback(Object* value, int old_index, int new_index) {}
2788 };
2789
2790 template <class CompactionCallback>
2791 void Compact();
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002792
2793 inline Object* Get(int index) const;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002794 inline void Clear(int index);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002795 inline int Length() const;
2796
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002797 inline bool IsEmptySlot(int index) const;
2798 static Object* Empty() { return Smi::FromInt(0); }
2799
2800 class Iterator {
2801 public:
2802 explicit Iterator(Object* maybe_array) : list_(NULL) { Reset(maybe_array); }
2803 void Reset(Object* maybe_array);
2804
2805 template <class T>
2806 inline T* Next();
2807
2808 private:
2809 int index_;
2810 WeakFixedArray* list_;
2811#ifdef DEBUG
2812 int last_used_index_;
2813 DisallowHeapAllocation no_gc_;
2814#endif // DEBUG
2815 DISALLOW_COPY_AND_ASSIGN(Iterator);
2816 };
2817
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002818 DECLARE_CAST(WeakFixedArray)
2819
2820 private:
2821 static const int kLastUsedIndexIndex = 0;
2822 static const int kFirstIndex = 1;
2823
2824 static Handle<WeakFixedArray> Allocate(
2825 Isolate* isolate, int size, Handle<WeakFixedArray> initialize_from);
2826
2827 static void Set(Handle<WeakFixedArray> array, int index,
2828 Handle<HeapObject> value);
2829 inline void clear(int index);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002830
2831 inline int last_used_index() const;
2832 inline void set_last_used_index(int index);
2833
2834 // Disallow inherited setters.
2835 void set(int index, Smi* value);
2836 void set(int index, Object* value);
2837 void set(int index, Object* value, WriteBarrierMode mode);
2838 DISALLOW_IMPLICIT_CONSTRUCTORS(WeakFixedArray);
2839};
2840
2841
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002842// Generic array grows dynamically with O(1) amortized insertion.
2843class ArrayList : public FixedArray {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002844 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002845 enum AddMode {
2846 kNone,
2847 // Use this if GC can delete elements from the array.
2848 kReloadLengthAfterAllocation,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002849 };
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002850 static Handle<ArrayList> Add(Handle<ArrayList> array, Handle<Object> obj,
2851 AddMode mode = kNone);
2852 static Handle<ArrayList> Add(Handle<ArrayList> array, Handle<Object> obj1,
2853 Handle<Object> obj2, AddMode = kNone);
2854 inline int Length();
2855 inline void SetLength(int length);
2856 inline Object* Get(int index);
2857 inline Object** Slot(int index);
2858 inline void Set(int index, Object* obj);
2859 inline void Clear(int index, Object* undefined);
2860 bool IsFull();
2861 DECLARE_CAST(ArrayList)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002862
2863 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002864 static Handle<ArrayList> EnsureSpace(Handle<ArrayList> array, int length);
2865 static const int kLengthIndex = 0;
2866 static const int kFirstIndex = 1;
2867 DISALLOW_IMPLICIT_CONSTRUCTORS(ArrayList);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002868};
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002869
2870
Steve Blocka7e24c12009-10-30 11:49:00 +00002871// DescriptorArrays are fixed arrays used to hold instance descriptors.
2872// The format of the these objects is:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002873// [0]: Number of descriptors
2874// [1]: Either Smi(0) if uninitialized, or a pointer to small fixed array:
2875// [0]: pointer to fixed array with enum cache
2876// [1]: either Smi(0) or pointer to fixed array with indices
2877// [2]: first key
2878// [2 + number of descriptors * kDescriptorSize]: start of slack
Steve Blocka7e24c12009-10-30 11:49:00 +00002879class DescriptorArray: public FixedArray {
2880 public:
Ben Murdoch257744e2011-11-30 15:57:28 +00002881 // Returns true for both shared empty_descriptor_array and for smis, which the
2882 // map uses to encode additional bit fields when the descriptor array is not
2883 // yet used.
Steve Blocka7e24c12009-10-30 11:49:00 +00002884 inline bool IsEmpty();
Leon Clarkee46be812010-01-19 14:06:41 +00002885
Steve Blocka7e24c12009-10-30 11:49:00 +00002886 // Returns the number of descriptors in the array.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002887 inline int number_of_descriptors();
Steve Blocka7e24c12009-10-30 11:49:00 +00002888
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002889 inline int number_of_descriptors_storage();
Steve Blocka7e24c12009-10-30 11:49:00 +00002890
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002891 inline int NumberOfSlackDescriptors();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002892
2893 inline void SetNumberOfDescriptors(int number_of_descriptors);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002894 inline int number_of_entries();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002895
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002896 inline bool HasEnumCache();
Steve Blocka7e24c12009-10-30 11:49:00 +00002897
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002898 inline void CopyEnumCacheFrom(DescriptorArray* array);
Steve Blocka7e24c12009-10-30 11:49:00 +00002899
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002900 inline FixedArray* GetEnumCache();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002901
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002902 inline bool HasEnumIndicesCache();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002903
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002904 inline FixedArray* GetEnumIndicesCache();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002905
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002906 inline Object** GetEnumCacheSlot();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002907
2908 void ClearEnumCache();
Ben Murdoch257744e2011-11-30 15:57:28 +00002909
Steve Blocka7e24c12009-10-30 11:49:00 +00002910 // Initialize or change the enum cache,
2911 // using the supplied storage for the small "bridge".
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002912 static void SetEnumCache(Handle<DescriptorArray> descriptors,
2913 Isolate* isolate, Handle<FixedArray> new_cache,
2914 Handle<FixedArray> new_index_cache);
Steve Blocka7e24c12009-10-30 11:49:00 +00002915
2916 // Accessors for fetching instance descriptor at descriptor number.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002917 inline Name* GetKey(int descriptor_number);
2918 inline Object** GetKeySlot(int descriptor_number);
Steve Blocka7e24c12009-10-30 11:49:00 +00002919 inline Object* GetValue(int descriptor_number);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002920 inline void SetValue(int descriptor_number, Object* value);
2921 inline Object** GetValueSlot(int descriptor_number);
2922 static inline int GetValueOffset(int descriptor_number);
2923 inline Object** GetDescriptorStartSlot(int descriptor_number);
2924 inline Object** GetDescriptorEndSlot(int descriptor_number);
2925 inline PropertyDetails GetDetails(int descriptor_number);
Steve Blocka7e24c12009-10-30 11:49:00 +00002926 inline PropertyType GetType(int descriptor_number);
2927 inline int GetFieldIndex(int descriptor_number);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002928 FieldType* GetFieldType(int descriptor_number);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002929 inline Object* GetConstant(int descriptor_number);
Steve Blocka7e24c12009-10-30 11:49:00 +00002930 inline Object* GetCallbacksObject(int descriptor_number);
2931 inline AccessorDescriptor* GetCallbacks(int descriptor_number);
Steve Blocka7e24c12009-10-30 11:49:00 +00002932
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002933 inline Name* GetSortedKey(int descriptor_number);
2934 inline int GetSortedKeyIndex(int descriptor_number);
2935 inline void SetSortedKey(int pointer, int descriptor_number);
2936 inline void SetRepresentation(int descriptor_number,
2937 Representation representation);
2938
2939 // Accessor for complete descriptor.
2940 inline void Get(int descriptor_number, Descriptor* desc);
2941 inline void Set(int descriptor_number, Descriptor* desc);
2942 void Replace(int descriptor_number, Descriptor* descriptor);
2943
2944 // Append automatically sets the enumeration index. This should only be used
2945 // to add descriptors in bulk at the end, followed by sorting the descriptor
2946 // array.
2947 inline void Append(Descriptor* desc);
2948
2949 static Handle<DescriptorArray> CopyUpTo(Handle<DescriptorArray> desc,
2950 int enumeration_index,
2951 int slack = 0);
2952
2953 static Handle<DescriptorArray> CopyUpToAddAttributes(
2954 Handle<DescriptorArray> desc,
2955 int enumeration_index,
2956 PropertyAttributes attributes,
2957 int slack = 0);
2958
2959 // Sort the instance descriptors by the hash codes of their keys.
2960 void Sort();
2961
2962 // Search the instance descriptors for given name.
2963 INLINE(int Search(Name* name, int number_of_own_descriptors));
2964
2965 // As the above, but uses DescriptorLookupCache and updates it when
2966 // necessary.
Ben Murdoch097c5b22016-05-18 11:27:45 +01002967 INLINE(int SearchWithCache(Isolate* isolate, Name* name, Map* map));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002968
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002969 bool IsEqualUpTo(DescriptorArray* desc, int nof_descriptors);
2970
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002971 // Allocates a DescriptorArray, but returns the singleton
2972 // empty descriptor array object if number_of_descriptors is 0.
Ben Murdoch097c5b22016-05-18 11:27:45 +01002973 static Handle<DescriptorArray> Allocate(
2974 Isolate* isolate, int number_of_descriptors, int slack,
2975 PretenureFlag pretenure = NOT_TENURED);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002976
2977 DECLARE_CAST(DescriptorArray)
2978
2979 // Constant for denoting key was not found.
2980 static const int kNotFound = -1;
2981
2982 static const int kDescriptorLengthIndex = 0;
2983 static const int kEnumCacheIndex = 1;
2984 static const int kFirstIndex = 2;
2985
2986 // The length of the "bridge" to the enum cache.
2987 static const int kEnumCacheBridgeLength = 2;
2988 static const int kEnumCacheBridgeCacheIndex = 0;
2989 static const int kEnumCacheBridgeIndicesCacheIndex = 1;
2990
2991 // Layout description.
2992 static const int kDescriptorLengthOffset = FixedArray::kHeaderSize;
2993 static const int kEnumCacheOffset = kDescriptorLengthOffset + kPointerSize;
2994 static const int kFirstOffset = kEnumCacheOffset + kPointerSize;
2995
2996 // Layout description for the bridge array.
2997 static const int kEnumCacheBridgeCacheOffset = FixedArray::kHeaderSize;
2998
2999 // Layout of descriptor.
3000 static const int kDescriptorKey = 0;
3001 static const int kDescriptorDetails = 1;
3002 static const int kDescriptorValue = 2;
3003 static const int kDescriptorSize = 3;
3004
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003005#if defined(DEBUG) || defined(OBJECT_PRINT)
3006 // For our gdb macros, we should perhaps change these in the future.
3007 void Print();
3008
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003009 // Print all the descriptors.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003010 void PrintDescriptors(std::ostream& os); // NOLINT
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003011#endif
3012
3013#ifdef DEBUG
3014 // Is the descriptor array sorted and without duplicates?
3015 bool IsSortedNoDuplicates(int valid_descriptors = -1);
3016
3017 // Is the descriptor array consistent with the back pointers in targets?
3018 bool IsConsistentWithBackPointers(Map* current_map);
3019
3020 // Are two DescriptorArrays equal?
3021 bool IsEqualTo(DescriptorArray* other);
3022#endif
3023
3024 // Returns the fixed array length required to hold number_of_descriptors
3025 // descriptors.
3026 static int LengthFor(int number_of_descriptors) {
3027 return ToKeyIndex(number_of_descriptors);
3028 }
3029
Ben Murdochda12d292016-06-02 14:46:10 +01003030 static int ToDetailsIndex(int descriptor_number) {
3031 return kFirstIndex + (descriptor_number * kDescriptorSize) +
3032 kDescriptorDetails;
3033 }
3034
3035 // Conversion from descriptor number to array indices.
3036 static int ToKeyIndex(int descriptor_number) {
3037 return kFirstIndex + (descriptor_number * kDescriptorSize) + kDescriptorKey;
3038 }
3039
Ben Murdochc5610432016-08-08 18:44:38 +01003040 static int ToValueIndex(int descriptor_number) {
3041 return kFirstIndex + (descriptor_number * kDescriptorSize) +
3042 kDescriptorValue;
3043 }
3044
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003045 private:
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003046 // An entry in a DescriptorArray, represented as an (array, index) pair.
3047 class Entry {
3048 public:
3049 inline explicit Entry(DescriptorArray* descs, int index) :
3050 descs_(descs), index_(index) { }
3051
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003052 inline PropertyType type();
3053 inline Object* GetCallbackObject();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003054
3055 private:
3056 DescriptorArray* descs_;
3057 int index_;
3058 };
3059
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003060 // Transfer a complete descriptor from the src descriptor array to this
3061 // descriptor array.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003062 void CopyFrom(int index, DescriptorArray* src);
Steve Blocka7e24c12009-10-30 11:49:00 +00003063
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003064 inline void SetDescriptor(int descriptor_number, Descriptor* desc);
Steve Blocka7e24c12009-10-30 11:49:00 +00003065
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003066 // Swap first and second descriptor.
3067 inline void SwapSortedKeys(int first, int second);
3068
Steve Blocka7e24c12009-10-30 11:49:00 +00003069 DISALLOW_IMPLICIT_CONSTRUCTORS(DescriptorArray);
3070};
3071
3072
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003073enum SearchMode { ALL_ENTRIES, VALID_ENTRIES };
3074
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003075template <SearchMode search_mode, typename T>
3076inline int Search(T* array, Name* name, int valid_entries = 0,
3077 int* out_insertion_index = NULL);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003078
3079
Steve Blocka7e24c12009-10-30 11:49:00 +00003080// HashTable is a subclass of FixedArray that implements a hash table
3081// that uses open addressing and quadratic probing.
3082//
3083// In order for the quadratic probing to work, elements that have not
3084// yet been used and elements that have been deleted are
3085// distinguished. Probing continues when deleted elements are
3086// encountered and stops when unused elements are encountered.
3087//
3088// - Elements with key == undefined have not been used yet.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003089// - Elements with key == the_hole have been deleted.
Steve Blocka7e24c12009-10-30 11:49:00 +00003090//
3091// The hash table class is parameterized with a Shape and a Key.
3092// Shape must be a class with the following interface:
3093// class ExampleShape {
3094// public:
3095// // Tells whether key matches other.
3096// static bool IsMatch(Key key, Object* other);
3097// // Returns the hash value for key.
3098// static uint32_t Hash(Key key);
3099// // Returns the hash value for object.
3100// static uint32_t HashForObject(Key key, Object* object);
3101// // Convert key to an object.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003102// static inline Handle<Object> AsHandle(Isolate* isolate, Key key);
Steve Blocka7e24c12009-10-30 11:49:00 +00003103// // The prefix size indicates number of elements in the beginning
3104// // of the backing storage.
3105// static const int kPrefixSize = ..;
3106// // The Element size indicates number of elements per entry.
3107// static const int kEntrySize = ..;
3108// };
Steve Block3ce2e202009-11-05 08:53:23 +00003109// The prefix size indicates an amount of memory in the
Steve Blocka7e24c12009-10-30 11:49:00 +00003110// beginning of the backing storage that can be used for non-element
3111// information by subclasses.
3112
Ben Murdochc7cc0282012-03-05 14:35:55 +00003113template<typename Key>
3114class BaseShape {
3115 public:
3116 static const bool UsesSeed = false;
3117 static uint32_t Hash(Key key) { return 0; }
3118 static uint32_t SeededHash(Key key, uint32_t seed) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003119 DCHECK(UsesSeed);
Ben Murdochc7cc0282012-03-05 14:35:55 +00003120 return Hash(key);
3121 }
3122 static uint32_t HashForObject(Key key, Object* object) { return 0; }
3123 static uint32_t SeededHashForObject(Key key, uint32_t seed, Object* object) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003124 DCHECK(UsesSeed);
Ben Murdochc7cc0282012-03-05 14:35:55 +00003125 return HashForObject(key, object);
3126 }
3127};
3128
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003129
3130class HashTableBase : public FixedArray {
3131 public:
3132 // Returns the number of elements in the hash table.
3133 inline int NumberOfElements();
3134
3135 // Returns the number of deleted elements in the hash table.
3136 inline int NumberOfDeletedElements();
3137
3138 // Returns the capacity of the hash table.
3139 inline int Capacity();
3140
3141 // ElementAdded should be called whenever an element is added to a
3142 // hash table.
3143 inline void ElementAdded();
3144
3145 // ElementRemoved should be called whenever an element is removed from
3146 // a hash table.
3147 inline void ElementRemoved();
3148 inline void ElementsRemoved(int n);
3149
3150 // Computes the required capacity for a table holding the given
3151 // number of elements. May be more than HashTable::kMaxCapacity.
3152 static inline int ComputeCapacity(int at_least_space_for);
3153
3154 // Tells whether k is a real key. The hole and undefined are not allowed
3155 // as keys and can be used to indicate missing or deleted elements.
3156 inline bool IsKey(Object* k);
Ben Murdoch61f157c2016-09-16 13:49:30 +01003157 inline bool IsKey(Isolate* isolate, Object* k);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003158
3159 // Compute the probe offset (quadratic probing).
3160 INLINE(static uint32_t GetProbeOffset(uint32_t n)) {
3161 return (n + n * n) >> 1;
3162 }
3163
3164 static const int kNumberOfElementsIndex = 0;
3165 static const int kNumberOfDeletedElementsIndex = 1;
3166 static const int kCapacityIndex = 2;
3167 static const int kPrefixStartIndex = 3;
3168
3169 // Constant used for denoting a absent entry.
3170 static const int kNotFound = -1;
3171
3172 protected:
3173 // Update the number of elements in the hash table.
3174 inline void SetNumberOfElements(int nof);
3175
3176 // Update the number of deleted elements in the hash table.
3177 inline void SetNumberOfDeletedElements(int nod);
3178
3179 // Returns probe entry.
3180 static uint32_t GetProbe(uint32_t hash, uint32_t number, uint32_t size) {
3181 DCHECK(base::bits::IsPowerOfTwo32(size));
3182 return (hash + GetProbeOffset(number)) & (size - 1);
3183 }
3184
3185 inline static uint32_t FirstProbe(uint32_t hash, uint32_t size) {
3186 return hash & (size - 1);
3187 }
3188
3189 inline static uint32_t NextProbe(
3190 uint32_t last, uint32_t number, uint32_t size) {
3191 return (last + number) & (size - 1);
3192 }
3193};
3194
3195
3196template <typename Derived, typename Shape, typename Key>
3197class HashTable : public HashTableBase {
Steve Blocka7e24c12009-10-30 11:49:00 +00003198 public:
Ben Murdoch61f157c2016-09-16 13:49:30 +01003199 typedef Shape ShapeT;
3200
Ben Murdochc7cc0282012-03-05 14:35:55 +00003201 // Wrapper methods
3202 inline uint32_t Hash(Key key) {
3203 if (Shape::UsesSeed) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003204 return Shape::SeededHash(key, GetHeap()->HashSeed());
Ben Murdochc7cc0282012-03-05 14:35:55 +00003205 } else {
3206 return Shape::Hash(key);
3207 }
3208 }
3209
3210 inline uint32_t HashForObject(Key key, Object* object) {
3211 if (Shape::UsesSeed) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003212 return Shape::SeededHashForObject(key, GetHeap()->HashSeed(), object);
Ben Murdochc7cc0282012-03-05 14:35:55 +00003213 } else {
3214 return Shape::HashForObject(key, object);
3215 }
3216 }
3217
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003218 // Returns a new HashTable object.
3219 MUST_USE_RESULT static Handle<Derived> New(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003220 Isolate* isolate, int at_least_space_for,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003221 MinimumCapacity capacity_option = USE_DEFAULT_MINIMUM_CAPACITY,
Kristian Monsen80d68ea2010-09-08 11:05:35 +01003222 PretenureFlag pretenure = NOT_TENURED);
Steve Blocka7e24c12009-10-30 11:49:00 +00003223
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003224 DECLARE_CAST(HashTable)
Steve Blocka7e24c12009-10-30 11:49:00 +00003225
3226 // Garbage collection support.
3227 void IteratePrefix(ObjectVisitor* visitor);
3228 void IterateElements(ObjectVisitor* visitor);
3229
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003230 // Find entry for key otherwise return kNotFound.
3231 inline int FindEntry(Key key);
3232 inline int FindEntry(Isolate* isolate, Key key, int32_t hash);
3233 int FindEntry(Isolate* isolate, Key key);
Steve Blocka7e24c12009-10-30 11:49:00 +00003234
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003235 // Rehashes the table in-place.
3236 void Rehash(Key key);
Steve Blocka7e24c12009-10-30 11:49:00 +00003237
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003238 // Returns the key at entry.
Ben Murdoch61f157c2016-09-16 13:49:30 +01003239 Object* KeyAt(int entry) { return get(EntryToIndex(entry) + kEntryKeyIndex); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003240
3241 static const int kElementsStartIndex = kPrefixStartIndex + Shape::kPrefixSize;
Leon Clarkee46be812010-01-19 14:06:41 +00003242 static const int kEntrySize = Shape::kEntrySize;
Ben Murdoch61f157c2016-09-16 13:49:30 +01003243 STATIC_ASSERT(kEntrySize > 0);
3244 static const int kEntryKeyIndex = 0;
Leon Clarkee46be812010-01-19 14:06:41 +00003245 static const int kElementsStartOffset =
Steve Blocka7e24c12009-10-30 11:49:00 +00003246 kHeaderSize + kElementsStartIndex * kPointerSize;
Steve Block6ded16b2010-05-10 14:33:55 +01003247 static const int kCapacityOffset =
3248 kHeaderSize + kCapacityIndex * kPointerSize;
Steve Blocka7e24c12009-10-30 11:49:00 +00003249
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003250 // Returns the index for an entry (of the key)
3251 static inline int EntryToIndex(int entry) {
3252 return (entry * kEntrySize) + kElementsStartIndex;
3253 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003254
Steve Blocka7e24c12009-10-30 11:49:00 +00003255 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003256 friend class ObjectHashTable;
3257
Steve Blocka7e24c12009-10-30 11:49:00 +00003258 // Find the entry at which to insert element with the given key that
3259 // has the given hash value.
3260 uint32_t FindInsertionEntry(uint32_t hash);
3261
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003262 // Attempt to shrink hash table after removal of key.
3263 MUST_USE_RESULT static Handle<Derived> Shrink(Handle<Derived> table, Key key);
Steve Blocka7e24c12009-10-30 11:49:00 +00003264
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003265 // Ensure enough space for n additional elements.
3266 MUST_USE_RESULT static Handle<Derived> EnsureCapacity(
3267 Handle<Derived> table,
3268 int n,
3269 Key key,
3270 PretenureFlag pretenure = NOT_TENURED);
Steve Blocka7e24c12009-10-30 11:49:00 +00003271
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003272 // Returns true if this table has sufficient capacity for adding n elements.
Ben Murdoch61f157c2016-09-16 13:49:30 +01003273 bool HasSufficientCapacityToAdd(int number_of_additional_elements);
Leon Clarkee46be812010-01-19 14:06:41 +00003274
Steve Blocka7e24c12009-10-30 11:49:00 +00003275 // Sets the capacity of the hash table.
3276 void SetCapacity(int capacity) {
3277 // To scale a computed hash code to fit within the hash table, we
3278 // use bit-wise AND with a mask, so the capacity must be positive
3279 // and non-zero.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003280 DCHECK(capacity > 0);
3281 DCHECK(capacity <= kMaxCapacity);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003282 set(kCapacityIndex, Smi::FromInt(capacity));
Steve Blocka7e24c12009-10-30 11:49:00 +00003283 }
3284
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003285 // Maximal capacity of HashTable. Based on maximal length of underlying
3286 // FixedArray. Staying below kMaxCapacity also ensures that EntryToIndex
3287 // cannot overflow.
3288 static const int kMaxCapacity =
3289 (FixedArray::kMaxLength - kElementsStartOffset) / kEntrySize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003290
3291 private:
3292 // Returns _expected_ if one of entries given by the first _probe_ probes is
3293 // equal to _expected_. Otherwise, returns the entry given by the probe
3294 // number _probe_.
3295 uint32_t EntryForProbe(Key key, Object* k, int probe, uint32_t expected);
3296
3297 void Swap(uint32_t entry1, uint32_t entry2, WriteBarrierMode mode);
3298
3299 // Rehashes this hash-table into the new table.
3300 void Rehash(Handle<Derived> new_table, Key key);
Steve Blocka7e24c12009-10-30 11:49:00 +00003301};
3302
3303
Steve Blocka7e24c12009-10-30 11:49:00 +00003304// HashTableKey is an abstract superclass for virtual key behavior.
3305class HashTableKey {
3306 public:
3307 // Returns whether the other object matches this key.
3308 virtual bool IsMatch(Object* other) = 0;
3309 // Returns the hash value for this key.
3310 virtual uint32_t Hash() = 0;
3311 // Returns the hash value for object.
3312 virtual uint32_t HashForObject(Object* key) = 0;
Steve Block3ce2e202009-11-05 08:53:23 +00003313 // Returns the key object for storing into the hash table.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003314 MUST_USE_RESULT virtual Handle<Object> AsHandle(Isolate* isolate) = 0;
Steve Blocka7e24c12009-10-30 11:49:00 +00003315 // Required.
3316 virtual ~HashTableKey() {}
3317};
3318
Ben Murdochc7cc0282012-03-05 14:35:55 +00003319
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003320class StringTableShape : public BaseShape<HashTableKey*> {
Steve Blocka7e24c12009-10-30 11:49:00 +00003321 public:
Steve Block44f0eee2011-05-26 01:26:41 +01003322 static inline bool IsMatch(HashTableKey* key, Object* value) {
Steve Blocka7e24c12009-10-30 11:49:00 +00003323 return key->IsMatch(value);
3324 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003325
Steve Block44f0eee2011-05-26 01:26:41 +01003326 static inline uint32_t Hash(HashTableKey* key) {
Steve Blocka7e24c12009-10-30 11:49:00 +00003327 return key->Hash();
3328 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003329
Steve Block44f0eee2011-05-26 01:26:41 +01003330 static inline uint32_t HashForObject(HashTableKey* key, Object* object) {
Steve Blocka7e24c12009-10-30 11:49:00 +00003331 return key->HashForObject(object);
3332 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003333
3334 static inline Handle<Object> AsHandle(Isolate* isolate, HashTableKey* key);
Steve Blocka7e24c12009-10-30 11:49:00 +00003335
3336 static const int kPrefixSize = 0;
3337 static const int kEntrySize = 1;
3338};
3339
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003340class SeqOneByteString;
Ben Murdoch257744e2011-11-30 15:57:28 +00003341
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003342// StringTable.
Steve Blocka7e24c12009-10-30 11:49:00 +00003343//
3344// No special elements in the prefix and the element size is 1
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003345// because only the string itself (the key) needs to be stored.
3346class StringTable: public HashTable<StringTable,
3347 StringTableShape,
3348 HashTableKey*> {
Steve Blocka7e24c12009-10-30 11:49:00 +00003349 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003350 // Find string in the string table. If it is not there yet, it is
3351 // added. The return value is the string found.
3352 static Handle<String> LookupString(Isolate* isolate, Handle<String> key);
3353 static Handle<String> LookupKey(Isolate* isolate, HashTableKey* key);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003354 static String* LookupKeyIfExists(Isolate* isolate, HashTableKey* key);
Steve Blocka7e24c12009-10-30 11:49:00 +00003355
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003356 // Tries to internalize given string and returns string handle on success
3357 // or an empty handle otherwise.
3358 MUST_USE_RESULT static MaybeHandle<String> InternalizeStringIfExists(
3359 Isolate* isolate,
3360 Handle<String> string);
Steve Blocka7e24c12009-10-30 11:49:00 +00003361
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003362 // Looks up a string that is equal to the given string and returns
3363 // string handle if it is found, or an empty handle otherwise.
3364 MUST_USE_RESULT static MaybeHandle<String> LookupStringIfExists(
3365 Isolate* isolate,
3366 Handle<String> str);
3367 MUST_USE_RESULT static MaybeHandle<String> LookupTwoCharsStringIfExists(
3368 Isolate* isolate,
3369 uint16_t c1,
3370 uint16_t c2);
3371
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003372 static void EnsureCapacityForDeserialization(Isolate* isolate, int expected);
3373
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003374 DECLARE_CAST(StringTable)
Steve Blocka7e24c12009-10-30 11:49:00 +00003375
3376 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003377 template <bool seq_one_byte>
3378 friend class JsonParser;
Steve Blocka7e24c12009-10-30 11:49:00 +00003379
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003380 DISALLOW_IMPLICIT_CONSTRUCTORS(StringTable);
Steve Blocka7e24c12009-10-30 11:49:00 +00003381};
3382
Ben Murdochda12d292016-06-02 14:46:10 +01003383class StringSetShape : public BaseShape<String*> {
3384 public:
3385 static inline bool IsMatch(String* key, Object* value);
3386 static inline uint32_t Hash(String* key);
3387 static inline uint32_t HashForObject(String* key, Object* object);
3388
3389 static const int kPrefixSize = 0;
3390 static const int kEntrySize = 1;
3391};
3392
3393class StringSet : public HashTable<StringSet, StringSetShape, String*> {
3394 public:
3395 static Handle<StringSet> New(Isolate* isolate);
3396 static Handle<StringSet> Add(Handle<StringSet> blacklist,
3397 Handle<String> name);
3398 bool Has(Handle<String> name);
3399
3400 DECLARE_CAST(StringSet)
3401};
Steve Blocka7e24c12009-10-30 11:49:00 +00003402
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003403template <typename Derived, typename Shape, typename Key>
3404class Dictionary: public HashTable<Derived, Shape, Key> {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003405 typedef HashTable<Derived, Shape, Key> DerivedHashTable;
Steve Blocka7e24c12009-10-30 11:49:00 +00003406
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003407 public:
Steve Blocka7e24c12009-10-30 11:49:00 +00003408 // Returns the value at entry.
3409 Object* ValueAt(int entry) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003410 return this->get(Derived::EntryToIndex(entry) + 1);
Steve Blocka7e24c12009-10-30 11:49:00 +00003411 }
3412
3413 // Set the value for entry.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003414 void ValueAtPut(int entry, Object* value) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003415 this->set(Derived::EntryToIndex(entry) + 1, value);
Steve Blocka7e24c12009-10-30 11:49:00 +00003416 }
3417
3418 // Returns the property details for the property at entry.
3419 PropertyDetails DetailsAt(int entry) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003420 return Shape::DetailsAt(static_cast<Derived*>(this), entry);
Steve Blocka7e24c12009-10-30 11:49:00 +00003421 }
3422
3423 // Set the details for entry.
3424 void DetailsAtPut(int entry, PropertyDetails value) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003425 Shape::DetailsAtPut(static_cast<Derived*>(this), entry, value);
Steve Blocka7e24c12009-10-30 11:49:00 +00003426 }
3427
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003428 // Returns true if property at given entry is deleted.
3429 bool IsDeleted(int entry) {
3430 return Shape::IsDeleted(static_cast<Derived*>(this), entry);
3431 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003432
3433 // Delete a property from the dictionary.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003434 static Handle<Object> DeleteProperty(Handle<Derived> dictionary, int entry);
Steve Blocka7e24c12009-10-30 11:49:00 +00003435
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003436 // Attempt to shrink the dictionary after deletion of key.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003437 MUST_USE_RESULT static inline Handle<Derived> Shrink(
3438 Handle<Derived> dictionary,
3439 Key key) {
3440 return DerivedHashTable::Shrink(dictionary, key);
3441 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003442
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003443 // Sorting support
3444 // TODO(dcarney): templatize or move to SeededNumberDictionary
3445 void CopyValuesTo(FixedArray* elements);
3446
Steve Blocka7e24c12009-10-30 11:49:00 +00003447 // Returns the number of elements in the dictionary filtering out properties
3448 // with the specified attributes.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003449 int NumberOfElementsFilterAttributes(PropertyFilter filter);
Steve Blocka7e24c12009-10-30 11:49:00 +00003450
3451 // Returns the number of enumerable elements in the dictionary.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003452 int NumberOfEnumElements() {
3453 return NumberOfElementsFilterAttributes(ENUMERABLE_STRINGS);
3454 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003455
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003456 enum SortMode { UNSORTED, SORTED };
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003457
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003458 // Collect the keys into the given KeyAccumulator, in ascending chronological
3459 // order of property creation.
3460 static void CollectKeysTo(Handle<Dictionary<Derived, Shape, Key> > dictionary,
3461 KeyAccumulator* keys, PropertyFilter filter);
3462
3463 // Copies enumerable keys to preallocated fixed array.
3464 void CopyEnumKeysTo(FixedArray* storage);
Steve Blocka7e24c12009-10-30 11:49:00 +00003465
3466 // Accessors for next enumeration index.
3467 void SetNextEnumerationIndex(int index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003468 DCHECK(index != 0);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003469 this->set(kNextEnumerationIndexIndex, Smi::FromInt(index));
Steve Blocka7e24c12009-10-30 11:49:00 +00003470 }
3471
3472 int NextEnumerationIndex() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003473 return Smi::cast(this->get(kNextEnumerationIndexIndex))->value();
Steve Blocka7e24c12009-10-30 11:49:00 +00003474 }
3475
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003476 // Creates a new dictionary.
3477 MUST_USE_RESULT static Handle<Derived> New(
3478 Isolate* isolate,
3479 int at_least_space_for,
3480 PretenureFlag pretenure = NOT_TENURED);
Steve Blocka7e24c12009-10-30 11:49:00 +00003481
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003482 // Ensures that a new dictionary is created when the capacity is checked.
3483 void SetRequiresCopyOnCapacityChange();
3484
Steve Blocka7e24c12009-10-30 11:49:00 +00003485 // Ensure enough space for n additional elements.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003486 static Handle<Derived> EnsureCapacity(Handle<Derived> obj, int n, Key key);
Steve Blocka7e24c12009-10-30 11:49:00 +00003487
Ben Murdochb0fe1622011-05-05 13:52:32 +01003488#ifdef OBJECT_PRINT
Ben Murdoch61f157c2016-09-16 13:49:30 +01003489 // For our gdb macros, we should perhaps change these in the future.
3490 void Print();
3491
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003492 void Print(std::ostream& os); // NOLINT
Steve Blocka7e24c12009-10-30 11:49:00 +00003493#endif
3494 // Returns the key (slow).
3495 Object* SlowReverseLookup(Object* value);
3496
3497 // Sets the entry to (key, value) pair.
3498 inline void SetEntry(int entry,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003499 Handle<Object> key,
3500 Handle<Object> value);
Ben Murdoch8b112d22011-06-08 16:22:53 +01003501 inline void SetEntry(int entry,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003502 Handle<Object> key,
3503 Handle<Object> value,
Steve Blocka7e24c12009-10-30 11:49:00 +00003504 PropertyDetails details);
3505
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003506 MUST_USE_RESULT static Handle<Derived> Add(
3507 Handle<Derived> dictionary,
3508 Key key,
3509 Handle<Object> value,
3510 PropertyDetails details);
Steve Blocka7e24c12009-10-30 11:49:00 +00003511
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003512 // Returns iteration indices array for the |dictionary|.
3513 // Values are direct indices in the |HashTable| array.
3514 static Handle<FixedArray> BuildIterationIndicesArray(
3515 Handle<Derived> dictionary);
3516
Steve Blocka7e24c12009-10-30 11:49:00 +00003517 protected:
3518 // Generic at put operation.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003519 MUST_USE_RESULT static Handle<Derived> AtPut(
3520 Handle<Derived> dictionary,
3521 Key key,
3522 Handle<Object> value);
Steve Blocka7e24c12009-10-30 11:49:00 +00003523
3524 // Add entry to dictionary.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003525 static void AddEntry(
3526 Handle<Derived> dictionary,
3527 Key key,
3528 Handle<Object> value,
3529 PropertyDetails details,
3530 uint32_t hash);
Steve Blocka7e24c12009-10-30 11:49:00 +00003531
3532 // Generate new enumeration indices to avoid enumeration index overflow.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003533 // Returns iteration indices array for the |dictionary|.
3534 static Handle<FixedArray> GenerateNewEnumerationIndices(
3535 Handle<Derived> dictionary);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003536 static const int kMaxNumberKeyIndex = DerivedHashTable::kPrefixStartIndex;
Steve Blocka7e24c12009-10-30 11:49:00 +00003537 static const int kNextEnumerationIndexIndex = kMaxNumberKeyIndex + 1;
3538};
3539
3540
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003541template <typename Derived, typename Shape>
3542class NameDictionaryBase : public Dictionary<Derived, Shape, Handle<Name> > {
3543 typedef Dictionary<Derived, Shape, Handle<Name> > DerivedDictionary;
3544
3545 public:
3546 // Find entry for key, otherwise return kNotFound. Optimized version of
3547 // HashTable::FindEntry.
3548 int FindEntry(Handle<Name> key);
3549};
3550
3551
3552template <typename Key>
3553class BaseDictionaryShape : public BaseShape<Key> {
3554 public:
3555 template <typename Dictionary>
3556 static inline PropertyDetails DetailsAt(Dictionary* dict, int entry) {
3557 STATIC_ASSERT(Dictionary::kEntrySize == 3);
3558 DCHECK(entry >= 0); // Not found is -1, which is not caught by get().
Ben Murdoch61f157c2016-09-16 13:49:30 +01003559 return PropertyDetails(Smi::cast(dict->get(
3560 Dictionary::EntryToIndex(entry) + Dictionary::kEntryDetailsIndex)));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003561 }
3562
3563 template <typename Dictionary>
3564 static inline void DetailsAtPut(Dictionary* dict, int entry,
3565 PropertyDetails value) {
3566 STATIC_ASSERT(Dictionary::kEntrySize == 3);
Ben Murdoch61f157c2016-09-16 13:49:30 +01003567 dict->set(Dictionary::EntryToIndex(entry) + Dictionary::kEntryDetailsIndex,
3568 value.AsSmi());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003569 }
3570
3571 template <typename Dictionary>
3572 static bool IsDeleted(Dictionary* dict, int entry) {
3573 return false;
3574 }
3575
3576 template <typename Dictionary>
3577 static inline void SetEntry(Dictionary* dict, int entry, Handle<Object> key,
3578 Handle<Object> value, PropertyDetails details);
3579};
3580
3581
3582class NameDictionaryShape : public BaseDictionaryShape<Handle<Name> > {
Steve Blocka7e24c12009-10-30 11:49:00 +00003583 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003584 static inline bool IsMatch(Handle<Name> key, Object* other);
3585 static inline uint32_t Hash(Handle<Name> key);
3586 static inline uint32_t HashForObject(Handle<Name> key, Object* object);
3587 static inline Handle<Object> AsHandle(Isolate* isolate, Handle<Name> key);
Steve Blocka7e24c12009-10-30 11:49:00 +00003588 static const int kPrefixSize = 2;
3589 static const int kEntrySize = 3;
Ben Murdoch61f157c2016-09-16 13:49:30 +01003590 static const int kEntryValueIndex = 1;
3591 static const int kEntryDetailsIndex = 2;
Steve Blocka7e24c12009-10-30 11:49:00 +00003592 static const bool kIsEnumerable = true;
3593};
3594
3595
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003596class NameDictionary
3597 : public NameDictionaryBase<NameDictionary, NameDictionaryShape> {
3598 typedef NameDictionaryBase<NameDictionary, NameDictionaryShape>
3599 DerivedDictionary;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003600
Steve Blocka7e24c12009-10-30 11:49:00 +00003601 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003602 DECLARE_CAST(NameDictionary)
Steve Blocka7e24c12009-10-30 11:49:00 +00003603
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003604 inline static Handle<FixedArray> DoGenerateNewEnumerationIndices(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003605 Handle<NameDictionary> dictionary);
Ben Murdoch61f157c2016-09-16 13:49:30 +01003606
3607 static const int kEntryValueIndex = 1;
3608 static const int kEntryDetailsIndex = 2;
Steve Blocka7e24c12009-10-30 11:49:00 +00003609};
3610
3611
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003612class GlobalDictionaryShape : public NameDictionaryShape {
3613 public:
3614 static const int kEntrySize = 2; // Overrides NameDictionaryShape::kEntrySize
3615
3616 template <typename Dictionary>
3617 static inline PropertyDetails DetailsAt(Dictionary* dict, int entry);
3618
3619 template <typename Dictionary>
3620 static inline void DetailsAtPut(Dictionary* dict, int entry,
3621 PropertyDetails value);
3622
3623 template <typename Dictionary>
3624 static bool IsDeleted(Dictionary* dict, int entry);
3625
3626 template <typename Dictionary>
3627 static inline void SetEntry(Dictionary* dict, int entry, Handle<Object> key,
3628 Handle<Object> value, PropertyDetails details);
3629};
3630
3631
3632class GlobalDictionary
3633 : public NameDictionaryBase<GlobalDictionary, GlobalDictionaryShape> {
3634 public:
3635 DECLARE_CAST(GlobalDictionary)
Ben Murdoch61f157c2016-09-16 13:49:30 +01003636
3637 static const int kEntryValueIndex = 1;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003638};
3639
3640
3641class NumberDictionaryShape : public BaseDictionaryShape<uint32_t> {
Steve Blocka7e24c12009-10-30 11:49:00 +00003642 public:
3643 static inline bool IsMatch(uint32_t key, Object* other);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003644 static inline Handle<Object> AsHandle(Isolate* isolate, uint32_t key);
Steve Blocka7e24c12009-10-30 11:49:00 +00003645 static const int kEntrySize = 3;
3646 static const bool kIsEnumerable = false;
3647};
3648
3649
Ben Murdochc7cc0282012-03-05 14:35:55 +00003650class SeededNumberDictionaryShape : public NumberDictionaryShape {
Steve Blocka7e24c12009-10-30 11:49:00 +00003651 public:
Ben Murdochc7cc0282012-03-05 14:35:55 +00003652 static const bool UsesSeed = true;
3653 static const int kPrefixSize = 2;
3654
3655 static inline uint32_t SeededHash(uint32_t key, uint32_t seed);
3656 static inline uint32_t SeededHashForObject(uint32_t key,
3657 uint32_t seed,
3658 Object* object);
3659};
3660
3661
3662class UnseededNumberDictionaryShape : public NumberDictionaryShape {
3663 public:
3664 static const int kPrefixSize = 0;
3665
3666 static inline uint32_t Hash(uint32_t key);
3667 static inline uint32_t HashForObject(uint32_t key, Object* object);
3668};
3669
3670
3671class SeededNumberDictionary
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003672 : public Dictionary<SeededNumberDictionary,
3673 SeededNumberDictionaryShape,
3674 uint32_t> {
Ben Murdochc7cc0282012-03-05 14:35:55 +00003675 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003676 DECLARE_CAST(SeededNumberDictionary)
Steve Blocka7e24c12009-10-30 11:49:00 +00003677
3678 // Type specific at put (default NONE attributes is used when adding).
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003679 MUST_USE_RESULT static Handle<SeededNumberDictionary> AtNumberPut(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003680 Handle<SeededNumberDictionary> dictionary, uint32_t key,
3681 Handle<Object> value, bool used_as_prototype);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003682 MUST_USE_RESULT static Handle<SeededNumberDictionary> AddNumberEntry(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003683 Handle<SeededNumberDictionary> dictionary, uint32_t key,
3684 Handle<Object> value, PropertyDetails details, bool used_as_prototype);
Steve Blocka7e24c12009-10-30 11:49:00 +00003685
3686 // Set an existing entry or add a new one if needed.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003687 // Return the updated dictionary.
3688 MUST_USE_RESULT static Handle<SeededNumberDictionary> Set(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003689 Handle<SeededNumberDictionary> dictionary, uint32_t key,
3690 Handle<Object> value, PropertyDetails details, bool used_as_prototype);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003691
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003692 void UpdateMaxNumberKey(uint32_t key, bool used_as_prototype);
Steve Blocka7e24c12009-10-30 11:49:00 +00003693
Ben Murdochda12d292016-06-02 14:46:10 +01003694 // Returns true if the dictionary contains any elements that are non-writable,
3695 // non-configurable, non-enumerable, or have getters/setters.
3696 bool HasComplexElements();
3697
Steve Blocka7e24c12009-10-30 11:49:00 +00003698 // If slow elements are required we will never go back to fast-case
3699 // for the elements kept in this dictionary. We require slow
3700 // elements if an element has been added at an index larger than
3701 // kRequiresSlowElementsLimit or set_requires_slow_elements() has been called
3702 // when defining a getter or setter with a number key.
3703 inline bool requires_slow_elements();
3704 inline void set_requires_slow_elements();
3705
3706 // Get the value of the max number key that has been added to this
3707 // dictionary. max_number_key can only be called if
3708 // requires_slow_elements returns false.
3709 inline uint32_t max_number_key();
3710
Ben Murdoch61f157c2016-09-16 13:49:30 +01003711 static const int kEntryValueIndex = 1;
3712 static const int kEntryDetailsIndex = 2;
3713
Steve Blocka7e24c12009-10-30 11:49:00 +00003714 // Bit masks.
3715 static const int kRequiresSlowElementsMask = 1;
3716 static const int kRequiresSlowElementsTagSize = 1;
3717 static const uint32_t kRequiresSlowElementsLimit = (1 << 29) - 1;
3718};
3719
3720
Ben Murdochc7cc0282012-03-05 14:35:55 +00003721class UnseededNumberDictionary
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003722 : public Dictionary<UnseededNumberDictionary,
3723 UnseededNumberDictionaryShape,
3724 uint32_t> {
Ben Murdochc7cc0282012-03-05 14:35:55 +00003725 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003726 DECLARE_CAST(UnseededNumberDictionary)
Ben Murdochc7cc0282012-03-05 14:35:55 +00003727
3728 // Type specific at put (default NONE attributes is used when adding).
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003729 MUST_USE_RESULT static Handle<UnseededNumberDictionary> AtNumberPut(
3730 Handle<UnseededNumberDictionary> dictionary,
3731 uint32_t key,
3732 Handle<Object> value);
3733 MUST_USE_RESULT static Handle<UnseededNumberDictionary> AddNumberEntry(
3734 Handle<UnseededNumberDictionary> dictionary,
3735 uint32_t key,
3736 Handle<Object> value);
Ben Murdochc7cc0282012-03-05 14:35:55 +00003737
3738 // Set an existing entry or add a new one if needed.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003739 // Return the updated dictionary.
3740 MUST_USE_RESULT static Handle<UnseededNumberDictionary> Set(
3741 Handle<UnseededNumberDictionary> dictionary,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003742 uint32_t key,
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003743 Handle<Object> value);
Ben Murdoch61f157c2016-09-16 13:49:30 +01003744
3745 static const int kEntryValueIndex = 1;
3746 static const int kEntryDetailsIndex = 2;
Ben Murdochc7cc0282012-03-05 14:35:55 +00003747};
3748
3749
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003750class ObjectHashTableShape : public BaseShape<Handle<Object> > {
Ben Murdoch2b4ba112012-01-20 14:57:15 +00003751 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003752 static inline bool IsMatch(Handle<Object> key, Object* other);
3753 static inline uint32_t Hash(Handle<Object> key);
3754 static inline uint32_t HashForObject(Handle<Object> key, Object* object);
3755 static inline Handle<Object> AsHandle(Isolate* isolate, Handle<Object> key);
Ben Murdoch592a9fc2012-03-05 11:04:45 +00003756 static const int kPrefixSize = 0;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003757 static const int kEntrySize = 2;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003758};
3759
3760
3761// ObjectHashTable maps keys that are arbitrary objects to object values by
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003762// using the identity hash of the key for hashing purposes.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003763class ObjectHashTable: public HashTable<ObjectHashTable,
3764 ObjectHashTableShape,
3765 Handle<Object> > {
3766 typedef HashTable<
3767 ObjectHashTable, ObjectHashTableShape, Handle<Object> > DerivedHashTable;
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003768 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003769 DECLARE_CAST(ObjectHashTable)
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003770
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003771 // Attempt to shrink hash table after removal of key.
3772 MUST_USE_RESULT static inline Handle<ObjectHashTable> Shrink(
3773 Handle<ObjectHashTable> table,
3774 Handle<Object> key);
3775
3776 // Looks up the value associated with the given key. The hole value is
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003777 // returned in case the key is not present.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003778 Object* Lookup(Handle<Object> key);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003779 Object* Lookup(Handle<Object> key, int32_t hash);
3780 Object* Lookup(Isolate* isolate, Handle<Object> key, int32_t hash);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003781
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003782 // Adds (or overwrites) the value associated with the given key.
3783 static Handle<ObjectHashTable> Put(Handle<ObjectHashTable> table,
3784 Handle<Object> key,
3785 Handle<Object> value);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003786 static Handle<ObjectHashTable> Put(Handle<ObjectHashTable> table,
3787 Handle<Object> key, Handle<Object> value,
3788 int32_t hash);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003789
3790 // Returns an ObjectHashTable (possibly |table|) where |key| has been removed.
3791 static Handle<ObjectHashTable> Remove(Handle<ObjectHashTable> table,
3792 Handle<Object> key,
3793 bool* was_present);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003794 static Handle<ObjectHashTable> Remove(Handle<ObjectHashTable> table,
3795 Handle<Object> key, bool* was_present,
3796 int32_t hash);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003797
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003798 protected:
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003799 friend class MarkCompactCollector;
3800
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003801 void AddEntry(int entry, Object* key, Object* value);
3802 void RemoveEntry(int entry);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003803
3804 // Returns the index to the value of an entry.
3805 static inline int EntryToValueIndex(int entry) {
3806 return EntryToIndex(entry) + 1;
3807 }
3808};
3809
3810
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003811// OrderedHashTable is a HashTable with Object keys that preserves
3812// insertion order. There are Map and Set interfaces (OrderedHashMap
3813// and OrderedHashTable, below). It is meant to be used by JSMap/JSSet.
3814//
3815// Only Object* keys are supported, with Object::SameValueZero() used as the
3816// equality operator and Object::GetHash() for the hash function.
3817//
3818// Based on the "Deterministic Hash Table" as described by Jason Orendorff at
3819// https://wiki.mozilla.org/User:Jorend/Deterministic_hash_tables
3820// Originally attributed to Tyler Close.
3821//
3822// Memory layout:
3823// [0]: bucket count
3824// [1]: element count
3825// [2]: deleted element count
3826// [3..(3 + NumberOfBuckets() - 1)]: "hash table", where each item is an
3827// offset into the data table (see below) where the
3828// first item in this bucket is stored.
3829// [3 + NumberOfBuckets()..length]: "data table", an array of length
3830// Capacity() * kEntrySize, where the first entrysize
3831// items are handled by the derived class and the
3832// item at kChainOffset is another entry into the
3833// data table indicating the next entry in this hash
3834// bucket.
3835//
3836// When we transition the table to a new version we obsolete it and reuse parts
3837// of the memory to store information how to transition an iterator to the new
3838// table:
3839//
3840// Memory layout for obsolete table:
3841// [0]: bucket count
3842// [1]: Next newer table
3843// [2]: Number of removed holes or -1 when the table was cleared.
3844// [3..(3 + NumberOfRemovedHoles() - 1)]: The indexes of the removed holes.
3845// [3 + NumberOfRemovedHoles()..length]: Not used
3846//
3847template<class Derived, class Iterator, int entrysize>
3848class OrderedHashTable: public FixedArray {
3849 public:
3850 // Returns an OrderedHashTable with a capacity of at least |capacity|.
3851 static Handle<Derived> Allocate(
3852 Isolate* isolate, int capacity, PretenureFlag pretenure = NOT_TENURED);
3853
3854 // Returns an OrderedHashTable (possibly |table|) with enough space
3855 // to add at least one new element.
3856 static Handle<Derived> EnsureGrowable(Handle<Derived> table);
3857
3858 // Returns an OrderedHashTable (possibly |table|) that's shrunken
3859 // if possible.
3860 static Handle<Derived> Shrink(Handle<Derived> table);
3861
3862 // Returns a new empty OrderedHashTable and records the clearing so that
Ben Murdochc5610432016-08-08 18:44:38 +01003863 // existing iterators can be updated.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003864 static Handle<Derived> Clear(Handle<Derived> table);
3865
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003866 // Returns a true if the OrderedHashTable contains the key
3867 static bool HasKey(Handle<Derived> table, Handle<Object> key);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003868
3869 int NumberOfElements() {
3870 return Smi::cast(get(kNumberOfElementsIndex))->value();
3871 }
3872
3873 int NumberOfDeletedElements() {
3874 return Smi::cast(get(kNumberOfDeletedElementsIndex))->value();
3875 }
3876
Ben Murdochc5610432016-08-08 18:44:38 +01003877 // Returns the number of contiguous entries in the data table, starting at 0,
3878 // that either are real entries or have been deleted.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003879 int UsedCapacity() { return NumberOfElements() + NumberOfDeletedElements(); }
3880
3881 int NumberOfBuckets() {
3882 return Smi::cast(get(kNumberOfBucketsIndex))->value();
3883 }
3884
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003885 // Returns an index into |this| for the given entry.
3886 int EntryToIndex(int entry) {
3887 return kHashTableStartIndex + NumberOfBuckets() + (entry * kEntrySize);
3888 }
3889
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003890 int HashToBucket(int hash) { return hash & (NumberOfBuckets() - 1); }
3891
3892 int HashToEntry(int hash) {
3893 int bucket = HashToBucket(hash);
3894 Object* entry = this->get(kHashTableStartIndex + bucket);
3895 return Smi::cast(entry)->value();
3896 }
3897
Ben Murdoch61f157c2016-09-16 13:49:30 +01003898 int KeyToFirstEntry(Isolate* isolate, Object* key) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003899 Object* hash = key->GetHash();
3900 // If the object does not have an identity hash, it was never used as a key
Ben Murdoch61f157c2016-09-16 13:49:30 +01003901 if (hash->IsUndefined(isolate)) return kNotFound;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003902 return HashToEntry(Smi::cast(hash)->value());
3903 }
3904
3905 int NextChainEntry(int entry) {
3906 Object* next_entry = get(EntryToIndex(entry) + kChainOffset);
3907 return Smi::cast(next_entry)->value();
3908 }
3909
Ben Murdoch61f157c2016-09-16 13:49:30 +01003910 // use KeyAt(i)->IsTheHole(isolate) to determine if this is a deleted entry.
Ben Murdochc5610432016-08-08 18:44:38 +01003911 Object* KeyAt(int entry) {
3912 DCHECK_LT(entry, this->UsedCapacity());
3913 return get(EntryToIndex(entry));
3914 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003915
3916 bool IsObsolete() {
3917 return !get(kNextTableIndex)->IsSmi();
3918 }
3919
3920 // The next newer table. This is only valid if the table is obsolete.
3921 Derived* NextTable() {
3922 return Derived::cast(get(kNextTableIndex));
3923 }
3924
3925 // When the table is obsolete we store the indexes of the removed holes.
3926 int RemovedIndexAt(int index) {
3927 return Smi::cast(get(kRemovedHolesIndex + index))->value();
3928 }
3929
3930 static const int kNotFound = -1;
3931 static const int kMinCapacity = 4;
3932
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003933 static const int kNumberOfBucketsIndex = 0;
3934 static const int kNumberOfElementsIndex = kNumberOfBucketsIndex + 1;
3935 static const int kNumberOfDeletedElementsIndex = kNumberOfElementsIndex + 1;
3936 static const int kHashTableStartIndex = kNumberOfDeletedElementsIndex + 1;
3937 static const int kNextTableIndex = kNumberOfElementsIndex;
3938
3939 static const int kNumberOfBucketsOffset =
3940 kHeaderSize + kNumberOfBucketsIndex * kPointerSize;
3941 static const int kNumberOfElementsOffset =
3942 kHeaderSize + kNumberOfElementsIndex * kPointerSize;
3943 static const int kNumberOfDeletedElementsOffset =
3944 kHeaderSize + kNumberOfDeletedElementsIndex * kPointerSize;
3945 static const int kHashTableStartOffset =
3946 kHeaderSize + kHashTableStartIndex * kPointerSize;
3947 static const int kNextTableOffset =
3948 kHeaderSize + kNextTableIndex * kPointerSize;
3949
3950 static const int kEntrySize = entrysize + 1;
3951 static const int kChainOffset = entrysize;
3952
3953 static const int kLoadFactor = 2;
3954
3955 // NumberOfDeletedElements is set to kClearedTableSentinel when
3956 // the table is cleared, which allows iterator transitions to
3957 // optimize that case.
3958 static const int kClearedTableSentinel = -1;
3959
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003960 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003961 static Handle<Derived> Rehash(Handle<Derived> table, int new_capacity);
3962
3963 void SetNumberOfBuckets(int num) {
3964 set(kNumberOfBucketsIndex, Smi::FromInt(num));
3965 }
3966
3967 void SetNumberOfElements(int num) {
3968 set(kNumberOfElementsIndex, Smi::FromInt(num));
3969 }
3970
3971 void SetNumberOfDeletedElements(int num) {
3972 set(kNumberOfDeletedElementsIndex, Smi::FromInt(num));
3973 }
3974
Ben Murdochc5610432016-08-08 18:44:38 +01003975 // Returns the number elements that can fit into the allocated buffer.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003976 int Capacity() {
3977 return NumberOfBuckets() * kLoadFactor;
3978 }
3979
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003980 void SetNextTable(Derived* next_table) {
3981 set(kNextTableIndex, next_table);
3982 }
3983
3984 void SetRemovedIndexAt(int index, int removed_index) {
3985 return set(kRemovedHolesIndex + index, Smi::FromInt(removed_index));
3986 }
3987
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003988 static const int kRemovedHolesIndex = kHashTableStartIndex;
3989
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003990 static const int kMaxCapacity =
3991 (FixedArray::kMaxLength - kHashTableStartIndex)
3992 / (1 + (kEntrySize * kLoadFactor));
3993};
3994
3995
3996class JSSetIterator;
3997
3998
3999class OrderedHashSet: public OrderedHashTable<
4000 OrderedHashSet, JSSetIterator, 1> {
4001 public:
4002 DECLARE_CAST(OrderedHashSet)
4003
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004004 static Handle<OrderedHashSet> Add(Handle<OrderedHashSet> table,
4005 Handle<Object> value);
Ben Murdoch61f157c2016-09-16 13:49:30 +01004006 static Handle<FixedArray> ConvertToKeysArray(Handle<OrderedHashSet> table,
4007 GetKeysConversion convert);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004008};
4009
4010
4011class JSMapIterator;
4012
4013
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004014class OrderedHashMap
4015 : public OrderedHashTable<OrderedHashMap, JSMapIterator, 2> {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004016 public:
4017 DECLARE_CAST(OrderedHashMap)
4018
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004019 inline Object* ValueAt(int entry);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004020
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004021 static const int kValueOffset = 1;
4022};
4023
4024
4025template <int entrysize>
4026class WeakHashTableShape : public BaseShape<Handle<Object> > {
4027 public:
4028 static inline bool IsMatch(Handle<Object> key, Object* other);
4029 static inline uint32_t Hash(Handle<Object> key);
4030 static inline uint32_t HashForObject(Handle<Object> key, Object* object);
4031 static inline Handle<Object> AsHandle(Isolate* isolate, Handle<Object> key);
4032 static const int kPrefixSize = 0;
4033 static const int kEntrySize = entrysize;
4034};
4035
4036
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004037// WeakHashTable maps keys that are arbitrary heap objects to heap object
4038// values. The table wraps the keys in weak cells and store values directly.
4039// Thus it references keys weakly and values strongly.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004040class WeakHashTable: public HashTable<WeakHashTable,
4041 WeakHashTableShape<2>,
4042 Handle<Object> > {
4043 typedef HashTable<
4044 WeakHashTable, WeakHashTableShape<2>, Handle<Object> > DerivedHashTable;
4045 public:
4046 DECLARE_CAST(WeakHashTable)
4047
4048 // Looks up the value associated with the given key. The hole value is
4049 // returned in case the key is not present.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004050 Object* Lookup(Handle<HeapObject> key);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004051
4052 // Adds (or overwrites) the value associated with the given key. Mapping a
4053 // key to the hole value causes removal of the whole entry.
4054 MUST_USE_RESULT static Handle<WeakHashTable> Put(Handle<WeakHashTable> table,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004055 Handle<HeapObject> key,
4056 Handle<HeapObject> value);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004057
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004058 static Handle<FixedArray> GetValues(Handle<WeakHashTable> table);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004059
4060 private:
4061 friend class MarkCompactCollector;
4062
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004063 void AddEntry(int entry, Handle<WeakCell> key, Handle<HeapObject> value);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004064
4065 // Returns the index to the value of an entry.
4066 static inline int EntryToValueIndex(int entry) {
4067 return EntryToIndex(entry) + 1;
4068 }
4069};
4070
4071
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004072// ScopeInfo represents information about different scopes of a source
4073// program and the allocation of the scope's variables. Scope information
4074// is stored in a compressed form in ScopeInfo objects and is used
4075// at runtime (stack dumps, deoptimization, etc.).
4076
4077// This object provides quick access to scope info details for runtime
4078// routines.
4079class ScopeInfo : public FixedArray {
4080 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004081 DECLARE_CAST(ScopeInfo)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004082
4083 // Return the type of this scope.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004084 ScopeType scope_type();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004085
4086 // Does this scope call eval?
4087 bool CallsEval();
4088
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004089 // Return the language mode of this scope.
4090 LanguageMode language_mode();
4091
4092 // True if this scope is a (var) declaration scope.
4093 bool is_declaration_scope();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004094
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004095 // Does this scope make a sloppy eval call?
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004096 bool CallsSloppyEval() { return CallsEval() && is_sloppy(language_mode()); }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004097
4098 // Return the total number of locals allocated on the stack and in the
4099 // context. This includes the parameters that are allocated in the context.
4100 int LocalCount();
4101
4102 // Return the number of stack slots for code. This number consists of two
4103 // parts:
4104 // 1. One stack slot per stack allocated local.
4105 // 2. One stack slot for the function name if it is stack allocated.
4106 int StackSlotCount();
4107
4108 // Return the number of context slots for code if a context is allocated. This
4109 // number consists of three parts:
4110 // 1. Size of fixed header for every context: Context::MIN_CONTEXT_SLOTS
4111 // 2. One context slot per context allocated local.
4112 // 3. One context slot for the function name if it is context allocated.
4113 // Parameters allocated in the context count as context allocated locals. If
4114 // no contexts are allocated for this scope ContextLength returns 0.
4115 int ContextLength();
4116
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004117 // Does this scope declare a "this" binding?
4118 bool HasReceiver();
4119
4120 // Does this scope declare a "this" binding, and the "this" binding is stack-
4121 // or context-allocated?
4122 bool HasAllocatedReceiver();
4123
4124 // Does this scope declare a "new.target" binding?
4125 bool HasNewTarget();
4126
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004127 // Is this scope the scope of a named function expression?
4128 bool HasFunctionName();
4129
4130 // Return if this has context allocated locals.
4131 bool HasHeapAllocatedLocals();
4132
4133 // Return if contexts are allocated for this scope.
4134 bool HasContext();
4135
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004136 // Return if this is a function scope with "use asm".
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004137 inline bool IsAsmModule();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004138
4139 // Return if this is a nested function within an asm module scope.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004140 inline bool IsAsmFunction();
4141
4142 inline bool HasSimpleParameters();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004143
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004144 // Return the function_name if present.
4145 String* FunctionName();
4146
4147 // Return the name of the given parameter.
4148 String* ParameterName(int var);
4149
4150 // Return the name of the given local.
4151 String* LocalName(int var);
4152
4153 // Return the name of the given stack local.
4154 String* StackLocalName(int var);
4155
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004156 // Return the name of the given stack local.
4157 int StackLocalIndex(int var);
4158
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004159 // Return the name of the given context local.
4160 String* ContextLocalName(int var);
4161
4162 // Return the mode of the given context local.
4163 VariableMode ContextLocalMode(int var);
4164
4165 // Return the initialization flag of the given context local.
4166 InitializationFlag ContextLocalInitFlag(int var);
4167
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004168 // Return the initialization flag of the given context local.
4169 MaybeAssignedFlag ContextLocalMaybeAssignedFlag(int var);
4170
4171 // Return true if this local was introduced by the compiler, and should not be
4172 // exposed to the user in a debugger.
Ben Murdochc5610432016-08-08 18:44:38 +01004173 static bool VariableIsSynthetic(String* name);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004174
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004175 // Lookup support for serialized scope info. Returns the
4176 // the stack slot index for a given slot name if the slot is
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004177 // present; otherwise returns a value < 0. The name must be an internalized
4178 // string.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004179 int StackSlotIndex(String* name);
4180
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004181 // Lookup support for serialized scope info. Returns the local context slot
4182 // index for a given slot name if the slot is present; otherwise
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004183 // returns a value < 0. The name must be an internalized string.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004184 // If the slot is present and mode != NULL, sets *mode to the corresponding
4185 // mode for that variable.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004186 static int ContextSlotIndex(Handle<ScopeInfo> scope_info, Handle<String> name,
4187 VariableMode* mode, InitializationFlag* init_flag,
4188 MaybeAssignedFlag* maybe_assigned_flag);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004189
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004190 // Similar to ContextSlotIndex() but this method searches only among
4191 // global slots of the serialized scope info. Returns the context slot index
4192 // for a given slot name if the slot is present; otherwise returns a
4193 // value < 0. The name must be an internalized string. If the slot is present
4194 // and mode != NULL, sets *mode to the corresponding mode for that variable.
4195 static int ContextGlobalSlotIndex(Handle<ScopeInfo> scope_info,
4196 Handle<String> name, VariableMode* mode,
4197 InitializationFlag* init_flag,
4198 MaybeAssignedFlag* maybe_assigned_flag);
4199
4200 // Lookup the name of a certain context slot by its index.
4201 String* ContextSlotName(int slot_index);
4202
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004203 // Lookup support for serialized scope info. Returns the
4204 // parameter index for a given parameter name if the parameter is present;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004205 // otherwise returns a value < 0. The name must be an internalized string.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004206 int ParameterIndex(String* name);
4207
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004208 // Lookup support for serialized scope info. Returns the function context
4209 // slot index if the function name is present and context-allocated (named
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004210 // function expressions, only), otherwise returns a value < 0. The name
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004211 // must be an internalized string.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004212 int FunctionContextSlotIndex(String* name, VariableMode* mode);
4213
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004214 // Lookup support for serialized scope info. Returns the receiver context
4215 // slot index if scope has a "this" binding, and the binding is
4216 // context-allocated. Otherwise returns a value < 0.
4217 int ReceiverContextSlotIndex();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004218
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004219 FunctionKind function_kind();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004220
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004221 static Handle<ScopeInfo> Create(Isolate* isolate, Zone* zone, Scope* scope);
4222 static Handle<ScopeInfo> CreateGlobalThisBinding(Isolate* isolate);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004223
4224 // Serializes empty scope info.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004225 static ScopeInfo* Empty(Isolate* isolate);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004226
4227#ifdef DEBUG
4228 void Print();
4229#endif
4230
4231 // The layout of the static part of a ScopeInfo is as follows. Each entry is
4232 // numeric and occupies one array slot.
4233 // 1. A set of properties of the scope
4234 // 2. The number of parameters. This only applies to function scopes. For
4235 // non-function scopes this is 0.
4236 // 3. The number of non-parameter variables allocated on the stack.
4237 // 4. The number of non-parameter and parameter variables allocated in the
4238 // context.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004239#define FOR_EACH_SCOPE_INFO_NUMERIC_FIELD(V) \
4240 V(Flags) \
4241 V(ParameterCount) \
4242 V(StackLocalCount) \
4243 V(ContextLocalCount) \
Ben Murdoch097c5b22016-05-18 11:27:45 +01004244 V(ContextGlobalCount)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004245
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004246#define FIELD_ACCESSORS(name) \
4247 inline void Set##name(int value); \
4248 inline int name();
4249 FOR_EACH_SCOPE_INFO_NUMERIC_FIELD(FIELD_ACCESSORS)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004250#undef FIELD_ACCESSORS
4251
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004252 enum {
4253#define DECL_INDEX(name) k##name,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004254 FOR_EACH_SCOPE_INFO_NUMERIC_FIELD(DECL_INDEX)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004255#undef DECL_INDEX
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004256 kVariablePartIndex
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004257 };
4258
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004259 private:
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004260 // The layout of the variable part of a ScopeInfo is as follows:
4261 // 1. ParameterEntries:
4262 // This part stores the names of the parameters for function scopes. One
4263 // slot is used per parameter, so in total this part occupies
4264 // ParameterCount() slots in the array. For other scopes than function
4265 // scopes ParameterCount() is 0.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004266 // 2. StackLocalFirstSlot:
4267 // Index of a first stack slot for stack local. Stack locals belonging to
4268 // this scope are located on a stack at slots starting from this index.
4269 // 3. StackLocalEntries:
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004270 // Contains the names of local variables that are allocated on the stack,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004271 // in increasing order of the stack slot index. First local variable has
4272 // a stack slot index defined in StackLocalFirstSlot (point 2 above).
4273 // One slot is used per stack local, so in total this part occupies
4274 // StackLocalCount() slots in the array.
4275 // 4. ContextLocalNameEntries:
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004276 // Contains the names of local variables and parameters that are allocated
4277 // in the context. They are stored in increasing order of the context slot
4278 // index starting with Context::MIN_CONTEXT_SLOTS. One slot is used per
4279 // context local, so in total this part occupies ContextLocalCount() slots
4280 // in the array.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004281 // 5. ContextLocalInfoEntries:
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004282 // Contains the variable modes and initialization flags corresponding to
4283 // the context locals in ContextLocalNameEntries. One slot is used per
4284 // context local, so in total this part occupies ContextLocalCount()
4285 // slots in the array.
Ben Murdoch097c5b22016-05-18 11:27:45 +01004286 // 6. RecieverEntryIndex:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004287 // If the scope binds a "this" value, one slot is reserved to hold the
4288 // context or stack slot index for the variable.
Ben Murdoch097c5b22016-05-18 11:27:45 +01004289 // 7. FunctionNameEntryIndex:
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004290 // If the scope belongs to a named function expression this part contains
4291 // information about the function variable. It always occupies two array
4292 // slots: a. The name of the function variable.
4293 // b. The context or stack slot index for the variable.
4294 int ParameterEntriesIndex();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004295 int StackLocalFirstSlotIndex();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004296 int StackLocalEntriesIndex();
4297 int ContextLocalNameEntriesIndex();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004298 int ContextGlobalNameEntriesIndex();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004299 int ContextLocalInfoEntriesIndex();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004300 int ContextGlobalInfoEntriesIndex();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004301 int ReceiverEntryIndex();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004302 int FunctionNameEntryIndex();
4303
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004304 int Lookup(Handle<String> name, int start, int end, VariableMode* mode,
4305 VariableLocation* location, InitializationFlag* init_flag,
4306 MaybeAssignedFlag* maybe_assigned_flag);
4307
4308 // Used for the function name variable for named function expressions, and for
4309 // the receiver.
4310 enum VariableAllocationInfo { NONE, STACK, CONTEXT, UNUSED };
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004311
4312 // Properties of scopes.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04004313 class ScopeTypeField : public BitField<ScopeType, 0, 4> {};
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004314 class CallsEvalField : public BitField<bool, ScopeTypeField::kNext, 1> {};
4315 STATIC_ASSERT(LANGUAGE_END == 3);
4316 class LanguageModeField
4317 : public BitField<LanguageMode, CallsEvalField::kNext, 2> {};
4318 class DeclarationScopeField
4319 : public BitField<bool, LanguageModeField::kNext, 1> {};
4320 class ReceiverVariableField
4321 : public BitField<VariableAllocationInfo, DeclarationScopeField::kNext,
4322 2> {};
4323 class HasNewTargetField
4324 : public BitField<bool, ReceiverVariableField::kNext, 1> {};
4325 class FunctionVariableField
4326 : public BitField<VariableAllocationInfo, HasNewTargetField::kNext, 2> {};
4327 class FunctionVariableMode
4328 : public BitField<VariableMode, FunctionVariableField::kNext, 3> {};
4329 class AsmModuleField : public BitField<bool, FunctionVariableMode::kNext, 1> {
4330 };
4331 class AsmFunctionField : public BitField<bool, AsmModuleField::kNext, 1> {};
4332 class HasSimpleParametersField
4333 : public BitField<bool, AsmFunctionField::kNext, 1> {};
4334 class FunctionKindField
Ben Murdochc5610432016-08-08 18:44:38 +01004335 : public BitField<FunctionKind, HasSimpleParametersField::kNext, 9> {};
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004336
4337 // BitFields representing the encoded information for context locals in the
4338 // ContextLocalInfoEntries part.
4339 class ContextLocalMode: public BitField<VariableMode, 0, 3> {};
4340 class ContextLocalInitFlag: public BitField<InitializationFlag, 3, 1> {};
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004341 class ContextLocalMaybeAssignedFlag
4342 : public BitField<MaybeAssignedFlag, 4, 1> {};
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004343
4344 friend class ScopeIterator;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004345};
4346
4347
Kristian Monsen80d68ea2010-09-08 11:05:35 +01004348// The cache for maps used by normalized (dictionary mode) objects.
4349// Such maps do not have property descriptors, so a typical program
4350// needs very limited number of distinct normalized maps.
4351class NormalizedMapCache: public FixedArray {
4352 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004353 static Handle<NormalizedMapCache> New(Isolate* isolate);
Kristian Monsen80d68ea2010-09-08 11:05:35 +01004354
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004355 MUST_USE_RESULT MaybeHandle<Map> Get(Handle<Map> fast_map,
4356 PropertyNormalizationMode mode);
4357 void Set(Handle<Map> fast_map, Handle<Map> normalized_map);
Kristian Monsen80d68ea2010-09-08 11:05:35 +01004358
Kristian Monsen80d68ea2010-09-08 11:05:35 +01004359 void Clear();
4360
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004361 DECLARE_CAST(NormalizedMapCache)
Kristian Monsen80d68ea2010-09-08 11:05:35 +01004362
Ben Murdoch097c5b22016-05-18 11:27:45 +01004363 static inline bool IsNormalizedMapCache(const HeapObject* obj);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004364
4365 DECLARE_VERIFIER(NormalizedMapCache)
4366 private:
4367 static const int kEntries = 64;
4368
4369 static inline int GetIndex(Handle<Map> map);
4370
4371 // The following declarations hide base class methods.
4372 Object* get(int index);
4373 void set(int index, Object* value);
Kristian Monsen80d68ea2010-09-08 11:05:35 +01004374};
4375
4376
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004377// ByteArray represents fixed sized byte arrays. Used for the relocation info
4378// that is attached to code objects.
Ben Murdoch69a99ed2011-11-30 16:03:39 +00004379class ByteArray: public FixedArrayBase {
Steve Blocka7e24c12009-10-30 11:49:00 +00004380 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004381 inline int Size();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004382
Steve Blocka7e24c12009-10-30 11:49:00 +00004383 // Setter and getter.
4384 inline byte get(int index);
4385 inline void set(int index, byte value);
4386
Ben Murdochc5610432016-08-08 18:44:38 +01004387 // Copy in / copy out whole byte slices.
4388 inline void copy_out(int index, byte* buffer, int length);
4389 inline void copy_in(int index, const byte* buffer, int length);
4390
Steve Blocka7e24c12009-10-30 11:49:00 +00004391 // Treat contents as an int array.
4392 inline int get_int(int index);
Ben Murdochc5610432016-08-08 18:44:38 +01004393 inline void set_int(int index, int value);
Steve Blocka7e24c12009-10-30 11:49:00 +00004394
4395 static int SizeFor(int length) {
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01004396 return OBJECT_POINTER_ALIGN(kHeaderSize + length);
Steve Blocka7e24c12009-10-30 11:49:00 +00004397 }
4398 // We use byte arrays for free blocks in the heap. Given a desired size in
4399 // bytes that is a multiple of the word size and big enough to hold a byte
4400 // array, this function returns the number of elements a byte array should
4401 // have.
4402 static int LengthFor(int size_in_bytes) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004403 DCHECK(IsAligned(size_in_bytes, kPointerSize));
4404 DCHECK(size_in_bytes >= kHeaderSize);
Steve Blocka7e24c12009-10-30 11:49:00 +00004405 return size_in_bytes - kHeaderSize;
4406 }
4407
4408 // Returns data start address.
4409 inline Address GetDataStartAddress();
4410
4411 // Returns a pointer to the ByteArray object for a given data start address.
4412 static inline ByteArray* FromDataStartAddress(Address address);
4413
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004414 DECLARE_CAST(ByteArray)
Steve Blocka7e24c12009-10-30 11:49:00 +00004415
4416 // Dispatched behavior.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004417 inline int ByteArraySize();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004418 DECLARE_PRINTER(ByteArray)
4419 DECLARE_VERIFIER(ByteArray)
Steve Blocka7e24c12009-10-30 11:49:00 +00004420
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01004421 // Layout description.
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01004422 static const int kAlignedSize = OBJECT_POINTER_ALIGN(kHeaderSize);
Steve Blocka7e24c12009-10-30 11:49:00 +00004423
Leon Clarkee46be812010-01-19 14:06:41 +00004424 // Maximal memory consumption for a single ByteArray.
4425 static const int kMaxSize = 512 * MB;
4426 // Maximal length of a single ByteArray.
4427 static const int kMaxLength = kMaxSize - kHeaderSize;
4428
Steve Blocka7e24c12009-10-30 11:49:00 +00004429 private:
4430 DISALLOW_IMPLICIT_CONSTRUCTORS(ByteArray);
4431};
4432
4433
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004434// BytecodeArray represents a sequence of interpreter bytecodes.
4435class BytecodeArray : public FixedArrayBase {
4436 public:
4437 static int SizeFor(int length) {
4438 return OBJECT_POINTER_ALIGN(kHeaderSize + length);
4439 }
4440
4441 // Setter and getter
4442 inline byte get(int index);
4443 inline void set(int index, byte value);
4444
4445 // Returns data start address.
4446 inline Address GetFirstBytecodeAddress();
4447
4448 // Accessors for frame size.
4449 inline int frame_size() const;
4450 inline void set_frame_size(int frame_size);
4451
4452 // Accessor for register count (derived from frame_size).
4453 inline int register_count() const;
4454
4455 // Accessors for parameter count (including implicit 'this' receiver).
4456 inline int parameter_count() const;
4457 inline void set_parameter_count(int number_of_parameters);
4458
Ben Murdoch097c5b22016-05-18 11:27:45 +01004459 // Accessors for profiling count.
4460 inline int interrupt_budget() const;
4461 inline void set_interrupt_budget(int interrupt_budget);
4462
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004463 // Accessors for the constant pool.
4464 DECL_ACCESSORS(constant_pool, FixedArray)
4465
Ben Murdoch097c5b22016-05-18 11:27:45 +01004466 // Accessors for handler table containing offsets of exception handlers.
4467 DECL_ACCESSORS(handler_table, FixedArray)
4468
4469 // Accessors for source position table containing mappings between byte code
4470 // offset and source position.
Ben Murdochda12d292016-06-02 14:46:10 +01004471 DECL_ACCESSORS(source_position_table, ByteArray)
Ben Murdoch097c5b22016-05-18 11:27:45 +01004472
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004473 DECLARE_CAST(BytecodeArray)
4474
4475 // Dispatched behavior.
4476 inline int BytecodeArraySize();
4477
Ben Murdoch097c5b22016-05-18 11:27:45 +01004478 inline int instruction_size();
4479
Ben Murdoch61f157c2016-09-16 13:49:30 +01004480 // Returns the size of bytecode and its metadata. This includes the size of
4481 // bytecode, constant pool, source position table, and handler table.
4482 inline int SizeIncludingMetadata();
4483
Ben Murdoch097c5b22016-05-18 11:27:45 +01004484 int SourcePosition(int offset);
4485 int SourceStatementPosition(int offset);
4486
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004487 DECLARE_PRINTER(BytecodeArray)
4488 DECLARE_VERIFIER(BytecodeArray)
4489
4490 void Disassemble(std::ostream& os);
4491
Ben Murdoch097c5b22016-05-18 11:27:45 +01004492 void CopyBytecodesTo(BytecodeArray* to);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004493
Ben Murdoch097c5b22016-05-18 11:27:45 +01004494 // Layout description.
4495 static const int kConstantPoolOffset = FixedArrayBase::kHeaderSize;
4496 static const int kHandlerTableOffset = kConstantPoolOffset + kPointerSize;
4497 static const int kSourcePositionTableOffset =
4498 kHandlerTableOffset + kPointerSize;
4499 static const int kFrameSizeOffset = kSourcePositionTableOffset + kPointerSize;
4500 static const int kParameterSizeOffset = kFrameSizeOffset + kIntSize;
4501 static const int kInterruptBudgetOffset = kParameterSizeOffset + kIntSize;
4502 static const int kHeaderSize = kInterruptBudgetOffset + kIntSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004503
4504 // Maximal memory consumption for a single BytecodeArray.
4505 static const int kMaxSize = 512 * MB;
4506 // Maximal length of a single BytecodeArray.
4507 static const int kMaxLength = kMaxSize - kHeaderSize;
4508
4509 class BodyDescriptor;
4510
4511 private:
4512 DISALLOW_IMPLICIT_CONSTRUCTORS(BytecodeArray);
4513};
4514
4515
4516// FreeSpace are fixed-size free memory blocks used by the heap and GC.
4517// They look like heap objects (are heap object tagged and have a map) so that
4518// the heap remains iterable. They have a size and a next pointer.
4519// The next pointer is the raw address of the next FreeSpace object (or NULL)
4520// in the free list.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004521class FreeSpace: public HeapObject {
4522 public:
4523 // [size]: size of the free space including the header.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004524 inline int size() const;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004525 inline void set_size(int value);
4526
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004527 inline int nobarrier_size() const;
4528 inline void nobarrier_set_size(int value);
4529
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004530 inline int Size();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004531
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004532 // Accessors for the next field.
4533 inline FreeSpace* next();
4534 inline void set_next(FreeSpace* next);
4535
4536 inline static FreeSpace* cast(HeapObject* obj);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004537
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004538 // Dispatched behavior.
4539 DECLARE_PRINTER(FreeSpace)
4540 DECLARE_VERIFIER(FreeSpace)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004541
4542 // Layout description.
4543 // Size is smi tagged when it is stored.
4544 static const int kSizeOffset = HeapObject::kHeaderSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004545 static const int kNextOffset = POINTER_SIZE_ALIGN(kSizeOffset + kPointerSize);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004546
4547 private:
4548 DISALLOW_IMPLICIT_CONSTRUCTORS(FreeSpace);
4549};
4550
4551
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004552// V has parameters (Type, type, TYPE, C type, element_size)
4553#define TYPED_ARRAYS(V) \
4554 V(Uint8, uint8, UINT8, uint8_t, 1) \
4555 V(Int8, int8, INT8, int8_t, 1) \
4556 V(Uint16, uint16, UINT16, uint16_t, 2) \
4557 V(Int16, int16, INT16, int16_t, 2) \
4558 V(Uint32, uint32, UINT32, uint32_t, 4) \
4559 V(Int32, int32, INT32, int32_t, 4) \
4560 V(Float32, float32, FLOAT32, float, 4) \
4561 V(Float64, float64, FLOAT64, double, 8) \
4562 V(Uint8Clamped, uint8_clamped, UINT8_CLAMPED, uint8_t, 1)
4563
4564
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004565class FixedTypedArrayBase: public FixedArrayBase {
4566 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004567 // [base_pointer]: Either points to the FixedTypedArrayBase itself or nullptr.
4568 DECL_ACCESSORS(base_pointer, Object)
4569
4570 // [external_pointer]: Contains the offset between base_pointer and the start
4571 // of the data. If the base_pointer is a nullptr, the external_pointer
4572 // therefore points to the actual backing store.
4573 DECL_ACCESSORS(external_pointer, void)
4574
4575 // Dispatched behavior.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004576 DECLARE_CAST(FixedTypedArrayBase)
4577
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004578 static const int kBasePointerOffset = FixedArrayBase::kHeaderSize;
4579 static const int kExternalPointerOffset = kBasePointerOffset + kPointerSize;
4580 static const int kHeaderSize =
4581 DOUBLE_POINTER_ALIGN(kExternalPointerOffset + kPointerSize);
4582
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004583 static const int kDataOffset = kHeaderSize;
4584
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004585 class BodyDescriptor;
4586
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004587 inline int size();
4588
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004589 static inline int TypedArraySize(InstanceType type, int length);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004590 inline int TypedArraySize(InstanceType type);
4591
4592 // Use with care: returns raw pointer into heap.
4593 inline void* DataPtr();
4594
4595 inline int DataSize();
4596
4597 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004598 static inline int ElementSize(InstanceType type);
4599
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004600 inline int DataSize(InstanceType type);
4601
4602 DISALLOW_IMPLICIT_CONSTRUCTORS(FixedTypedArrayBase);
4603};
4604
4605
4606template <class Traits>
4607class FixedTypedArray: public FixedTypedArrayBase {
4608 public:
4609 typedef typename Traits::ElementType ElementType;
4610 static const InstanceType kInstanceType = Traits::kInstanceType;
4611
4612 DECLARE_CAST(FixedTypedArray<Traits>)
4613
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004614 inline ElementType get_scalar(int index);
Ben Murdoch097c5b22016-05-18 11:27:45 +01004615 static inline Handle<Object> get(FixedTypedArray* array, int index);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004616 inline void set(int index, ElementType value);
4617
4618 static inline ElementType from_int(int value);
4619 static inline ElementType from_double(double value);
4620
4621 // This accessor applies the correct conversion from Smi, HeapNumber
4622 // and undefined.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004623 inline void SetValue(uint32_t index, Object* value);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004624
4625 DECLARE_PRINTER(FixedTypedArray)
4626 DECLARE_VERIFIER(FixedTypedArray)
4627
4628 private:
4629 DISALLOW_IMPLICIT_CONSTRUCTORS(FixedTypedArray);
4630};
4631
4632#define FIXED_TYPED_ARRAY_TRAITS(Type, type, TYPE, elementType, size) \
4633 class Type##ArrayTraits { \
4634 public: /* NOLINT */ \
4635 typedef elementType ElementType; \
4636 static const InstanceType kInstanceType = FIXED_##TYPE##_ARRAY_TYPE; \
4637 static const char* Designator() { return #type " array"; } \
4638 static inline Handle<Object> ToHandle(Isolate* isolate, \
4639 elementType scalar); \
4640 static inline elementType defaultValue(); \
4641 }; \
4642 \
4643 typedef FixedTypedArray<Type##ArrayTraits> Fixed##Type##Array;
4644
4645TYPED_ARRAYS(FIXED_TYPED_ARRAY_TRAITS)
4646
4647#undef FIXED_TYPED_ARRAY_TRAITS
4648
Emily Bernierd0a1eb72015-03-24 16:35:39 -04004649
Ben Murdochb0fe1622011-05-05 13:52:32 +01004650// DeoptimizationInputData is a fixed array used to hold the deoptimization
4651// data for code generated by the Hydrogen/Lithium compiler. It also
4652// contains information about functions that were inlined. If N different
4653// functions were inlined then first N elements of the literal array will
4654// contain these functions.
4655//
4656// It can be empty.
4657class DeoptimizationInputData: public FixedArray {
4658 public:
4659 // Layout description. Indices in the array.
4660 static const int kTranslationByteArrayIndex = 0;
4661 static const int kInlinedFunctionCountIndex = 1;
4662 static const int kLiteralArrayIndex = 2;
4663 static const int kOsrAstIdIndex = 3;
4664 static const int kOsrPcOffsetIndex = 4;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004665 static const int kOptimizationIdIndex = 5;
4666 static const int kSharedFunctionInfoIndex = 6;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004667 static const int kWeakCellCacheIndex = 7;
4668 static const int kFirstDeoptEntryIndex = 8;
Ben Murdochb0fe1622011-05-05 13:52:32 +01004669
4670 // Offsets of deopt entry elements relative to the start of the entry.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004671 static const int kAstIdRawOffset = 0;
Ben Murdochb0fe1622011-05-05 13:52:32 +01004672 static const int kTranslationIndexOffset = 1;
4673 static const int kArgumentsStackHeightOffset = 2;
Ben Murdoch2b4ba112012-01-20 14:57:15 +00004674 static const int kPcOffset = 3;
4675 static const int kDeoptEntrySize = 4;
Ben Murdochb0fe1622011-05-05 13:52:32 +01004676
4677 // Simple element accessors.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004678#define DECLARE_ELEMENT_ACCESSORS(name, type) \
4679 inline type* name(); \
4680 inline void Set##name(type* value);
Ben Murdochb0fe1622011-05-05 13:52:32 +01004681
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004682 DECLARE_ELEMENT_ACCESSORS(TranslationByteArray, ByteArray)
4683 DECLARE_ELEMENT_ACCESSORS(InlinedFunctionCount, Smi)
4684 DECLARE_ELEMENT_ACCESSORS(LiteralArray, FixedArray)
4685 DECLARE_ELEMENT_ACCESSORS(OsrAstId, Smi)
4686 DECLARE_ELEMENT_ACCESSORS(OsrPcOffset, Smi)
4687 DECLARE_ELEMENT_ACCESSORS(OptimizationId, Smi)
4688 DECLARE_ELEMENT_ACCESSORS(SharedFunctionInfo, Object)
4689 DECLARE_ELEMENT_ACCESSORS(WeakCellCache, Object)
Ben Murdochb0fe1622011-05-05 13:52:32 +01004690
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004691#undef DECLARE_ELEMENT_ACCESSORS
Ben Murdochb0fe1622011-05-05 13:52:32 +01004692
4693 // Accessors for elements of the ith deoptimization entry.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004694#define DECLARE_ENTRY_ACCESSORS(name, type) \
4695 inline type* name(int i); \
4696 inline void Set##name(int i, type* value);
Ben Murdochb0fe1622011-05-05 13:52:32 +01004697
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004698 DECLARE_ENTRY_ACCESSORS(AstIdRaw, Smi)
4699 DECLARE_ENTRY_ACCESSORS(TranslationIndex, Smi)
4700 DECLARE_ENTRY_ACCESSORS(ArgumentsStackHeight, Smi)
4701 DECLARE_ENTRY_ACCESSORS(Pc, Smi)
Ben Murdochb0fe1622011-05-05 13:52:32 +01004702
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004703#undef DECLARE_ENTRY_ACCESSORS
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004704
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004705 inline BailoutId AstId(int i);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004706
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004707 inline void SetAstId(int i, BailoutId value);
Ben Murdochb0fe1622011-05-05 13:52:32 +01004708
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004709 inline int DeoptCount();
Ben Murdochb0fe1622011-05-05 13:52:32 +01004710
4711 // Allocates a DeoptimizationInputData.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004712 static Handle<DeoptimizationInputData> New(Isolate* isolate,
4713 int deopt_entry_count,
4714 PretenureFlag pretenure);
Ben Murdochb0fe1622011-05-05 13:52:32 +01004715
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004716 DECLARE_CAST(DeoptimizationInputData)
Ben Murdochb0fe1622011-05-05 13:52:32 +01004717
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00004718#ifdef ENABLE_DISASSEMBLER
Emily Bernierd0a1eb72015-03-24 16:35:39 -04004719 void DeoptimizationInputDataPrint(std::ostream& os); // NOLINT
Ben Murdochb0fe1622011-05-05 13:52:32 +01004720#endif
4721
4722 private:
4723 static int IndexForEntry(int i) {
4724 return kFirstDeoptEntryIndex + (i * kDeoptEntrySize);
4725 }
4726
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004727
4728 static int LengthFor(int entry_count) { return IndexForEntry(entry_count); }
Ben Murdochb0fe1622011-05-05 13:52:32 +01004729};
4730
4731
4732// DeoptimizationOutputData is a fixed array used to hold the deoptimization
4733// data for code generated by the full compiler.
4734// The format of the these objects is
4735// [i * 2]: Ast ID for ith deoptimization.
4736// [i * 2 + 1]: PC and state of ith deoptimization
4737class DeoptimizationOutputData: public FixedArray {
4738 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004739 inline int DeoptPoints();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004740
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004741 inline BailoutId AstId(int index);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004742
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004743 inline void SetAstId(int index, BailoutId id);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004744
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004745 inline Smi* PcAndState(int index);
4746 inline void SetPcAndState(int index, Smi* offset);
Ben Murdochb0fe1622011-05-05 13:52:32 +01004747
4748 static int LengthOfFixedArray(int deopt_points) {
4749 return deopt_points * 2;
4750 }
4751
4752 // Allocates a DeoptimizationOutputData.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004753 static Handle<DeoptimizationOutputData> New(Isolate* isolate,
4754 int number_of_deopt_points,
4755 PretenureFlag pretenure);
Ben Murdochb0fe1622011-05-05 13:52:32 +01004756
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004757 DECLARE_CAST(DeoptimizationOutputData)
Ben Murdochb0fe1622011-05-05 13:52:32 +01004758
Ben Murdoch097c5b22016-05-18 11:27:45 +01004759#ifdef ENABLE_DISASSEMBLER
Emily Bernierd0a1eb72015-03-24 16:35:39 -04004760 void DeoptimizationOutputDataPrint(std::ostream& os); // NOLINT
Ben Murdochb0fe1622011-05-05 13:52:32 +01004761#endif
4762};
4763
4764
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004765// A literals array contains the literals for a JSFunction. It also holds
4766// the type feedback vector.
4767class LiteralsArray : public FixedArray {
4768 public:
4769 static const int kVectorIndex = 0;
4770 static const int kFirstLiteralIndex = 1;
Ben Murdoch61f157c2016-09-16 13:49:30 +01004771 static const int kFeedbackVectorOffset;
4772 static const int kOffsetToFirstLiteral;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004773
4774 static int OffsetOfLiteralAt(int index) {
Ben Murdoch61f157c2016-09-16 13:49:30 +01004775 return OffsetOfElementAt(index + kFirstLiteralIndex);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004776 }
4777
4778 inline TypeFeedbackVector* feedback_vector() const;
4779 inline void set_feedback_vector(TypeFeedbackVector* vector);
4780 inline Object* literal(int literal_index) const;
4781 inline void set_literal(int literal_index, Object* literal);
Ben Murdoch61f157c2016-09-16 13:49:30 +01004782 inline void set_literal_undefined(int literal_index);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004783 inline int literals_count() const;
4784
4785 static Handle<LiteralsArray> New(Isolate* isolate,
4786 Handle<TypeFeedbackVector> vector,
4787 int number_of_literals,
4788 PretenureFlag pretenure);
4789
4790 DECLARE_CAST(LiteralsArray)
4791
4792 private:
4793 inline Object* get(int index) const;
4794 inline void set(int index, Object* value);
4795 inline void set(int index, Smi* value);
4796 inline void set(int index, Object* value, WriteBarrierMode mode);
4797};
4798
4799
4800// HandlerTable is a fixed array containing entries for exception handlers in
4801// the code object it is associated with. The tables comes in two flavors:
4802// 1) Based on ranges: Used for unoptimized code. Contains one entry per
4803// exception handler and a range representing the try-block covered by that
4804// handler. Layout looks as follows:
Ben Murdoch097c5b22016-05-18 11:27:45 +01004805// [ range-start , range-end , handler-offset , handler-data ]
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004806// 2) Based on return addresses: Used for turbofanned code. Contains one entry
4807// per call-site that could throw an exception. Layout looks as follows:
4808// [ return-address-offset , handler-offset ]
4809class HandlerTable : public FixedArray {
4810 public:
4811 // Conservative prediction whether a given handler will locally catch an
4812 // exception or cause a re-throw to outside the code boundary. Since this is
4813 // undecidable it is merely an approximation (e.g. useful for debugger).
4814 enum CatchPrediction { UNCAUGHT, CAUGHT };
4815
Ben Murdoch097c5b22016-05-18 11:27:45 +01004816 // Getters for handler table based on ranges.
4817 inline int GetRangeStart(int index) const;
4818 inline int GetRangeEnd(int index) const;
4819 inline int GetRangeHandler(int index) const;
4820 inline int GetRangeData(int index) const;
4821
4822 // Setters for handler table based on ranges.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004823 inline void SetRangeStart(int index, int value);
4824 inline void SetRangeEnd(int index, int value);
4825 inline void SetRangeHandler(int index, int offset, CatchPrediction pred);
Ben Murdoch097c5b22016-05-18 11:27:45 +01004826 inline void SetRangeData(int index, int value);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004827
Ben Murdoch097c5b22016-05-18 11:27:45 +01004828 // Setters for handler table based on return addresses.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004829 inline void SetReturnOffset(int index, int value);
4830 inline void SetReturnHandler(int index, int offset, CatchPrediction pred);
4831
4832 // Lookup handler in a table based on ranges.
Ben Murdoch097c5b22016-05-18 11:27:45 +01004833 int LookupRange(int pc_offset, int* data, CatchPrediction* prediction);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004834
4835 // Lookup handler in a table based on return addresses.
4836 int LookupReturn(int pc_offset, CatchPrediction* prediction);
4837
Ben Murdoch097c5b22016-05-18 11:27:45 +01004838 // Returns the conservative catch predication.
4839 inline CatchPrediction GetRangePrediction(int index) const;
4840
4841 // Returns the number of entries in the table.
4842 inline int NumberOfRangeEntries() const;
4843
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004844 // Returns the required length of the underlying fixed array.
4845 static int LengthForRange(int entries) { return entries * kRangeEntrySize; }
4846 static int LengthForReturn(int entries) { return entries * kReturnEntrySize; }
4847
4848 DECLARE_CAST(HandlerTable)
4849
Ben Murdoch097c5b22016-05-18 11:27:45 +01004850#ifdef ENABLE_DISASSEMBLER
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004851 void HandlerTableRangePrint(std::ostream& os); // NOLINT
4852 void HandlerTableReturnPrint(std::ostream& os); // NOLINT
4853#endif
4854
4855 private:
4856 // Layout description for handler table based on ranges.
4857 static const int kRangeStartIndex = 0;
4858 static const int kRangeEndIndex = 1;
4859 static const int kRangeHandlerIndex = 2;
Ben Murdoch097c5b22016-05-18 11:27:45 +01004860 static const int kRangeDataIndex = 3;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004861 static const int kRangeEntrySize = 4;
4862
4863 // Layout description for handler table based on return addresses.
4864 static const int kReturnOffsetIndex = 0;
4865 static const int kReturnHandlerIndex = 1;
4866 static const int kReturnEntrySize = 2;
4867
4868 // Encoding of the {handler} field.
4869 class HandlerPredictionField : public BitField<CatchPrediction, 0, 1> {};
4870 class HandlerOffsetField : public BitField<int, 1, 30> {};
4871};
4872
Ben Murdochb8e0da22011-05-16 14:20:40 +01004873
Steve Blocka7e24c12009-10-30 11:49:00 +00004874// Code describes objects with on-the-fly generated machine code.
4875class Code: public HeapObject {
4876 public:
4877 // Opaque data type for encapsulating code flags like kind, inline
4878 // cache state, and arguments count.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004879 typedef uint32_t Flags;
4880
4881#define NON_IC_KIND_LIST(V) \
4882 V(FUNCTION) \
4883 V(OPTIMIZED_FUNCTION) \
Ben Murdochda12d292016-06-02 14:46:10 +01004884 V(BYTECODE_HANDLER) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004885 V(STUB) \
4886 V(HANDLER) \
4887 V(BUILTIN) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004888 V(REGEXP) \
Ben Murdochda12d292016-06-02 14:46:10 +01004889 V(WASM_FUNCTION) \
4890 V(WASM_TO_JS_FUNCTION) \
4891 V(JS_TO_WASM_FUNCTION)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004892
4893#define IC_KIND_LIST(V) \
4894 V(LOAD_IC) \
Ben Murdoch61f157c2016-09-16 13:49:30 +01004895 V(LOAD_GLOBAL_IC) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004896 V(KEYED_LOAD_IC) \
4897 V(CALL_IC) \
4898 V(STORE_IC) \
4899 V(KEYED_STORE_IC) \
4900 V(BINARY_OP_IC) \
4901 V(COMPARE_IC) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004902 V(TO_BOOLEAN_IC)
4903
4904#define CODE_KIND_LIST(V) \
4905 NON_IC_KIND_LIST(V) \
4906 IC_KIND_LIST(V)
Steve Blocka7e24c12009-10-30 11:49:00 +00004907
4908 enum Kind {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004909#define DEFINE_CODE_KIND_ENUM(name) name,
4910 CODE_KIND_LIST(DEFINE_CODE_KIND_ENUM)
4911#undef DEFINE_CODE_KIND_ENUM
4912 NUMBER_OF_KINDS
Steve Blocka7e24c12009-10-30 11:49:00 +00004913 };
4914
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004915 static const char* Kind2String(Kind kind);
4916
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004917 static const int kPrologueOffsetNotSet = -1;
Ben Murdochb8e0da22011-05-16 14:20:40 +01004918
Steve Blocka7e24c12009-10-30 11:49:00 +00004919#ifdef ENABLE_DISASSEMBLER
4920 // Printing
Steve Blocka7e24c12009-10-30 11:49:00 +00004921 static const char* ICState2String(InlineCacheState state);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04004922 static void PrintExtraICState(std::ostream& os, // NOLINT
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004923 Kind kind, ExtraICState extra);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04004924 void Disassemble(const char* name, std::ostream& os); // NOLINT
Steve Blocka7e24c12009-10-30 11:49:00 +00004925#endif // ENABLE_DISASSEMBLER
4926
4927 // [instruction_size]: Size of the native instructions
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004928 inline int instruction_size() const;
Steve Blocka7e24c12009-10-30 11:49:00 +00004929 inline void set_instruction_size(int value);
4930
Leon Clarkeac952652010-07-15 11:15:24 +01004931 // [relocation_info]: Code relocation information
4932 DECL_ACCESSORS(relocation_info, ByteArray)
Ben Murdochb0fe1622011-05-05 13:52:32 +01004933 void InvalidateRelocation();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004934 void InvalidateEmbeddedObjects();
Leon Clarkeac952652010-07-15 11:15:24 +01004935
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004936 // [handler_table]: Fixed array containing offsets of exception handlers.
4937 DECL_ACCESSORS(handler_table, FixedArray)
4938
Ben Murdochb0fe1622011-05-05 13:52:32 +01004939 // [deoptimization_data]: Array containing data for deopt.
4940 DECL_ACCESSORS(deoptimization_data, FixedArray)
4941
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004942 // [raw_type_feedback_info]: This field stores various things, depending on
4943 // the kind of the code object.
4944 // FUNCTION => type feedback information.
4945 // STUB and ICs => major/minor key as Smi.
4946 DECL_ACCESSORS(raw_type_feedback_info, Object)
4947 inline Object* type_feedback_info();
4948 inline void set_type_feedback_info(
4949 Object* value, WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
4950 inline uint32_t stub_key();
4951 inline void set_stub_key(uint32_t key);
4952
4953 // [next_code_link]: Link for lists of optimized or deoptimized code.
4954 // Note that storage for this field is overlapped with typefeedback_info.
4955 DECL_ACCESSORS(next_code_link, Object)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004956
4957 // [gc_metadata]: Field used to hold GC related metadata. The contents of this
Ben Murdoch257744e2011-11-30 15:57:28 +00004958 // field does not have to be traced during garbage collection since
4959 // it is only used by the garbage collector itself.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004960 DECL_ACCESSORS(gc_metadata, Object)
4961
4962 // [ic_age]: Inline caching age: the value of the Heap::global_ic_age
4963 // at the moment when this object was created.
4964 inline void set_ic_age(int count);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004965 inline int ic_age() const;
4966
4967 // [prologue_offset]: Offset of the function prologue, used for aging
4968 // FUNCTIONs and OPTIMIZED_FUNCTIONs.
4969 inline int prologue_offset() const;
4970 inline void set_prologue_offset(int offset);
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01004971
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004972 // [constant_pool offset]: Offset of the constant pool.
4973 // Valid for FLAG_enable_embedded_constant_pool only
4974 inline int constant_pool_offset() const;
4975 inline void set_constant_pool_offset(int offset);
4976
Ben Murdochb0fe1622011-05-05 13:52:32 +01004977 // Unchecked accessors to be used during GC.
Leon Clarkeac952652010-07-15 11:15:24 +01004978 inline ByteArray* unchecked_relocation_info();
4979
Steve Blocka7e24c12009-10-30 11:49:00 +00004980 inline int relocation_size();
Steve Blocka7e24c12009-10-30 11:49:00 +00004981
Steve Blocka7e24c12009-10-30 11:49:00 +00004982 // [flags]: Various code flags.
4983 inline Flags flags();
4984 inline void set_flags(Flags flags);
4985
4986 // [flags]: Access to specific code flags.
4987 inline Kind kind();
Ben Murdochb8e0da22011-05-16 14:20:40 +01004988 inline ExtraICState extra_ic_state(); // Only valid for IC stubs.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004989
Steve Blocka7e24c12009-10-30 11:49:00 +00004990 // Testers for IC stub kinds.
4991 inline bool is_inline_cache_stub();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004992 inline bool is_debug_stub();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004993 inline bool is_handler();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004994 inline bool is_call_stub();
4995 inline bool is_binary_op_stub();
4996 inline bool is_compare_ic_stub();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004997 inline bool is_to_boolean_ic_stub();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004998 inline bool is_optimized_code();
Ben Murdochda12d292016-06-02 14:46:10 +01004999 inline bool is_wasm_code();
Ben Murdochb0fe1622011-05-05 13:52:32 +01005000
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005001 inline bool IsCodeStubOrIC();
5002
5003 inline void set_raw_kind_specific_flags1(int value);
5004 inline void set_raw_kind_specific_flags2(int value);
5005
Ben Murdoch097c5b22016-05-18 11:27:45 +01005006 // Testers for interpreter builtins.
Ben Murdoch61f157c2016-09-16 13:49:30 +01005007 inline bool is_interpreter_trampoline_builtin();
Ben Murdoch097c5b22016-05-18 11:27:45 +01005008
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005009 // [is_crankshafted]: For kind STUB or ICs, tells whether or not a code
5010 // object was generated by either the hydrogen or the TurboFan optimizing
5011 // compiler (but it may not be an optimized function).
5012 inline bool is_crankshafted();
5013 inline bool is_hydrogen_stub(); // Crankshafted, but not a function.
5014 inline void set_is_crankshafted(bool value);
5015
5016 // [is_turbofanned]: For kind STUB or OPTIMIZED_FUNCTION, tells whether the
5017 // code object was generated by the TurboFan optimizing compiler.
5018 inline bool is_turbofanned();
5019 inline void set_is_turbofanned(bool value);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005020
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005021 // [can_have_weak_objects]: For kind OPTIMIZED_FUNCTION, tells whether the
5022 // embedded objects in code should be treated weakly.
5023 inline bool can_have_weak_objects();
5024 inline void set_can_have_weak_objects(bool value);
Ben Murdochb0fe1622011-05-05 13:52:32 +01005025
5026 // [has_deoptimization_support]: For FUNCTION kind, tells if it has
5027 // deoptimization support.
5028 inline bool has_deoptimization_support();
5029 inline void set_has_deoptimization_support(bool value);
5030
Ben Murdoch589d6972011-11-30 16:04:58 +00005031 // [has_debug_break_slots]: For FUNCTION kind, tells if it has
5032 // been compiled with debug break slots.
5033 inline bool has_debug_break_slots();
5034 inline void set_has_debug_break_slots(bool value);
5035
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005036 // [has_reloc_info_for_serialization]: For FUNCTION kind, tells if its
5037 // reloc info includes runtime and external references to support
5038 // serialization/deserialization.
5039 inline bool has_reloc_info_for_serialization();
5040 inline void set_has_reloc_info_for_serialization(bool value);
5041
Ben Murdochb0fe1622011-05-05 13:52:32 +01005042 // [allow_osr_at_loop_nesting_level]: For FUNCTION kind, tells for
5043 // how long the function has been marked for OSR and therefore which
5044 // level of loop nesting we are willing to do on-stack replacement
5045 // for.
5046 inline void set_allow_osr_at_loop_nesting_level(int level);
5047 inline int allow_osr_at_loop_nesting_level();
5048
Ben Murdoch8f9999f2012-04-23 10:39:17 +01005049 // [profiler_ticks]: For FUNCTION kind, tells for how many profiler ticks
5050 // the code object was seen on the stack with no IC patching going on.
5051 inline int profiler_ticks();
5052 inline void set_profiler_ticks(int ticks);
5053
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005054 // [builtin_index]: For BUILTIN kind, tells which builtin index it has.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005055 // For builtins, tells which builtin index it has.
5056 // Note that builtins can have a code kind other than BUILTIN, which means
5057 // that for arbitrary code objects, this index value may be random garbage.
5058 // To verify in that case, compare the code object to the indexed builtin.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005059 inline int builtin_index();
5060 inline void set_builtin_index(int id);
5061
Ben Murdochb0fe1622011-05-05 13:52:32 +01005062 // [stack_slots]: For kind OPTIMIZED_FUNCTION, the number of stack slots
5063 // reserved in the code prologue.
5064 inline unsigned stack_slots();
5065 inline void set_stack_slots(unsigned slots);
5066
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005067 // [safepoint_table_start]: For kind OPTIMIZED_FUNCTION, the offset in
Ben Murdochb0fe1622011-05-05 13:52:32 +01005068 // the instruction stream where the safepoint table starts.
Steve Block1e0659c2011-05-24 12:43:12 +01005069 inline unsigned safepoint_table_offset();
5070 inline void set_safepoint_table_offset(unsigned offset);
Ben Murdochb0fe1622011-05-05 13:52:32 +01005071
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005072 // [back_edge_table_start]: For kind FUNCTION, the offset in the
5073 // instruction stream where the back edge table starts.
5074 inline unsigned back_edge_table_offset();
5075 inline void set_back_edge_table_offset(unsigned offset);
Ben Murdochb0fe1622011-05-05 13:52:32 +01005076
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005077 inline bool back_edges_patched_for_osr();
Ben Murdochb0fe1622011-05-05 13:52:32 +01005078
Ben Murdoch69a99ed2011-11-30 16:03:39 +00005079 // [to_boolean_foo]: For kind TO_BOOLEAN_IC tells what state the stub is in.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005080 inline uint16_t to_boolean_state();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005081
5082 // [marked_for_deoptimization]: For kind OPTIMIZED_FUNCTION tells whether
5083 // the code is going to be deoptimized because of dead embedded maps.
5084 inline bool marked_for_deoptimization();
5085 inline void set_marked_for_deoptimization(bool flag);
5086
5087 // [constant_pool]: The constant pool for this function.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005088 inline Address constant_pool();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005089
Ben Murdochb8e0da22011-05-16 14:20:40 +01005090 // Get the safepoint entry for the given pc.
5091 SafepointEntry GetSafepointEntry(Address pc);
Ben Murdochb0fe1622011-05-05 13:52:32 +01005092
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005093 // Find an object in a stub with a specified map
5094 Object* FindNthObject(int n, Map* match_map);
5095
5096 // Find the first allocation site in an IC stub.
5097 AllocationSite* FindFirstAllocationSite();
Ben Murdochb0fe1622011-05-05 13:52:32 +01005098
5099 // Find the first map in an IC stub.
5100 Map* FindFirstMap();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005101
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005102 class FindAndReplacePattern;
5103 // For each (map-to-find, object-to-replace) pair in the pattern, this
5104 // function replaces the corresponding placeholder in the code with the
5105 // object-to-replace. The function assumes that pairs in the pattern come in
5106 // the same order as the placeholders in the code.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005107 // If the placeholder is a weak cell, then the value of weak cell is matched
5108 // against the map-to-find.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005109 void FindAndReplace(const FindAndReplacePattern& pattern);
5110
5111 // The entire code object including its header is copied verbatim to the
5112 // snapshot so that it can be written in one, fast, memcpy during
5113 // deserialization. The deserializer will overwrite some pointers, rather
5114 // like a runtime linker, but the random allocation addresses used in the
5115 // mksnapshot process would still be present in the unlinked snapshot data,
5116 // which would make snapshot production non-reproducible. This method wipes
5117 // out the to-be-overwritten header data for reproducible snapshots.
5118 inline void WipeOutHeader();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005119
Steve Blocka7e24c12009-10-30 11:49:00 +00005120 // Flags operations.
Ben Murdochb8e0da22011-05-16 14:20:40 +01005121 static inline Flags ComputeFlags(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005122 Kind kind, ExtraICState extra_ic_state = kNoExtraICState,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005123 CacheHolderFlag holder = kCacheOnReceiver);
Steve Blocka7e24c12009-10-30 11:49:00 +00005124
Ben Murdochc5610432016-08-08 18:44:38 +01005125 static inline Flags ComputeHandlerFlags(
5126 Kind handler_kind, CacheHolderFlag holder = kCacheOnReceiver);
5127
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005128 static inline CacheHolderFlag ExtractCacheHolderFromFlags(Flags flags);
Ben Murdoch589d6972011-11-30 16:04:58 +00005129 static inline Kind ExtractKindFromFlags(Flags flags);
Ben Murdoch589d6972011-11-30 16:04:58 +00005130 static inline ExtraICState ExtractExtraICStateFromFlags(Flags flags);
Ben Murdoch589d6972011-11-30 16:04:58 +00005131
Ben Murdochc5610432016-08-08 18:44:38 +01005132 static inline Flags RemoveHolderFromFlags(Flags flags);
Steve Blocka7e24c12009-10-30 11:49:00 +00005133
5134 // Convert a target address into a code object.
5135 static inline Code* GetCodeFromTargetAddress(Address address);
5136
Steve Block791712a2010-08-27 10:21:07 +01005137 // Convert an entry address into an object.
5138 static inline Object* GetObjectFromEntryAddress(Address location_of_address);
5139
Steve Blocka7e24c12009-10-30 11:49:00 +00005140 // Returns the address of the first instruction.
5141 inline byte* instruction_start();
5142
Leon Clarkeac952652010-07-15 11:15:24 +01005143 // Returns the address right after the last instruction.
5144 inline byte* instruction_end();
5145
Ben Murdoch61f157c2016-09-16 13:49:30 +01005146 // Returns the size of the instructions, padding, relocation and unwinding
5147 // information.
Steve Blocka7e24c12009-10-30 11:49:00 +00005148 inline int body_size();
5149
Ben Murdoch61f157c2016-09-16 13:49:30 +01005150 // Returns the size of code and its metadata. This includes the size of code
5151 // relocation information, deoptimization data and handler table.
5152 inline int SizeIncludingMetadata();
5153
Steve Blocka7e24c12009-10-30 11:49:00 +00005154 // Returns the address of the first relocation info (read backwards!).
5155 inline byte* relocation_start();
5156
Ben Murdoch61f157c2016-09-16 13:49:30 +01005157 // [has_unwinding_info]: Whether this code object has unwinding information.
5158 // If it doesn't, unwinding_information_start() will point to invalid data.
5159 //
5160 // The body of all code objects has the following layout.
5161 //
5162 // +--------------------------+ <-- instruction_start()
5163 // | instructions |
5164 // | ... |
5165 // +--------------------------+
5166 // | relocation info |
5167 // | ... |
5168 // +--------------------------+ <-- instruction_end()
5169 //
5170 // If has_unwinding_info() is false, instruction_end() points to the first
5171 // memory location after the end of the code object. Otherwise, the body
5172 // continues as follows:
5173 //
5174 // +--------------------------+
5175 // | padding to the next |
5176 // | 8-byte aligned address |
5177 // +--------------------------+ <-- instruction_end()
5178 // | [unwinding_info_size] |
5179 // | as uint64_t |
5180 // +--------------------------+ <-- unwinding_info_start()
5181 // | unwinding info |
5182 // | ... |
5183 // +--------------------------+ <-- unwinding_info_end()
5184 //
5185 // and unwinding_info_end() points to the first memory location after the end
5186 // of the code object.
5187 //
5188 DECL_BOOLEAN_ACCESSORS(has_unwinding_info)
5189
5190 // [unwinding_info_size]: Size of the unwinding information.
5191 inline int unwinding_info_size() const;
5192 inline void set_unwinding_info_size(int value);
5193
5194 // Returns the address of the unwinding information, if any.
5195 inline byte* unwinding_info_start();
5196
5197 // Returns the address right after the end of the unwinding information.
5198 inline byte* unwinding_info_end();
5199
Steve Blocka7e24c12009-10-30 11:49:00 +00005200 // Code entry point.
5201 inline byte* entry();
5202
5203 // Returns true if pc is inside this object's instructions.
5204 inline bool contains(byte* pc);
5205
Steve Blocka7e24c12009-10-30 11:49:00 +00005206 // Relocate the code by delta bytes. Called to signal that this code
5207 // object has been moved by delta bytes.
Steve Blockd0582a62009-12-15 09:54:21 +00005208 void Relocate(intptr_t delta);
Steve Blocka7e24c12009-10-30 11:49:00 +00005209
5210 // Migrate code described by desc.
5211 void CopyFrom(const CodeDesc& desc);
5212
Ben Murdoch3bec4d22010-07-22 14:51:16 +01005213 // Returns the object size for a given body (used for allocation).
5214 static int SizeFor(int body_size) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005215 DCHECK_SIZE_TAG_ALIGNED(body_size);
Ben Murdoch3bec4d22010-07-22 14:51:16 +01005216 return RoundUp(kHeaderSize + body_size, kCodeAlignment);
Steve Blocka7e24c12009-10-30 11:49:00 +00005217 }
5218
5219 // Calculate the size of the code object to report for log events. This takes
5220 // the layout of the code object into account.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005221 inline int ExecutableSize();
Steve Blocka7e24c12009-10-30 11:49:00 +00005222
5223 // Locating source position.
Ben Murdoch097c5b22016-05-18 11:27:45 +01005224 int SourcePosition(int code_offset);
5225 int SourceStatementPosition(int code_offset);
Steve Blocka7e24c12009-10-30 11:49:00 +00005226
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005227 DECLARE_CAST(Code)
Steve Blocka7e24c12009-10-30 11:49:00 +00005228
5229 // Dispatched behavior.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005230 inline int CodeSize();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005231
5232 DECLARE_PRINTER(Code)
5233 DECLARE_VERIFIER(Code)
5234
Ben Murdoch8f9999f2012-04-23 10:39:17 +01005235 void ClearInlineCaches();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005236
5237 BailoutId TranslatePcOffsetToAstId(uint32_t pc_offset);
5238 uint32_t TranslateAstIdToPcOffset(BailoutId ast_id);
5239
5240#define DECLARE_CODE_AGE_ENUM(X) k##X##CodeAge,
5241 enum Age {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005242 kToBeExecutedOnceCodeAge = -3,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005243 kNotExecutedCodeAge = -2,
5244 kExecutedOnceCodeAge = -1,
5245 kNoAgeCodeAge = 0,
5246 CODE_AGE_LIST(DECLARE_CODE_AGE_ENUM)
5247 kAfterLastCodeAge,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005248 kFirstCodeAge = kToBeExecutedOnceCodeAge,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005249 kLastCodeAge = kAfterLastCodeAge - 1,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005250 kCodeAgeCount = kAfterLastCodeAge - kFirstCodeAge - 1,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005251 kIsOldCodeAge = kSexagenarianCodeAge,
5252 kPreAgedCodeAge = kIsOldCodeAge - 1
5253 };
5254#undef DECLARE_CODE_AGE_ENUM
5255
5256 // Code aging. Indicates how many full GCs this code has survived without
5257 // being entered through the prologue. Used to determine when it is
5258 // relatively safe to flush this code object and replace it with the lazy
5259 // compilation stub.
5260 static void MakeCodeAgeSequenceYoung(byte* sequence, Isolate* isolate);
5261 static void MarkCodeAsExecuted(byte* sequence, Isolate* isolate);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005262 void MakeYoung(Isolate* isolate);
Ben Murdochda12d292016-06-02 14:46:10 +01005263 void PreAge(Isolate* isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005264 void MarkToBeExecutedOnce(Isolate* isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005265 void MakeOlder(MarkingParity);
5266 static bool IsYoungSequence(Isolate* isolate, byte* sequence);
5267 bool IsOld();
5268 Age GetAge();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005269 static inline Code* GetPreAgedCodeAgeStub(Isolate* isolate) {
5270 return GetCodeAgeStub(isolate, kNotExecutedCodeAge, NO_MARKING_PARITY);
5271 }
5272
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005273 void PrintDeoptLocation(FILE* out, Address pc);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005274 bool CanDeoptAt(Address pc);
5275
5276#ifdef VERIFY_HEAP
5277 void VerifyEmbeddedObjectsDependency();
5278#endif
5279
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005280#ifdef DEBUG
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005281 enum VerifyMode { kNoContextSpecificPointers, kNoContextRetainingPointers };
5282 void VerifyEmbeddedObjects(VerifyMode mode = kNoContextRetainingPointers);
5283 static void VerifyRecompiledCode(Code* old_code, Code* new_code);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005284#endif // DEBUG
5285
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005286 inline bool CanContainWeakObjects();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005287
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005288 inline bool IsWeakObject(Object* object);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005289
5290 static inline bool IsWeakObjectInOptimizedCode(Object* object);
Ben Murdochb0fe1622011-05-05 13:52:32 +01005291
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005292 static Handle<WeakCell> WeakCellFor(Handle<Code> code);
5293 WeakCell* CachedWeakCell();
5294
Ben Murdochb0fe1622011-05-05 13:52:32 +01005295 // Max loop nesting marker used to postpose OSR. We don't take loop
5296 // nesting that is deeper than 5 levels into account.
5297 static const int kMaxLoopNestingMarker = 6;
5298
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005299 static const int kConstantPoolSize =
5300 FLAG_enable_embedded_constant_pool ? kIntSize : 0;
5301
Steve Blocka7e24c12009-10-30 11:49:00 +00005302 // Layout description.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005303 static const int kRelocationInfoOffset = HeapObject::kHeaderSize;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005304 static const int kHandlerTableOffset = kRelocationInfoOffset + kPointerSize;
Ben Murdochb0fe1622011-05-05 13:52:32 +01005305 static const int kDeoptimizationDataOffset =
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005306 kHandlerTableOffset + kPointerSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005307 // For FUNCTION kind, we store the type feedback info here.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005308 static const int kTypeFeedbackInfoOffset =
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01005309 kDeoptimizationDataOffset + kPointerSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005310 static const int kNextCodeLinkOffset = kTypeFeedbackInfoOffset + kPointerSize;
5311 static const int kGCMetadataOffset = kNextCodeLinkOffset + kPointerSize;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005312 static const int kInstructionSizeOffset = kGCMetadataOffset + kPointerSize;
5313 static const int kICAgeOffset = kInstructionSizeOffset + kIntSize;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005314 static const int kFlagsOffset = kICAgeOffset + kIntSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005315 static const int kKindSpecificFlags1Offset = kFlagsOffset + kIntSize;
5316 static const int kKindSpecificFlags2Offset =
5317 kKindSpecificFlags1Offset + kIntSize;
5318 // Note: We might be able to squeeze this into the flags above.
5319 static const int kPrologueOffset = kKindSpecificFlags2Offset + kIntSize;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005320 static const int kConstantPoolOffset = kPrologueOffset + kIntSize;
Ben Murdochda12d292016-06-02 14:46:10 +01005321 static const int kBuiltinIndexOffset =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005322 kConstantPoolOffset + kConstantPoolSize;
Ben Murdochda12d292016-06-02 14:46:10 +01005323 static const int kHeaderPaddingStart = kBuiltinIndexOffset + kIntSize;
Ben Murdochb0fe1622011-05-05 13:52:32 +01005324
Steve Blocka7e24c12009-10-30 11:49:00 +00005325 // Add padding to align the instruction start following right after
5326 // the Code object header.
5327 static const int kHeaderSize =
Ben Murdochb0fe1622011-05-05 13:52:32 +01005328 (kHeaderPaddingStart + kCodeAlignmentMask) & ~kCodeAlignmentMask;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005329
Ben Murdoch61f157c2016-09-16 13:49:30 +01005330 inline int GetUnwindingInfoSizeOffset() const;
5331
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005332 class BodyDescriptor;
Steve Blocka7e24c12009-10-30 11:49:00 +00005333
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005334 // Byte offsets within kKindSpecificFlags1Offset.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005335 static const int kFullCodeFlags = kKindSpecificFlags1Offset;
Ben Murdoch589d6972011-11-30 16:04:58 +00005336 class FullCodeFlagsHasDeoptimizationSupportField:
5337 public BitField<bool, 0, 1> {}; // NOLINT
5338 class FullCodeFlagsHasDebugBreakSlotsField: public BitField<bool, 1, 1> {};
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005339 class FullCodeFlagsHasRelocInfoForSerialization
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005340 : public BitField<bool, 2, 1> {};
5341 // Bit 3 in this bitfield is unused.
5342 class ProfilerTicksField : public BitField<int, 4, 28> {};
Steve Blocka7e24c12009-10-30 11:49:00 +00005343
Ben Murdoch589d6972011-11-30 16:04:58 +00005344 // Flags layout. BitField<type, shift, size>.
Ben Murdoch61f157c2016-09-16 13:49:30 +01005345 class ICStateField : public BitField<InlineCacheState, 0, 2> {};
5346 class HasUnwindingInfoField : public BitField<bool, ICStateField::kNext, 1> {
5347 };
5348 class CacheHolderField
5349 : public BitField<CacheHolderFlag, HasUnwindingInfoField::kNext, 2> {};
5350 class KindField : public BitField<Kind, CacheHolderField::kNext, 5> {};
5351 STATIC_ASSERT(NUMBER_OF_KINDS <= KindField::kMax);
5352 class ExtraICStateField : public BitField<ExtraICState, KindField::kNext,
5353 PlatformSmiTagging::kSmiValueSize -
5354 KindField::kNext + 1> {};
Steve Blocka7e24c12009-10-30 11:49:00 +00005355
Ben Murdochda12d292016-06-02 14:46:10 +01005356 // KindSpecificFlags1 layout (STUB, BUILTIN and OPTIMIZED_FUNCTION)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005357 static const int kStackSlotsFirstBit = 0;
5358 static const int kStackSlotsBitCount = 24;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005359 static const int kMarkedForDeoptimizationBit =
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005360 kStackSlotsFirstBit + kStackSlotsBitCount;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005361 static const int kIsTurbofannedBit = kMarkedForDeoptimizationBit + 1;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005362 static const int kCanHaveWeakObjects = kIsTurbofannedBit + 1;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005363
5364 STATIC_ASSERT(kStackSlotsFirstBit + kStackSlotsBitCount <= 32);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005365 STATIC_ASSERT(kCanHaveWeakObjects + 1 <= 32);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005366
5367 class StackSlotsField: public BitField<int,
5368 kStackSlotsFirstBit, kStackSlotsBitCount> {}; // NOLINT
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005369 class MarkedForDeoptimizationField
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005370 : public BitField<bool, kMarkedForDeoptimizationBit, 1> {}; // NOLINT
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005371 class IsTurbofannedField : public BitField<bool, kIsTurbofannedBit, 1> {
5372 }; // NOLINT
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005373 class CanHaveWeakObjectsField
5374 : public BitField<bool, kCanHaveWeakObjects, 1> {}; // NOLINT
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005375
5376 // KindSpecificFlags2 layout (ALL)
5377 static const int kIsCrankshaftedBit = 0;
5378 class IsCrankshaftedField: public BitField<bool,
5379 kIsCrankshaftedBit, 1> {}; // NOLINT
5380
5381 // KindSpecificFlags2 layout (STUB and OPTIMIZED_FUNCTION)
5382 static const int kSafepointTableOffsetFirstBit = kIsCrankshaftedBit + 1;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005383 static const int kSafepointTableOffsetBitCount = 30;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005384
5385 STATIC_ASSERT(kSafepointTableOffsetFirstBit +
5386 kSafepointTableOffsetBitCount <= 32);
5387 STATIC_ASSERT(1 + kSafepointTableOffsetBitCount <= 32);
5388
5389 class SafepointTableOffsetField: public BitField<int,
5390 kSafepointTableOffsetFirstBit,
5391 kSafepointTableOffsetBitCount> {}; // NOLINT
5392
5393 // KindSpecificFlags2 layout (FUNCTION)
5394 class BackEdgeTableOffsetField: public BitField<int,
5395 kIsCrankshaftedBit + 1, 27> {}; // NOLINT
5396 class AllowOSRAtLoopNestingLevelField: public BitField<int,
5397 kIsCrankshaftedBit + 1 + 27, 4> {}; // NOLINT
5398 STATIC_ASSERT(AllowOSRAtLoopNestingLevelField::kMax >= kMaxLoopNestingMarker);
5399
5400 static const int kArgumentsBits = 16;
5401 static const int kMaxArguments = (1 << kArgumentsBits) - 1;
Steve Blocka7e24c12009-10-30 11:49:00 +00005402
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005403 // This constant should be encodable in an ARM instruction.
Ben Murdochc5610432016-08-08 18:44:38 +01005404 static const int kFlagsNotUsedInLookup = CacheHolderField::kMask;
Steve Blocka7e24c12009-10-30 11:49:00 +00005405
5406 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005407 friend class RelocIterator;
5408 friend class Deoptimizer; // For FindCodeAgeSequence.
5409
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005410 // Code aging
5411 byte* FindCodeAgeSequence();
5412 static void GetCodeAgeAndParity(Code* code, Age* age,
5413 MarkingParity* parity);
5414 static void GetCodeAgeAndParity(Isolate* isolate, byte* sequence, Age* age,
5415 MarkingParity* parity);
5416 static Code* GetCodeAgeStub(Isolate* isolate, Age age, MarkingParity parity);
5417
5418 // Code aging -- platform-specific
5419 static void PatchPlatformCodeAge(Isolate* isolate,
5420 byte* sequence, Age age,
5421 MarkingParity parity);
5422
Steve Blocka7e24c12009-10-30 11:49:00 +00005423 DISALLOW_IMPLICIT_CONSTRUCTORS(Code);
5424};
5425
Ben Murdoch097c5b22016-05-18 11:27:45 +01005426class AbstractCode : public HeapObject {
5427 public:
Ben Murdochda12d292016-06-02 14:46:10 +01005428 // All code kinds and INTERPRETED_FUNCTION.
5429 enum Kind {
5430#define DEFINE_CODE_KIND_ENUM(name) name,
5431 CODE_KIND_LIST(DEFINE_CODE_KIND_ENUM)
5432#undef DEFINE_CODE_KIND_ENUM
5433 INTERPRETED_FUNCTION,
Ben Murdoch61f157c2016-09-16 13:49:30 +01005434 NUMBER_OF_KINDS
Ben Murdochda12d292016-06-02 14:46:10 +01005435 };
5436
Ben Murdoch61f157c2016-09-16 13:49:30 +01005437 static const char* Kind2String(Kind kind);
5438
Ben Murdoch097c5b22016-05-18 11:27:45 +01005439 int SourcePosition(int offset);
5440 int SourceStatementPosition(int offset);
5441
Ben Murdochda12d292016-06-02 14:46:10 +01005442 // Returns the address of the first instruction.
5443 inline Address instruction_start();
5444
5445 // Returns the address right after the last instruction.
5446 inline Address instruction_end();
5447
Ben Murdoch61f157c2016-09-16 13:49:30 +01005448 // Returns the size of the code instructions.
Ben Murdochda12d292016-06-02 14:46:10 +01005449 inline int instruction_size();
5450
Ben Murdoch61f157c2016-09-16 13:49:30 +01005451 // Returns the size of instructions and the metadata.
5452 inline int SizeIncludingMetadata();
5453
Ben Murdochda12d292016-06-02 14:46:10 +01005454 // Returns true if pc is inside this object's instructions.
5455 inline bool contains(byte* pc);
5456
5457 // Returns the AbstractCode::Kind of the code.
5458 inline Kind kind();
5459
5460 // Calculate the size of the code object to report for log events. This takes
5461 // the layout of the code object into account.
5462 inline int ExecutableSize();
5463
Ben Murdoch097c5b22016-05-18 11:27:45 +01005464 DECLARE_CAST(AbstractCode)
Ben Murdoch097c5b22016-05-18 11:27:45 +01005465 inline Code* GetCode();
5466 inline BytecodeArray* GetBytecodeArray();
5467};
Steve Blocka7e24c12009-10-30 11:49:00 +00005468
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005469// Dependent code is a singly linked list of fixed arrays. Each array contains
5470// code objects in weak cells for one dependent group. The suffix of the array
5471// can be filled with the undefined value if the number of codes is less than
5472// the length of the array.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005473//
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005474// +------+-----------------+--------+--------+-----+--------+-----------+-----+
5475// | next | count & group 1 | code 1 | code 2 | ... | code n | undefined | ... |
5476// +------+-----------------+--------+--------+-----+--------+-----------+-----+
5477// |
5478// V
5479// +------+-----------------+--------+--------+-----+--------+-----------+-----+
5480// | next | count & group 2 | code 1 | code 2 | ... | code m | undefined | ... |
5481// +------+-----------------+--------+--------+-----+--------+-----------+-----+
5482// |
5483// V
5484// empty_fixed_array()
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005485//
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005486// The list of fixed arrays is ordered by dependency groups.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005487
5488class DependentCode: public FixedArray {
5489 public:
5490 enum DependencyGroup {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005491 // Group of code that weakly embed this map and depend on being
5492 // deoptimized when the map is garbage collected.
5493 kWeakCodeGroup,
5494 // Group of code that embed a transition to this map, and depend on being
5495 // deoptimized when the transition is replaced by a new version.
5496 kTransitionGroup,
5497 // Group of code that omit run-time prototype checks for prototypes
5498 // described by this map. The group is deoptimized whenever an object
5499 // described by this map changes shape (and transitions to a new map),
5500 // possibly invalidating the assumptions embedded in the code.
5501 kPrototypeCheckGroup,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005502 // Group of code that depends on global property values in property cells
5503 // not being changed.
5504 kPropertyCellChangedGroup,
5505 // Group of code that omit run-time type checks for the field(s) introduced
5506 // by this map.
5507 kFieldTypeGroup,
5508 // Group of code that omit run-time type checks for initial maps of
5509 // constructors.
5510 kInitialMapChangedGroup,
5511 // Group of code that depends on tenuring information in AllocationSites
5512 // not being changed.
5513 kAllocationSiteTenuringChangedGroup,
5514 // Group of code that depends on element transition information in
5515 // AllocationSites not being changed.
5516 kAllocationSiteTransitionChangedGroup
5517 };
5518
5519 static const int kGroupCount = kAllocationSiteTransitionChangedGroup + 1;
5520
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005521 bool Contains(DependencyGroup group, WeakCell* code_cell);
5522 bool IsEmpty(DependencyGroup group);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005523
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005524 static Handle<DependentCode> InsertCompilationDependencies(
5525 Handle<DependentCode> entries, DependencyGroup group,
5526 Handle<Foreign> info);
5527
5528 static Handle<DependentCode> InsertWeakCode(Handle<DependentCode> entries,
5529 DependencyGroup group,
5530 Handle<WeakCell> code_cell);
5531
5532 void UpdateToFinishedCode(DependencyGroup group, Foreign* info,
5533 WeakCell* code_cell);
5534
5535 void RemoveCompilationDependencies(DependentCode::DependencyGroup group,
5536 Foreign* info);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005537
5538 void DeoptimizeDependentCodeGroup(Isolate* isolate,
5539 DependentCode::DependencyGroup group);
5540
5541 bool MarkCodeForDeoptimization(Isolate* isolate,
5542 DependentCode::DependencyGroup group);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005543
5544 // The following low-level accessors should only be used by this class
5545 // and the mark compact collector.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005546 inline DependentCode* next_link();
5547 inline void set_next_link(DependentCode* next);
5548 inline int count();
5549 inline void set_count(int value);
5550 inline DependencyGroup group();
5551 inline void set_group(DependencyGroup group);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005552 inline Object* object_at(int i);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005553 inline void set_object_at(int i, Object* object);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005554 inline void clear_at(int i);
5555 inline void copy(int from, int to);
5556 DECLARE_CAST(DependentCode)
5557
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005558 static const char* DependencyGroupName(DependencyGroup group);
5559 static void SetMarkedForDeoptimization(Code* code, DependencyGroup group);
5560
5561 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005562 static Handle<DependentCode> Insert(Handle<DependentCode> entries,
5563 DependencyGroup group,
5564 Handle<Object> object);
5565 static Handle<DependentCode> New(DependencyGroup group, Handle<Object> object,
5566 Handle<DependentCode> next);
5567 static Handle<DependentCode> EnsureSpace(Handle<DependentCode> entries);
5568 // Compact by removing cleared weak cells and return true if there was
5569 // any cleared weak cell.
5570 bool Compact();
5571 static int Grow(int number_of_entries) {
5572 if (number_of_entries < 5) return number_of_entries + 1;
5573 return number_of_entries * 5 / 4;
5574 }
5575 inline int flags();
5576 inline void set_flags(int flags);
5577 class GroupField : public BitField<int, 0, 3> {};
5578 class CountField : public BitField<int, 3, 27> {};
5579 STATIC_ASSERT(kGroupCount <= GroupField::kMax + 1);
5580 static const int kNextLinkIndex = 0;
5581 static const int kFlagsIndex = 1;
5582 static const int kCodesStartIndex = 2;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005583};
5584
5585
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005586class PrototypeInfo;
5587
5588
Steve Blocka7e24c12009-10-30 11:49:00 +00005589// All heap objects have a Map that describes their structure.
5590// A Map contains information about:
5591// - Size information about the object
5592// - How to iterate over an object (for garbage collection)
5593class Map: public HeapObject {
5594 public:
5595 // Instance size.
Steve Block791712a2010-08-27 10:21:07 +01005596 // Size in bytes or kVariableSizeSentinel if instances do not have
5597 // a fixed size.
Steve Blocka7e24c12009-10-30 11:49:00 +00005598 inline int instance_size();
5599 inline void set_instance_size(int value);
5600
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005601 // Only to clear an unused byte, remove once byte is used.
5602 inline void clear_unused();
Steve Blocka7e24c12009-10-30 11:49:00 +00005603
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005604 // [inobject_properties_or_constructor_function_index]: Provides access
5605 // to the inobject properties in case of JSObject maps, or the constructor
5606 // function index in case of primitive maps.
5607 inline int inobject_properties_or_constructor_function_index();
5608 inline void set_inobject_properties_or_constructor_function_index(int value);
5609 // Count of properties allocated in the object (JSObject only).
5610 inline int GetInObjectProperties();
5611 inline void SetInObjectProperties(int value);
5612 // Index of the constructor function in the native context (primitives only),
5613 // or the special sentinel value to indicate that there is no object wrapper
5614 // for the primitive (i.e. in case of null or undefined).
5615 static const int kNoConstructorFunctionIndex = 0;
5616 inline int GetConstructorFunctionIndex();
5617 inline void SetConstructorFunctionIndex(int value);
5618 static MaybeHandle<JSFunction> GetConstructorFunction(
5619 Handle<Map> map, Handle<Context> native_context);
Steve Blocka7e24c12009-10-30 11:49:00 +00005620
Ben Murdochda12d292016-06-02 14:46:10 +01005621 // Retrieve interceptors.
5622 inline InterceptorInfo* GetNamedInterceptor();
5623 inline InterceptorInfo* GetIndexedInterceptor();
5624
Steve Blocka7e24c12009-10-30 11:49:00 +00005625 // Instance type.
5626 inline InstanceType instance_type();
5627 inline void set_instance_type(InstanceType value);
5628
5629 // Tells how many unused property fields are available in the
5630 // instance (only used for JSObject in fast mode).
5631 inline int unused_property_fields();
5632 inline void set_unused_property_fields(int value);
5633
5634 // Bit field.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005635 inline byte bit_field() const;
Steve Blocka7e24c12009-10-30 11:49:00 +00005636 inline void set_bit_field(byte value);
5637
5638 // Bit field 2.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005639 inline byte bit_field2() const;
Steve Blocka7e24c12009-10-30 11:49:00 +00005640 inline void set_bit_field2(byte value);
5641
Ben Murdoch257744e2011-11-30 15:57:28 +00005642 // Bit field 3.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005643 inline uint32_t bit_field3() const;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005644 inline void set_bit_field3(uint32_t bits);
5645
5646 class EnumLengthBits: public BitField<int,
5647 0, kDescriptorIndexBitCount> {}; // NOLINT
5648 class NumberOfOwnDescriptorsBits: public BitField<int,
5649 kDescriptorIndexBitCount, kDescriptorIndexBitCount> {}; // NOLINT
5650 STATIC_ASSERT(kDescriptorIndexBitCount + kDescriptorIndexBitCount == 20);
5651 class DictionaryMap : public BitField<bool, 20, 1> {};
5652 class OwnsDescriptors : public BitField<bool, 21, 1> {};
Ben Murdoch097c5b22016-05-18 11:27:45 +01005653 class HasHiddenPrototype : public BitField<bool, 22, 1> {};
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005654 class Deprecated : public BitField<bool, 23, 1> {};
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005655 class IsUnstable : public BitField<bool, 24, 1> {};
5656 class IsMigrationTarget : public BitField<bool, 25, 1> {};
Ben Murdochda12d292016-06-02 14:46:10 +01005657 // Bit 26 is free.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005658 class NewTargetIsBase : public BitField<bool, 27, 1> {};
5659 // Bit 28 is free.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005660
5661 // Keep this bit field at the very end for better code in
5662 // Builtins::kJSConstructStubGeneric stub.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005663 // This counter is used for in-object slack tracking.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005664 // The in-object slack tracking is considered enabled when the counter is
Ben Murdoch097c5b22016-05-18 11:27:45 +01005665 // non zero. The counter only has a valid count for initial maps. For
5666 // transitioned maps only kNoSlackTracking has a meaning, namely that inobject
5667 // slack tracking already finished for the transition tree. Any other value
5668 // indicates that either inobject slack tracking is still in progress, or that
5669 // the map isn't part of the transition tree anymore.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005670 class ConstructionCounter : public BitField<int, 29, 3> {};
5671 static const int kSlackTrackingCounterStart = 7;
5672 static const int kSlackTrackingCounterEnd = 1;
5673 static const int kNoSlackTracking = 0;
5674 STATIC_ASSERT(kSlackTrackingCounterStart <= ConstructionCounter::kMax);
5675
5676
5677 // Inobject slack tracking is the way to reclaim unused inobject space.
5678 //
5679 // The instance size is initially determined by adding some slack to
5680 // expected_nof_properties (to allow for a few extra properties added
5681 // after the constructor). There is no guarantee that the extra space
5682 // will not be wasted.
5683 //
5684 // Here is the algorithm to reclaim the unused inobject space:
5685 // - Detect the first constructor call for this JSFunction.
5686 // When it happens enter the "in progress" state: initialize construction
5687 // counter in the initial_map.
5688 // - While the tracking is in progress initialize unused properties of a new
5689 // object with one_pointer_filler_map instead of undefined_value (the "used"
5690 // part is initialized with undefined_value as usual). This way they can
5691 // be resized quickly and safely.
5692 // - Once enough objects have been created compute the 'slack'
5693 // (traverse the map transition tree starting from the
5694 // initial_map and find the lowest value of unused_property_fields).
5695 // - Traverse the transition tree again and decrease the instance size
5696 // of every map. Existing objects will resize automatically (they are
5697 // filled with one_pointer_filler_map). All further allocations will
5698 // use the adjusted instance size.
5699 // - SharedFunctionInfo's expected_nof_properties left unmodified since
5700 // allocations made using different closures could actually create different
5701 // kind of objects (see prototype inheritance pattern).
5702 //
5703 // Important: inobject slack tracking is not attempted during the snapshot
5704 // creation.
5705
5706 static const int kGenerousAllocationCount =
5707 kSlackTrackingCounterStart - kSlackTrackingCounterEnd + 1;
5708
5709 // Starts the tracking by initializing object constructions countdown counter.
5710 void StartInobjectSlackTracking();
5711
5712 // True if the object constructions countdown counter is a range
5713 // [kSlackTrackingCounterEnd, kSlackTrackingCounterStart].
5714 inline bool IsInobjectSlackTrackingInProgress();
5715
5716 // Does the tracking step.
5717 inline void InobjectSlackTrackingStep();
5718
5719 // Completes inobject slack tracking for the transition tree starting at this
5720 // initial map.
5721 void CompleteInobjectSlackTracking();
Ben Murdoch257744e2011-11-30 15:57:28 +00005722
Steve Blocka7e24c12009-10-30 11:49:00 +00005723 // Tells whether the object in the prototype property will be used
5724 // for instances created from this function. If the prototype
5725 // property is set to a value that is not a JSObject, the prototype
5726 // property will not be used to create instances of the function.
5727 // See ECMA-262, 13.2.2.
5728 inline void set_non_instance_prototype(bool value);
5729 inline bool has_non_instance_prototype();
5730
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005731 // Tells whether the instance has a [[Construct]] internal method.
5732 // This property is implemented according to ES6, section 7.2.4.
Ben Murdoch097c5b22016-05-18 11:27:45 +01005733 inline void set_is_constructor(bool value);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005734 inline bool is_constructor() const;
Steve Block6ded16b2010-05-10 14:33:55 +01005735
Ben Murdoch097c5b22016-05-18 11:27:45 +01005736 // Tells whether the instance with this map has a hidden prototype.
5737 inline void set_has_hidden_prototype(bool value);
5738 inline bool has_hidden_prototype() const;
Steve Blocka7e24c12009-10-30 11:49:00 +00005739
5740 // Records and queries whether the instance has a named interceptor.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005741 inline void set_has_named_interceptor();
5742 inline bool has_named_interceptor();
Steve Blocka7e24c12009-10-30 11:49:00 +00005743
5744 // Records and queries whether the instance has an indexed interceptor.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005745 inline void set_has_indexed_interceptor();
5746 inline bool has_indexed_interceptor();
Steve Blocka7e24c12009-10-30 11:49:00 +00005747
5748 // Tells whether the instance is undetectable.
5749 // An undetectable object is a special class of JSObject: 'typeof' operator
5750 // returns undefined, ToBoolean returns false. Otherwise it behaves like
5751 // a normal JS object. It is useful for implementing undetectable
5752 // document.all in Firefox & Safari.
5753 // See https://bugzilla.mozilla.org/show_bug.cgi?id=248549.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005754 inline void set_is_undetectable();
5755 inline bool is_undetectable();
Steve Blocka7e24c12009-10-30 11:49:00 +00005756
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005757 // Tells whether the instance has a [[Call]] internal method.
5758 // This property is implemented according to ES6, section 7.2.3.
5759 inline void set_is_callable();
5760 inline bool is_callable() const;
Steve Blocka7e24c12009-10-30 11:49:00 +00005761
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005762 inline void set_new_target_is_base(bool value);
5763 inline bool new_target_is_base();
Steve Block8defd9f2010-07-08 12:39:36 +01005764 inline void set_is_extensible(bool value);
5765 inline bool is_extensible();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005766 inline void set_is_prototype_map(bool value);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005767 inline bool is_prototype_map() const;
Steve Block8defd9f2010-07-08 12:39:36 +01005768
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005769 inline void set_elements_kind(ElementsKind elements_kind);
5770 inline ElementsKind elements_kind();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005771
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005772 // Tells whether the instance has fast elements that are only Smis.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005773 inline bool has_fast_smi_elements();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005774
Steve Block8defd9f2010-07-08 12:39:36 +01005775 // Tells whether the instance has fast elements.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005776 inline bool has_fast_object_elements();
5777 inline bool has_fast_smi_or_object_elements();
5778 inline bool has_fast_double_elements();
5779 inline bool has_fast_elements();
5780 inline bool has_sloppy_arguments_elements();
Ben Murdoch61f157c2016-09-16 13:49:30 +01005781 inline bool has_fast_sloppy_arguments_elements();
Ben Murdoch097c5b22016-05-18 11:27:45 +01005782 inline bool has_fast_string_wrapper_elements();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005783 inline bool has_fixed_typed_array_elements();
5784 inline bool has_dictionary_elements();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005785
5786 static bool IsValidElementsTransition(ElementsKind from_kind,
5787 ElementsKind to_kind);
5788
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005789 // Returns true if the current map doesn't have DICTIONARY_ELEMENTS but if a
5790 // map with DICTIONARY_ELEMENTS was found in the prototype chain.
5791 bool DictionaryElementsInPrototypeChainOnly();
Kristian Monsen0d5e1162010-09-30 15:31:59 +01005792
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005793 inline Map* ElementsTransitionMap();
Kristian Monsen0d5e1162010-09-30 15:31:59 +01005794
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005795 inline FixedArrayBase* GetInitialElements();
Kristian Monsen0d5e1162010-09-30 15:31:59 +01005796
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005797 // [raw_transitions]: Provides access to the transitions storage field.
5798 // Don't call set_raw_transitions() directly to overwrite transitions, use
5799 // the TransitionArray::ReplaceTransitions() wrapper instead!
5800 DECL_ACCESSORS(raw_transitions, Object)
5801 // [prototype_info]: Per-prototype metadata. Aliased with transitions
5802 // (which prototype maps don't have).
5803 DECL_ACCESSORS(prototype_info, Object)
5804 // PrototypeInfo is created lazily using this helper (which installs it on
5805 // the given prototype's map).
5806 static Handle<PrototypeInfo> GetOrCreatePrototypeInfo(
5807 Handle<JSObject> prototype, Isolate* isolate);
5808 static Handle<PrototypeInfo> GetOrCreatePrototypeInfo(
5809 Handle<Map> prototype_map, Isolate* isolate);
Ben Murdoch61f157c2016-09-16 13:49:30 +01005810 inline bool should_be_fast_prototype_map() const;
5811 static void SetShouldBeFastPrototypeMap(Handle<Map> map, bool value,
5812 Isolate* isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005813
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005814 // [prototype chain validity cell]: Associated with a prototype object,
5815 // stored in that object's map's PrototypeInfo, indicates that prototype
5816 // chains through this object are currently valid. The cell will be
5817 // invalidated and replaced when the prototype chain changes.
5818 static Handle<Cell> GetOrCreatePrototypeChainValidityCell(Handle<Map> map,
5819 Isolate* isolate);
5820 static const int kPrototypeChainValid = 0;
5821 static const int kPrototypeChainInvalid = 1;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005822
5823 Map* FindRootMap();
5824 Map* FindFieldOwner(int descriptor);
5825
5826 inline int GetInObjectPropertyOffset(int index);
5827
5828 int NumberOfFields();
5829
5830 // TODO(ishell): candidate with JSObject::MigrateToMap().
Ben Murdochc5610432016-08-08 18:44:38 +01005831 bool InstancesNeedRewriting(Map* target);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005832 bool InstancesNeedRewriting(Map* target, int target_number_of_fields,
5833 int target_inobject, int target_unused,
5834 int* old_number_of_fields);
5835 // TODO(ishell): moveit!
5836 static Handle<Map> GeneralizeAllFieldRepresentations(Handle<Map> map);
Ben Murdoch097c5b22016-05-18 11:27:45 +01005837 MUST_USE_RESULT static Handle<FieldType> GeneralizeFieldType(
5838 Representation rep1, Handle<FieldType> type1, Representation rep2,
5839 Handle<FieldType> type2, Isolate* isolate);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005840 static void GeneralizeFieldType(Handle<Map> map, int modify_index,
5841 Representation new_representation,
Ben Murdoch097c5b22016-05-18 11:27:45 +01005842 Handle<FieldType> new_field_type);
Ben Murdochc5610432016-08-08 18:44:38 +01005843
5844 static inline Handle<Map> ReconfigureProperty(
5845 Handle<Map> map, int modify_index, PropertyKind new_kind,
5846 PropertyAttributes new_attributes, Representation new_representation,
5847 Handle<FieldType> new_field_type, StoreMode store_mode);
5848
5849 static inline Handle<Map> ReconfigureElementsKind(
5850 Handle<Map> map, ElementsKind new_elements_kind);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005851
5852 static Handle<Map> PrepareForDataProperty(Handle<Map> old_map,
5853 int descriptor_number,
5854 Handle<Object> value);
5855
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005856 static Handle<Map> Normalize(Handle<Map> map, PropertyNormalizationMode mode,
5857 const char* reason);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005858
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005859 // Tells whether the map is used for JSObjects in dictionary mode (ie
5860 // normalized objects, ie objects for which HasFastProperties returns false).
5861 // A map can never be used for both dictionary mode and fast mode JSObjects.
5862 // False by default and for HeapObjects that are not JSObjects.
5863 inline void set_dictionary_map(bool value);
5864 inline bool is_dictionary_map();
Kristian Monsen0d5e1162010-09-30 15:31:59 +01005865
Steve Blocka7e24c12009-10-30 11:49:00 +00005866 // Tells whether the instance needs security checks when accessing its
5867 // properties.
5868 inline void set_is_access_check_needed(bool access_check_needed);
5869 inline bool is_access_check_needed();
5870
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005871 // Returns true if map has a non-empty stub code cache.
5872 inline bool has_code_cache();
5873
Steve Blocka7e24c12009-10-30 11:49:00 +00005874 // [prototype]: implicit prototype object.
5875 DECL_ACCESSORS(prototype, Object)
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005876 // TODO(jkummerow): make set_prototype private.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005877 static void SetPrototype(
5878 Handle<Map> map, Handle<Object> prototype,
5879 PrototypeOptimizationMode proto_mode = FAST_PROTOTYPE);
Steve Blocka7e24c12009-10-30 11:49:00 +00005880
5881 // [constructor]: points back to the function responsible for this map.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005882 // The field overlaps with the back pointer. All maps in a transition tree
5883 // have the same constructor, so maps with back pointers can walk the
5884 // back pointer chain until they find the map holding their constructor.
5885 DECL_ACCESSORS(constructor_or_backpointer, Object)
5886 inline Object* GetConstructor() const;
5887 inline void SetConstructor(Object* constructor,
5888 WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
5889 // [back pointer]: points back to the parent map from which a transition
5890 // leads to this map. The field overlaps with the constructor (see above).
5891 inline Object* GetBackPointer();
5892 inline void SetBackPointer(Object* value,
5893 WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
Steve Blocka7e24c12009-10-30 11:49:00 +00005894
5895 // [instance descriptors]: describes the object.
5896 DECL_ACCESSORS(instance_descriptors, DescriptorArray)
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005897
5898 // [layout descriptor]: describes the object layout.
5899 DECL_ACCESSORS(layout_descriptor, LayoutDescriptor)
5900 // |layout descriptor| accessor which can be used from GC.
5901 inline LayoutDescriptor* layout_descriptor_gc_safe();
5902 inline bool HasFastPointerLayout() const;
5903
5904 // |layout descriptor| accessor that is safe to call even when
5905 // FLAG_unbox_double_fields is disabled (in this case Map does not contain
5906 // |layout_descriptor| field at all).
5907 inline LayoutDescriptor* GetLayoutDescriptor();
5908
5909 inline void UpdateDescriptors(DescriptorArray* descriptors,
5910 LayoutDescriptor* layout_descriptor);
5911 inline void InitializeDescriptors(DescriptorArray* descriptors,
5912 LayoutDescriptor* layout_descriptor);
Ben Murdoch257744e2011-11-30 15:57:28 +00005913
Steve Blocka7e24c12009-10-30 11:49:00 +00005914 // [stub cache]: contains stubs compiled for this map.
Ben Murdoch61f157c2016-09-16 13:49:30 +01005915 DECL_ACCESSORS(code_cache, FixedArray)
Steve Blocka7e24c12009-10-30 11:49:00 +00005916
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005917 // [dependent code]: list of optimized codes that weakly embed this map.
5918 DECL_ACCESSORS(dependent_code, DependentCode)
5919
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005920 // [weak cell cache]: cache that stores a weak cell pointing to this map.
5921 DECL_ACCESSORS(weak_cell_cache, Object)
Kristian Monsen80d68ea2010-09-08 11:05:35 +01005922
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005923 inline PropertyDetails GetLastDescriptorDetails();
5924
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005925 inline int LastAdded();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005926
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005927 inline int NumberOfOwnDescriptors();
5928 inline void SetNumberOfOwnDescriptors(int number);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005929
5930 inline Cell* RetrieveDescriptorsPointer();
5931
Ben Murdoch097c5b22016-05-18 11:27:45 +01005932 // Checks whether all properties are stored either in the map or on the object
5933 // (inobject, properties, or elements backing store), requiring no special
5934 // checks.
5935 bool OnlyHasSimpleProperties();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005936 inline int EnumLength();
5937 inline void SetEnumLength(int length);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005938
5939 inline bool owns_descriptors();
5940 inline void set_owns_descriptors(bool owns_descriptors);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005941 inline void mark_unstable();
5942 inline bool is_stable();
5943 inline void set_migration_target(bool value);
5944 inline bool is_migration_target();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005945 inline void set_construction_counter(int value);
5946 inline int construction_counter();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005947 inline void deprecate();
5948 inline bool is_deprecated();
5949 inline bool CanBeDeprecated();
5950 // Returns a non-deprecated version of the input. If the input was not
5951 // deprecated, it is directly returned. Otherwise, the non-deprecated version
5952 // is found by re-transitioning from the root of the transition tree using the
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005953 // descriptor array of the map. Returns MaybeHandle<Map>() if no updated map
5954 // is found.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005955 static MaybeHandle<Map> TryUpdate(Handle<Map> map) WARN_UNUSED_RESULT;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005956
5957 // Returns a non-deprecated version of the input. This method may deprecate
5958 // existing maps along the way if encodings conflict. Not for use while
5959 // gathering type feedback. Use TryUpdate in those cases instead.
5960 static Handle<Map> Update(Handle<Map> map);
5961
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005962 static inline Handle<Map> CopyInitialMap(Handle<Map> map);
5963 static Handle<Map> CopyInitialMap(Handle<Map> map, int instance_size,
5964 int in_object_properties,
5965 int unused_property_fields);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005966 static Handle<Map> CopyDropDescriptors(Handle<Map> map);
5967 static Handle<Map> CopyInsertDescriptor(Handle<Map> map,
5968 Descriptor* descriptor,
5969 TransitionFlag flag);
5970
5971 MUST_USE_RESULT static MaybeHandle<Map> CopyWithField(
Ben Murdoch097c5b22016-05-18 11:27:45 +01005972 Handle<Map> map, Handle<Name> name, Handle<FieldType> type,
5973 PropertyAttributes attributes, Representation representation,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005974 TransitionFlag flag);
5975
5976 MUST_USE_RESULT static MaybeHandle<Map> CopyWithConstant(
5977 Handle<Map> map,
5978 Handle<Name> name,
5979 Handle<Object> constant,
5980 PropertyAttributes attributes,
5981 TransitionFlag flag);
5982
5983 // Returns a new map with all transitions dropped from the given map and
5984 // the ElementsKind set.
5985 static Handle<Map> TransitionElementsTo(Handle<Map> map,
5986 ElementsKind to_kind);
5987
5988 static Handle<Map> AsElementsKind(Handle<Map> map, ElementsKind kind);
5989
5990 static Handle<Map> CopyAsElementsKind(Handle<Map> map,
5991 ElementsKind kind,
5992 TransitionFlag flag);
5993
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005994 static Handle<Map> AsLanguageMode(Handle<Map> initial_map,
5995 LanguageMode language_mode,
5996 FunctionKind kind);
5997
5998
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005999 static Handle<Map> CopyForPreventExtensions(Handle<Map> map,
6000 PropertyAttributes attrs_to_add,
6001 Handle<Symbol> transition_marker,
6002 const char* reason);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006003
6004 static Handle<Map> FixProxy(Handle<Map> map, InstanceType type, int size);
6005
6006
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006007 // Maximal number of fast properties. Used to restrict the number of map
6008 // transitions to avoid an explosion in the number of maps for objects used as
6009 // dictionaries.
6010 inline bool TooManyFastProperties(StoreFromKeyed store_mode);
6011 static Handle<Map> TransitionToDataProperty(Handle<Map> map,
6012 Handle<Name> name,
6013 Handle<Object> value,
6014 PropertyAttributes attributes,
6015 StoreFromKeyed store_mode);
6016 static Handle<Map> TransitionToAccessorProperty(
Ben Murdochc5610432016-08-08 18:44:38 +01006017 Isolate* isolate, Handle<Map> map, Handle<Name> name, int descriptor,
6018 Handle<Object> getter, Handle<Object> setter,
Ben Murdochda12d292016-06-02 14:46:10 +01006019 PropertyAttributes attributes);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006020 static Handle<Map> ReconfigureExistingProperty(Handle<Map> map,
6021 int descriptor,
6022 PropertyKind kind,
6023 PropertyAttributes attributes);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006024
6025 inline void AppendDescriptor(Descriptor* desc);
Steve Blocka7e24c12009-10-30 11:49:00 +00006026
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006027 // Returns a copy of the map, prepared for inserting into the transition
6028 // tree (if the |map| owns descriptors then the new one will share
6029 // descriptors with |map|).
6030 static Handle<Map> CopyForTransition(Handle<Map> map, const char* reason);
6031
Steve Blocka7e24c12009-10-30 11:49:00 +00006032 // Returns a copy of the map, with all transitions dropped from the
6033 // instance descriptors.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006034 static Handle<Map> Copy(Handle<Map> map, const char* reason);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006035 static Handle<Map> Create(Isolate* isolate, int inobject_properties);
Steve Blocka7e24c12009-10-30 11:49:00 +00006036
6037 // Returns the next free property index (only valid for FAST MODE).
6038 int NextFreePropertyIndex();
6039
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006040 // Returns the number of properties described in instance_descriptors
6041 // filtering out properties with the specified attributes.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006042 int NumberOfDescribedProperties(DescriptorFlag which = OWN_DESCRIPTORS,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006043 PropertyFilter filter = ALL_PROPERTIES);
Steve Blocka7e24c12009-10-30 11:49:00 +00006044
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006045 DECLARE_CAST(Map)
Steve Blocka7e24c12009-10-30 11:49:00 +00006046
6047 // Code cache operations.
6048
6049 // Clears the code cache.
Steve Block44f0eee2011-05-26 01:26:41 +01006050 inline void ClearCodeCache(Heap* heap);
Steve Blocka7e24c12009-10-30 11:49:00 +00006051
6052 // Update code cache.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006053 static void UpdateCodeCache(Handle<Map> map,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006054 Handle<Name> name,
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006055 Handle<Code> code);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006056
6057 // Extend the descriptor array of the map with the list of descriptors.
6058 // In case of duplicates, the latest descriptor is used.
6059 static void AppendCallbackDescriptors(Handle<Map> map,
6060 Handle<Object> descriptors);
6061
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006062 static inline int SlackForArraySize(int old_size, int size_limit);
6063
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006064 static void EnsureDescriptorSlack(Handle<Map> map, int slack);
Steve Blocka7e24c12009-10-30 11:49:00 +00006065
Ben Murdochc5610432016-08-08 18:44:38 +01006066 Code* LookupInCodeCache(Name* name, Code::Flags code);
Steve Blocka7e24c12009-10-30 11:49:00 +00006067
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00006068 // Computes a hash value for this map, to be used in HashTables and such.
6069 int Hash();
6070
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006071 // Returns the transitioned map for this map with the most generic
Ben Murdochc5610432016-08-08 18:44:38 +01006072 // elements_kind that's found in |candidates|, or |nullptr| if no match is
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006073 // found at all.
Ben Murdochc5610432016-08-08 18:44:38 +01006074 Map* FindElementsKindTransitionedMap(MapHandleList* candidates);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006075
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006076 inline bool CanTransition();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006077
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006078 inline bool IsBooleanMap();
6079 inline bool IsPrimitiveMap();
6080 inline bool IsJSReceiverMap();
6081 inline bool IsJSObjectMap();
6082 inline bool IsJSArrayMap();
6083 inline bool IsJSFunctionMap();
6084 inline bool IsStringMap();
6085 inline bool IsJSProxyMap();
6086 inline bool IsJSGlobalProxyMap();
6087 inline bool IsJSGlobalObjectMap();
6088 inline bool IsJSTypedArrayMap();
6089 inline bool IsJSDataViewMap();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006090
6091 inline bool CanOmitMapChecks();
6092
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006093 static void AddDependentCode(Handle<Map> map,
6094 DependentCode::DependencyGroup group,
6095 Handle<Code> code);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006096
6097 bool IsMapInArrayPrototypeChain();
Ben Murdoch592a9fc2012-03-05 11:04:45 +00006098
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006099 static Handle<WeakCell> WeakCellForMap(Handle<Map> map);
6100
Steve Blocka7e24c12009-10-30 11:49:00 +00006101 // Dispatched behavior.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006102 DECLARE_PRINTER(Map)
6103 DECLARE_VERIFIER(Map)
6104
6105#ifdef VERIFY_HEAP
6106 void DictionaryMapVerify();
6107 void VerifyOmittedMapChecks();
Steve Blocka7e24c12009-10-30 11:49:00 +00006108#endif
6109
Iain Merrick75681382010-08-19 15:07:18 +01006110 inline int visitor_id();
6111 inline void set_visitor_id(int visitor_id);
Ben Murdoch3bec4d22010-07-22 14:51:16 +01006112
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006113 static Handle<Map> TransitionToPrototype(Handle<Map> map,
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006114 Handle<Object> prototype,
6115 PrototypeOptimizationMode mode);
Steve Block053d10c2011-06-13 19:13:29 +01006116
Steve Blocka7e24c12009-10-30 11:49:00 +00006117 static const int kMaxPreAllocatedPropertyFields = 255;
6118
6119 // Layout description.
6120 static const int kInstanceSizesOffset = HeapObject::kHeaderSize;
6121 static const int kInstanceAttributesOffset = kInstanceSizesOffset + kIntSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006122 static const int kBitField3Offset = kInstanceAttributesOffset + kIntSize;
6123 static const int kPrototypeOffset = kBitField3Offset + kPointerSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006124 static const int kConstructorOrBackPointerOffset =
6125 kPrototypeOffset + kPointerSize;
6126 // When there is only one transition, it is stored directly in this field;
6127 // otherwise a transition array is used.
6128 // For prototype maps, this slot is used to store this map's PrototypeInfo
6129 // struct.
6130 static const int kTransitionsOrPrototypeInfoOffset =
6131 kConstructorOrBackPointerOffset + kPointerSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006132 static const int kDescriptorsOffset =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006133 kTransitionsOrPrototypeInfoOffset + kPointerSize;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006134#if V8_DOUBLE_FIELDS_UNBOXING
6135 static const int kLayoutDecriptorOffset = kDescriptorsOffset + kPointerSize;
6136 static const int kCodeCacheOffset = kLayoutDecriptorOffset + kPointerSize;
6137#else
6138 static const int kLayoutDecriptorOffset = 1; // Must not be ever accessed.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006139 static const int kCodeCacheOffset = kDescriptorsOffset + kPointerSize;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006140#endif
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006141 static const int kDependentCodeOffset = kCodeCacheOffset + kPointerSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006142 static const int kWeakCellCacheOffset = kDependentCodeOffset + kPointerSize;
6143 static const int kSize = kWeakCellCacheOffset + kPointerSize;
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01006144
6145 // Layout of pointer fields. Heap iteration code relies on them
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006146 // being continuously allocated.
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01006147 static const int kPointerFieldsBeginOffset = Map::kPrototypeOffset;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006148 static const int kPointerFieldsEndOffset = kSize;
Steve Blocka7e24c12009-10-30 11:49:00 +00006149
6150 // Byte offsets within kInstanceSizesOffset.
6151 static const int kInstanceSizeOffset = kInstanceSizesOffset + 0;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006152 static const int kInObjectPropertiesOrConstructorFunctionIndexByte = 1;
6153 static const int kInObjectPropertiesOrConstructorFunctionIndexOffset =
6154 kInstanceSizesOffset + kInObjectPropertiesOrConstructorFunctionIndexByte;
6155 // Note there is one byte available for use here.
6156 static const int kUnusedByte = 2;
6157 static const int kUnusedOffset = kInstanceSizesOffset + kUnusedByte;
Iain Merrick9ac36c92010-09-13 15:29:50 +01006158 static const int kVisitorIdByte = 3;
6159 static const int kVisitorIdOffset = kInstanceSizesOffset + kVisitorIdByte;
Steve Blocka7e24c12009-10-30 11:49:00 +00006160
6161 // Byte offsets within kInstanceAttributesOffset attributes.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006162#if V8_TARGET_LITTLE_ENDIAN
6163 // Order instance type and bit field together such that they can be loaded
6164 // together as a 16-bit word with instance type in the lower 8 bits regardless
6165 // of endianess. Also provide endian-independent offset to that 16-bit word.
Steve Blocka7e24c12009-10-30 11:49:00 +00006166 static const int kInstanceTypeOffset = kInstanceAttributesOffset + 0;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006167 static const int kBitFieldOffset = kInstanceAttributesOffset + 1;
6168#else
6169 static const int kBitFieldOffset = kInstanceAttributesOffset + 0;
6170 static const int kInstanceTypeOffset = kInstanceAttributesOffset + 1;
6171#endif
6172 static const int kInstanceTypeAndBitFieldOffset =
6173 kInstanceAttributesOffset + 0;
6174 static const int kBitField2Offset = kInstanceAttributesOffset + 2;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006175 static const int kUnusedPropertyFieldsByte = 3;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006176 static const int kUnusedPropertyFieldsOffset = kInstanceAttributesOffset + 3;
Steve Blocka7e24c12009-10-30 11:49:00 +00006177
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006178 STATIC_ASSERT(kInstanceTypeAndBitFieldOffset ==
6179 Internals::kMapInstanceTypeAndBitFieldOffset);
Steve Blocka7e24c12009-10-30 11:49:00 +00006180
6181 // Bit positions for bit field.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006182 static const int kHasNonInstancePrototype = 0;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006183 static const int kIsCallable = 1;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006184 static const int kHasNamedInterceptor = 2;
6185 static const int kHasIndexedInterceptor = 3;
6186 static const int kIsUndetectable = 4;
Ben Murdochc5610432016-08-08 18:44:38 +01006187 static const int kIsAccessCheckNeeded = 5;
6188 static const int kIsConstructor = 6;
6189 // Bit 7 is free.
Steve Blocka7e24c12009-10-30 11:49:00 +00006190
6191 // Bit positions for bit field 2
Andrei Popescu31002712010-02-23 13:46:05 +00006192 static const int kIsExtensible = 0;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006193 // Bit 1 is free.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006194 class IsPrototypeMapBits : public BitField<bool, 2, 1> {};
6195 class ElementsKindBits: public BitField<ElementsKind, 3, 5> {};
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00006196
6197 // Derived values from bit field 2
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00006198 static const int8_t kMaximumBitField2FastElementValue = static_cast<int8_t>(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006199 (FAST_ELEMENTS + 1) << Map::ElementsKindBits::kShift) - 1;
6200 static const int8_t kMaximumBitField2FastSmiElementValue =
6201 static_cast<int8_t>((FAST_SMI_ELEMENTS + 1) <<
6202 Map::ElementsKindBits::kShift) - 1;
6203 static const int8_t kMaximumBitField2FastHoleyElementValue =
6204 static_cast<int8_t>((FAST_HOLEY_ELEMENTS + 1) <<
6205 Map::ElementsKindBits::kShift) - 1;
6206 static const int8_t kMaximumBitField2FastHoleySmiElementValue =
6207 static_cast<int8_t>((FAST_HOLEY_SMI_ELEMENTS + 1) <<
6208 Map::ElementsKindBits::kShift) - 1;
Steve Blocka7e24c12009-10-30 11:49:00 +00006209
Iain Merrick75681382010-08-19 15:07:18 +01006210 typedef FixedBodyDescriptor<kPointerFieldsBeginOffset,
6211 kPointerFieldsEndOffset,
6212 kSize> BodyDescriptor;
6213
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006214 // Compares this map to another to see if they describe equivalent objects.
6215 // If |mode| is set to CLEAR_INOBJECT_PROPERTIES, |other| is treated as if
6216 // it had exactly zero inobject properties.
6217 // The "shared" flags of both this map and |other| are ignored.
6218 bool EquivalentToForNormalization(Map* other, PropertyNormalizationMode mode);
6219
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006220 // Returns true if given field is unboxed double.
6221 inline bool IsUnboxedDoubleField(FieldIndex index);
6222
6223#if TRACE_MAPS
6224 static void TraceTransition(const char* what, Map* from, Map* to, Name* name);
6225 static void TraceAllTransitions(Map* map);
6226#endif
6227
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006228 static inline Handle<Map> AddMissingTransitionsForTesting(
6229 Handle<Map> split_map, Handle<DescriptorArray> descriptors,
6230 Handle<LayoutDescriptor> full_layout_descriptor);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006231
Steve Blocka7e24c12009-10-30 11:49:00 +00006232 private:
Ben Murdochc5610432016-08-08 18:44:38 +01006233 // Returns the map that this (root) map transitions to if its elements_kind
6234 // is changed to |elements_kind|, or |nullptr| if no such map is cached yet.
6235 Map* LookupElementsTransitionMap(ElementsKind elements_kind);
6236
6237 // Tries to replay property transitions starting from this (root) map using
6238 // the descriptor array of the |map|. The |root_map| is expected to have
6239 // proper elements kind and therefore elements kinds transitions are not
6240 // taken by this function. Returns |nullptr| if matching transition map is
6241 // not found.
6242 Map* TryReplayPropertyTransitions(Map* map);
6243
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006244 static void ConnectTransition(Handle<Map> parent, Handle<Map> child,
6245 Handle<Name> name, SimpleTransitionFlag flag);
6246
6247 bool EquivalentToForTransition(Map* other);
6248 static Handle<Map> RawCopy(Handle<Map> map, int instance_size);
6249 static Handle<Map> ShareDescriptor(Handle<Map> map,
6250 Handle<DescriptorArray> descriptors,
6251 Descriptor* descriptor);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006252 static Handle<Map> AddMissingTransitions(
6253 Handle<Map> map, Handle<DescriptorArray> descriptors,
6254 Handle<LayoutDescriptor> full_layout_descriptor);
6255 static void InstallDescriptors(
6256 Handle<Map> parent_map, Handle<Map> child_map, int new_descriptor,
6257 Handle<DescriptorArray> descriptors,
6258 Handle<LayoutDescriptor> full_layout_descriptor);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006259 static Handle<Map> CopyAddDescriptor(Handle<Map> map,
6260 Descriptor* descriptor,
6261 TransitionFlag flag);
6262 static Handle<Map> CopyReplaceDescriptors(
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006263 Handle<Map> map, Handle<DescriptorArray> descriptors,
6264 Handle<LayoutDescriptor> layout_descriptor, TransitionFlag flag,
6265 MaybeHandle<Name> maybe_name, const char* reason,
6266 SimpleTransitionFlag simple_flag);
6267
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006268 static Handle<Map> CopyReplaceDescriptor(Handle<Map> map,
6269 Handle<DescriptorArray> descriptors,
6270 Descriptor* descriptor,
6271 int index,
6272 TransitionFlag flag);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006273 static MUST_USE_RESULT MaybeHandle<Map> TryReconfigureExistingProperty(
6274 Handle<Map> map, int descriptor, PropertyKind kind,
6275 PropertyAttributes attributes, const char** reason);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006276
6277 static Handle<Map> CopyNormalized(Handle<Map> map,
6278 PropertyNormalizationMode mode);
6279
Ben Murdochc5610432016-08-08 18:44:38 +01006280 static Handle<Map> Reconfigure(Handle<Map> map,
6281 ElementsKind new_elements_kind,
6282 int modify_index, PropertyKind new_kind,
6283 PropertyAttributes new_attributes,
6284 Representation new_representation,
6285 Handle<FieldType> new_field_type,
6286 StoreMode store_mode);
6287
6288 static Handle<Map> CopyGeneralizeAllRepresentations(
6289 Handle<Map> map, ElementsKind elements_kind, int modify_index,
6290 StoreMode store_mode, PropertyKind kind, PropertyAttributes attributes,
6291 const char* reason);
6292
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006293 // Fires when the layout of an object with a leaf map changes.
6294 // This includes adding transitions to the leaf map or changing
6295 // the descriptor array.
6296 inline void NotifyLeafMapLayoutChange();
6297
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006298 void DeprecateTransitionTree();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006299
6300 void ReplaceDescriptors(DescriptorArray* new_descriptors,
6301 LayoutDescriptor* new_layout_descriptor);
6302
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006303
6304 Map* FindLastMatchMap(int verbatim, int length, DescriptorArray* descriptors);
6305
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006306 // Update field type of the given descriptor to new representation and new
6307 // type. The type must be prepared for storing in descriptor array:
6308 // it must be either a simple type or a map wrapped in a weak cell.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006309 void UpdateFieldType(int descriptor_number, Handle<Name> name,
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006310 Representation new_representation,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006311 Handle<Object> new_wrapped_type);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006312
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006313 void PrintReconfiguration(FILE* file, int modify_index, PropertyKind kind,
6314 PropertyAttributes attributes);
Ben Murdoch097c5b22016-05-18 11:27:45 +01006315 void PrintGeneralization(FILE* file, const char* reason, int modify_index,
6316 int split, int descriptors, bool constant_to_field,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006317 Representation old_representation,
6318 Representation new_representation,
Ben Murdoch097c5b22016-05-18 11:27:45 +01006319 MaybeHandle<FieldType> old_field_type,
6320 MaybeHandle<Object> old_value,
6321 MaybeHandle<FieldType> new_field_type,
6322 MaybeHandle<Object> new_value);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006323
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006324 static const int kFastPropertiesSoftLimit = 12;
6325 static const int kMaxFastProperties = 128;
6326
Steve Blocka7e24c12009-10-30 11:49:00 +00006327 DISALLOW_IMPLICIT_CONSTRUCTORS(Map);
6328};
6329
6330
6331// An abstract superclass, a marker class really, for simple structure classes.
Ben Murdoch257744e2011-11-30 15:57:28 +00006332// It doesn't carry much functionality but allows struct classes to be
Steve Blocka7e24c12009-10-30 11:49:00 +00006333// identified in the type system.
6334class Struct: public HeapObject {
6335 public:
6336 inline void InitializeBody(int object_size);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006337 DECLARE_CAST(Struct)
6338};
6339
6340
6341// A simple one-element struct, useful where smis need to be boxed.
6342class Box : public Struct {
6343 public:
6344 // [value]: the boxed contents.
6345 DECL_ACCESSORS(value, Object)
6346
6347 DECLARE_CAST(Box)
6348
6349 // Dispatched behavior.
6350 DECLARE_PRINTER(Box)
6351 DECLARE_VERIFIER(Box)
6352
6353 static const int kValueOffset = HeapObject::kHeaderSize;
6354 static const int kSize = kValueOffset + kPointerSize;
6355
6356 private:
6357 DISALLOW_IMPLICIT_CONSTRUCTORS(Box);
Steve Blocka7e24c12009-10-30 11:49:00 +00006358};
6359
6360
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006361// Container for metadata stored on each prototype map.
6362class PrototypeInfo : public Struct {
6363 public:
6364 static const int UNREGISTERED = -1;
6365
6366 // [prototype_users]: WeakFixedArray containing maps using this prototype,
6367 // or Smi(0) if uninitialized.
6368 DECL_ACCESSORS(prototype_users, Object)
Ben Murdoch61f157c2016-09-16 13:49:30 +01006369
6370 // [object_create_map]: A field caching the map for Object.create(prototype).
6371 static inline void SetObjectCreateMap(Handle<PrototypeInfo> info,
6372 Handle<Map> map);
6373 inline Map* ObjectCreateMap();
6374 inline bool HasObjectCreateMap();
6375
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006376 // [registry_slot]: Slot in prototype's user registry where this user
6377 // is stored. Returns UNREGISTERED if this prototype has not been registered.
6378 inline int registry_slot() const;
6379 inline void set_registry_slot(int slot);
6380 // [validity_cell]: Cell containing the validity bit for prototype chains
6381 // going through this object, or Smi(0) if uninitialized.
6382 // When a prototype object changes its map, then both its own validity cell
6383 // and those of all "downstream" prototypes are invalidated; handlers for a
6384 // given receiver embed the currently valid cell for that receiver's prototype
6385 // during their compilation and check it on execution.
6386 DECL_ACCESSORS(validity_cell, Object)
Ben Murdoch61f157c2016-09-16 13:49:30 +01006387 // [bit_field]
6388 inline int bit_field() const;
6389 inline void set_bit_field(int bit_field);
6390
6391 DECL_BOOLEAN_ACCESSORS(should_be_fast_map)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006392
6393 DECLARE_CAST(PrototypeInfo)
6394
6395 // Dispatched behavior.
6396 DECLARE_PRINTER(PrototypeInfo)
6397 DECLARE_VERIFIER(PrototypeInfo)
6398
6399 static const int kPrototypeUsersOffset = HeapObject::kHeaderSize;
6400 static const int kRegistrySlotOffset = kPrototypeUsersOffset + kPointerSize;
6401 static const int kValidityCellOffset = kRegistrySlotOffset + kPointerSize;
Ben Murdoch61f157c2016-09-16 13:49:30 +01006402 static const int kObjectCreateMap = kValidityCellOffset + kPointerSize;
6403 static const int kBitFieldOffset = kObjectCreateMap + kPointerSize;
6404 static const int kSize = kBitFieldOffset + kPointerSize;
6405
6406 // Bit field usage.
6407 static const int kShouldBeFastBit = 0;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006408
6409 private:
Ben Murdoch61f157c2016-09-16 13:49:30 +01006410 DECL_ACCESSORS(object_create_map, Object)
6411
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006412 DISALLOW_IMPLICIT_CONSTRUCTORS(PrototypeInfo);
6413};
6414
6415
6416// Pair used to store both a ScopeInfo and an extension object in the extension
6417// slot of a block context. Needed in the rare case where a declaration block
6418// scope (a "varblock" as used to desugar parameter destructuring) also contains
6419// a sloppy direct eval. (In no other case both are needed at the same time.)
6420class SloppyBlockWithEvalContextExtension : public Struct {
6421 public:
6422 // [scope_info]: Scope info.
6423 DECL_ACCESSORS(scope_info, ScopeInfo)
6424 // [extension]: Extension object.
6425 DECL_ACCESSORS(extension, JSObject)
6426
6427 DECLARE_CAST(SloppyBlockWithEvalContextExtension)
6428
6429 // Dispatched behavior.
6430 DECLARE_PRINTER(SloppyBlockWithEvalContextExtension)
6431 DECLARE_VERIFIER(SloppyBlockWithEvalContextExtension)
6432
6433 static const int kScopeInfoOffset = HeapObject::kHeaderSize;
6434 static const int kExtensionOffset = kScopeInfoOffset + kPointerSize;
6435 static const int kSize = kExtensionOffset + kPointerSize;
6436
6437 private:
6438 DISALLOW_IMPLICIT_CONSTRUCTORS(SloppyBlockWithEvalContextExtension);
6439};
6440
6441
Steve Blocka7e24c12009-10-30 11:49:00 +00006442// Script describes a script which has been added to the VM.
6443class Script: public Struct {
6444 public:
6445 // Script types.
6446 enum Type {
6447 TYPE_NATIVE = 0,
6448 TYPE_EXTENSION = 1,
6449 TYPE_NORMAL = 2
6450 };
6451
6452 // Script compilation types.
6453 enum CompilationType {
6454 COMPILATION_TYPE_HOST = 0,
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08006455 COMPILATION_TYPE_EVAL = 1
Steve Blocka7e24c12009-10-30 11:49:00 +00006456 };
6457
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006458 // Script compilation state.
6459 enum CompilationState {
6460 COMPILATION_STATE_INITIAL = 0,
6461 COMPILATION_STATE_COMPILED = 1
6462 };
6463
Steve Blocka7e24c12009-10-30 11:49:00 +00006464 // [source]: the script source.
6465 DECL_ACCESSORS(source, Object)
6466
6467 // [name]: the script name.
6468 DECL_ACCESSORS(name, Object)
6469
6470 // [id]: the script id.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006471 DECL_INT_ACCESSORS(id)
Steve Blocka7e24c12009-10-30 11:49:00 +00006472
6473 // [line_offset]: script line offset in resource from where it was extracted.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006474 DECL_INT_ACCESSORS(line_offset)
Steve Blocka7e24c12009-10-30 11:49:00 +00006475
6476 // [column_offset]: script column offset in resource from where it was
6477 // extracted.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006478 DECL_INT_ACCESSORS(column_offset)
Steve Blocka7e24c12009-10-30 11:49:00 +00006479
Steve Blocka7e24c12009-10-30 11:49:00 +00006480 // [context_data]: context data for the context this script was compiled in.
6481 DECL_ACCESSORS(context_data, Object)
6482
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006483 // [wrapper]: the wrapper cache. This is either undefined or a WeakCell.
6484 DECL_ACCESSORS(wrapper, HeapObject)
Steve Blocka7e24c12009-10-30 11:49:00 +00006485
6486 // [type]: the script type.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006487 DECL_INT_ACCESSORS(type)
Steve Blocka7e24c12009-10-30 11:49:00 +00006488
Steve Blockd0582a62009-12-15 09:54:21 +00006489 // [line_ends]: FixedArray of line ends positions.
Steve Blocka7e24c12009-10-30 11:49:00 +00006490 DECL_ACCESSORS(line_ends, Object)
6491
Ben Murdoch097c5b22016-05-18 11:27:45 +01006492 // [eval_from_shared]: for eval scripts the shared function info for the
Steve Blockd0582a62009-12-15 09:54:21 +00006493 // function from which eval was called.
6494 DECL_ACCESSORS(eval_from_shared, Object)
Steve Blocka7e24c12009-10-30 11:49:00 +00006495
Ben Murdochc5610432016-08-08 18:44:38 +01006496 // [eval_from_position]: the source position in the code for the function
6497 // from which eval was called, as positive integer. Or the code offset in the
6498 // code from which eval was called, as negative integer.
6499 DECL_INT_ACCESSORS(eval_from_position)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006500
6501 // [shared_function_infos]: weak fixed array containing all shared
6502 // function infos created from this script.
6503 DECL_ACCESSORS(shared_function_infos, Object)
Steve Blocka7e24c12009-10-30 11:49:00 +00006504
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006505 // [flags]: Holds an exciting bitfield.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006506 DECL_INT_ACCESSORS(flags)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006507
6508 // [source_url]: sourceURL from magic comment
6509 DECL_ACCESSORS(source_url, Object)
6510
6511 // [source_url]: sourceMappingURL magic comment
6512 DECL_ACCESSORS(source_mapping_url, Object)
6513
6514 // [compilation_type]: how the the script was compiled. Encoded in the
6515 // 'flags' field.
6516 inline CompilationType compilation_type();
6517 inline void set_compilation_type(CompilationType type);
6518
6519 // [compilation_state]: determines whether the script has already been
6520 // compiled. Encoded in the 'flags' field.
6521 inline CompilationState compilation_state();
6522 inline void set_compilation_state(CompilationState state);
6523
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006524 // [hide_source]: determines whether the script source can be exposed as
6525 // function source. Encoded in the 'flags' field.
6526 inline bool hide_source();
6527 inline void set_hide_source(bool value);
6528
6529 // [origin_options]: optional attributes set by the embedder via ScriptOrigin,
6530 // and used by the embedder to make decisions about the script. V8 just passes
6531 // this through. Encoded in the 'flags' field.
6532 inline v8::ScriptOriginOptions origin_options();
6533 inline void set_origin_options(ScriptOriginOptions origin_options);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006534
6535 DECLARE_CAST(Script)
Steve Blocka7e24c12009-10-30 11:49:00 +00006536
Steve Block3ce2e202009-11-05 08:53:23 +00006537 // If script source is an external string, check that the underlying
6538 // resource is accessible. Otherwise, always return true.
6539 inline bool HasValidSource();
6540
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006541 static Handle<Object> GetNameOrSourceURL(Handle<Script> script);
6542
Ben Murdochc5610432016-08-08 18:44:38 +01006543 // Set eval origin for stack trace formatting.
6544 static void SetEvalOrigin(Handle<Script> script,
6545 Handle<SharedFunctionInfo> outer,
6546 int eval_position);
6547 // Retrieve source position from where eval was called.
6548 int GetEvalPosition();
6549
Ben Murdoch097c5b22016-05-18 11:27:45 +01006550 // Init line_ends array with source code positions of line ends.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006551 static void InitLineEnds(Handle<Script> script);
6552
Ben Murdoch61f157c2016-09-16 13:49:30 +01006553 // Convert code offset into column number.
6554 static int GetColumnNumber(Handle<Script> script, int code_offset);
6555
6556 // Convert code offset into (zero-based) line number.
6557 // The non-handlified version does not allocate, but may be much slower.
6558 static int GetLineNumber(Handle<Script> script, int code_offset);
6559 int GetLineNumber(int code_pos);
6560
6561 // Carries information about a source position.
6562 struct PositionInfo {
6563 PositionInfo() : line(-1), column(-1), line_start(-1), line_end(-1) {}
6564
6565 int line; // Zero-based line number.
6566 int column; // Zero-based column number.
6567 int line_start; // Position of first character in line.
6568 int line_end; // Position of last (non-linebreak) character in line.
6569 };
6570
6571 // Specifies whether to add offsets to position infos.
6572 enum OffsetFlag { NO_OFFSET = 0, WITH_OFFSET = 1 };
6573
6574 // Retrieves information about the given position, optionally with an offset.
6575 // Returns false on failure, and otherwise writes into the given info object
6576 // on success.
6577 bool GetPositionInfo(int position, PositionInfo* info,
6578 OffsetFlag offset_flag);
6579
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006580 // Get the JS object wrapping the given script; create it if none exists.
6581 static Handle<JSObject> GetWrapper(Handle<Script> script);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006582
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006583 // Look through the list of existing shared function infos to find one
6584 // that matches the function literal. Return empty handle if not found.
6585 MaybeHandle<SharedFunctionInfo> FindSharedFunctionInfo(FunctionLiteral* fun);
6586
6587 // Iterate over all script objects on the heap.
6588 class Iterator {
6589 public:
6590 explicit Iterator(Isolate* isolate);
6591 Script* Next();
6592
6593 private:
6594 WeakFixedArray::Iterator iterator_;
6595 DISALLOW_COPY_AND_ASSIGN(Iterator);
6596 };
6597
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006598 // Dispatched behavior.
6599 DECLARE_PRINTER(Script)
6600 DECLARE_VERIFIER(Script)
Steve Blocka7e24c12009-10-30 11:49:00 +00006601
6602 static const int kSourceOffset = HeapObject::kHeaderSize;
6603 static const int kNameOffset = kSourceOffset + kPointerSize;
6604 static const int kLineOffsetOffset = kNameOffset + kPointerSize;
6605 static const int kColumnOffsetOffset = kLineOffsetOffset + kPointerSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006606 static const int kContextOffset = kColumnOffsetOffset + kPointerSize;
Steve Blocka7e24c12009-10-30 11:49:00 +00006607 static const int kWrapperOffset = kContextOffset + kPointerSize;
6608 static const int kTypeOffset = kWrapperOffset + kPointerSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006609 static const int kLineEndsOffset = kTypeOffset + kPointerSize;
Steve Blocka7e24c12009-10-30 11:49:00 +00006610 static const int kIdOffset = kLineEndsOffset + kPointerSize;
Steve Blockd0582a62009-12-15 09:54:21 +00006611 static const int kEvalFromSharedOffset = kIdOffset + kPointerSize;
Ben Murdochc5610432016-08-08 18:44:38 +01006612 static const int kEvalFromPositionOffset =
Steve Blockd0582a62009-12-15 09:54:21 +00006613 kEvalFromSharedOffset + kPointerSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006614 static const int kSharedFunctionInfosOffset =
Ben Murdochc5610432016-08-08 18:44:38 +01006615 kEvalFromPositionOffset + kPointerSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006616 static const int kFlagsOffset = kSharedFunctionInfosOffset + kPointerSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006617 static const int kSourceUrlOffset = kFlagsOffset + kPointerSize;
6618 static const int kSourceMappingUrlOffset = kSourceUrlOffset + kPointerSize;
6619 static const int kSize = kSourceMappingUrlOffset + kPointerSize;
Steve Blocka7e24c12009-10-30 11:49:00 +00006620
6621 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006622 int GetLineNumberWithArray(int code_pos);
6623
6624 // Bit positions in the flags field.
6625 static const int kCompilationTypeBit = 0;
6626 static const int kCompilationStateBit = 1;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006627 static const int kHideSourceBit = 2;
6628 static const int kOriginOptionsShift = 3;
6629 static const int kOriginOptionsSize = 3;
6630 static const int kOriginOptionsMask = ((1 << kOriginOptionsSize) - 1)
6631 << kOriginOptionsShift;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006632
Steve Blocka7e24c12009-10-30 11:49:00 +00006633 DISALLOW_IMPLICIT_CONSTRUCTORS(Script);
6634};
6635
6636
Ben Murdochb0fe1622011-05-05 13:52:32 +01006637// List of builtin functions we want to identify to improve code
6638// generation.
6639//
6640// Each entry has a name of a global object property holding an object
6641// optionally followed by ".prototype", a name of a builtin function
6642// on the object (the one the id is set for), and a label.
6643//
6644// Installation of ids for the selected builtin functions is handled
6645// by the bootstrapper.
Ben Murdochda12d292016-06-02 14:46:10 +01006646#define FUNCTIONS_WITH_ID_LIST(V) \
6647 V(Array.prototype, indexOf, ArrayIndexOf) \
6648 V(Array.prototype, lastIndexOf, ArrayLastIndexOf) \
6649 V(Array.prototype, push, ArrayPush) \
6650 V(Array.prototype, pop, ArrayPop) \
6651 V(Array.prototype, shift, ArrayShift) \
6652 V(Function.prototype, apply, FunctionApply) \
6653 V(Function.prototype, call, FunctionCall) \
6654 V(Object.prototype, hasOwnProperty, ObjectHasOwnProperty) \
6655 V(String.prototype, charCodeAt, StringCharCodeAt) \
6656 V(String.prototype, charAt, StringCharAt) \
6657 V(String.prototype, concat, StringConcat) \
6658 V(String.prototype, toLowerCase, StringToLowerCase) \
6659 V(String.prototype, toUpperCase, StringToUpperCase) \
6660 V(String, fromCharCode, StringFromCharCode) \
6661 V(Math, random, MathRandom) \
6662 V(Math, floor, MathFloor) \
6663 V(Math, round, MathRound) \
6664 V(Math, ceil, MathCeil) \
6665 V(Math, abs, MathAbs) \
6666 V(Math, log, MathLog) \
Ben Murdoch61f157c2016-09-16 13:49:30 +01006667 V(Math, log1p, MathLog1p) \
6668 V(Math, log2, MathLog2) \
6669 V(Math, log10, MathLog10) \
6670 V(Math, cbrt, MathCbrt) \
Ben Murdochda12d292016-06-02 14:46:10 +01006671 V(Math, exp, MathExp) \
Ben Murdoch61f157c2016-09-16 13:49:30 +01006672 V(Math, expm1, MathExpm1) \
Ben Murdochda12d292016-06-02 14:46:10 +01006673 V(Math, sqrt, MathSqrt) \
6674 V(Math, pow, MathPow) \
6675 V(Math, max, MathMax) \
6676 V(Math, min, MathMin) \
6677 V(Math, cos, MathCos) \
6678 V(Math, sin, MathSin) \
6679 V(Math, tan, MathTan) \
6680 V(Math, acos, MathAcos) \
6681 V(Math, asin, MathAsin) \
6682 V(Math, atan, MathAtan) \
6683 V(Math, atan2, MathAtan2) \
Ben Murdoch61f157c2016-09-16 13:49:30 +01006684 V(Math, atanh, MathAtanh) \
Ben Murdochda12d292016-06-02 14:46:10 +01006685 V(Math, imul, MathImul) \
6686 V(Math, clz32, MathClz32) \
6687 V(Math, fround, MathFround) \
6688 V(Math, trunc, MathTrunc)
Ben Murdochb0fe1622011-05-05 13:52:32 +01006689
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006690#define ATOMIC_FUNCTIONS_WITH_ID_LIST(V) \
6691 V(Atomics, load, AtomicsLoad) \
6692 V(Atomics, store, AtomicsStore)
6693
Ben Murdochb0fe1622011-05-05 13:52:32 +01006694enum BuiltinFunctionId {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006695 kArrayCode,
Ben Murdochb0fe1622011-05-05 13:52:32 +01006696#define DECLARE_FUNCTION_ID(ignored1, ignore2, name) \
6697 k##name,
6698 FUNCTIONS_WITH_ID_LIST(DECLARE_FUNCTION_ID)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006699 ATOMIC_FUNCTIONS_WITH_ID_LIST(DECLARE_FUNCTION_ID)
Ben Murdochb0fe1622011-05-05 13:52:32 +01006700#undef DECLARE_FUNCTION_ID
6701 // Fake id for a special case of Math.pow. Note, it continues the
6702 // list of math functions.
Ben Murdoch61f157c2016-09-16 13:49:30 +01006703 kMathPowHalf,
6704 // These are manually assigned to special getters during bootstrapping.
6705 kDataViewBuffer,
6706 kDataViewByteLength,
6707 kDataViewByteOffset,
6708 kTypedArrayByteLength,
6709 kTypedArrayByteOffset,
6710 kTypedArrayLength,
Ben Murdochb0fe1622011-05-05 13:52:32 +01006711};
6712
6713
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006714// Result of searching in an optimized code map of a SharedFunctionInfo. Note
6715// that both {code} and {literals} can be NULL to pass search result status.
6716struct CodeAndLiterals {
6717 Code* code; // Cached optimized code.
6718 LiteralsArray* literals; // Cached literals array.
6719};
6720
6721
Steve Blocka7e24c12009-10-30 11:49:00 +00006722// SharedFunctionInfo describes the JSFunction information that can be
6723// shared by multiple instances of the function.
6724class SharedFunctionInfo: public HeapObject {
6725 public:
6726 // [name]: Function name.
6727 DECL_ACCESSORS(name, Object)
6728
6729 // [code]: Function code.
6730 DECL_ACCESSORS(code, Code)
Ben Murdoch097c5b22016-05-18 11:27:45 +01006731
Ben Murdochda12d292016-06-02 14:46:10 +01006732 // Get the abstract code associated with the function, which will either be
6733 // a Code object or a BytecodeArray.
6734 inline AbstractCode* abstract_code();
6735
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006736 inline void ReplaceCode(Code* code);
6737
6738 // [optimized_code_map]: Map from native context to optimized code
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006739 // and a shared literals array.
6740 DECL_ACCESSORS(optimized_code_map, FixedArray)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006741
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006742 // Returns entry from optimized code map for specified context and OSR entry.
6743 // Note that {code == nullptr, literals == nullptr} indicates no matching
6744 // entry has been found, whereas {code, literals == nullptr} indicates that
6745 // code is context-independent.
6746 CodeAndLiterals SearchOptimizedCodeMap(Context* native_context,
6747 BailoutId osr_ast_id);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006748
6749 // Clear optimized code map.
6750 void ClearOptimizedCodeMap();
6751
Ben Murdoch61f157c2016-09-16 13:49:30 +01006752 // Like ClearOptimizedCodeMap, but preserves literals.
6753 void ClearCodeFromOptimizedCodeMap();
6754
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006755 // We have a special root FixedArray with the right shape and values
6756 // to represent the cleared optimized code map. This predicate checks
6757 // if that root is installed.
6758 inline bool OptimizedCodeMapIsCleared() const;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006759
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006760 // Removes a specific optimized code object from the optimized code map.
6761 // In case of non-OSR the code reference is cleared from the cache entry but
6762 // the entry itself is left in the map in order to proceed sharing literals.
6763 void EvictFromOptimizedCodeMap(Code* optimized_code, const char* reason);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006764
6765 // Trims the optimized code map after entries have been removed.
6766 void TrimOptimizedCodeMap(int shrink_by);
6767
Ben Murdoch61f157c2016-09-16 13:49:30 +01006768 static Handle<LiteralsArray> FindOrCreateLiterals(
6769 Handle<SharedFunctionInfo> shared, Handle<Context> native_context);
6770
Ben Murdochda12d292016-06-02 14:46:10 +01006771 // Add or update entry in the optimized code map for context-independent code.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006772 static void AddSharedCodeToOptimizedCodeMap(Handle<SharedFunctionInfo> shared,
6773 Handle<Code> code);
6774
Ben Murdochda12d292016-06-02 14:46:10 +01006775 // Add or update entry in the optimized code map for context-dependent code.
6776 // If {code} is not given, then an existing entry's code won't be overwritten.
6777 static void AddToOptimizedCodeMap(Handle<SharedFunctionInfo> shared,
6778 Handle<Context> native_context,
6779 MaybeHandle<Code> code,
6780 Handle<LiteralsArray> literals,
6781 BailoutId osr_ast_id);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006782
6783 // Set up the link between shared function info and the script. The shared
6784 // function info is added to the list on the script.
6785 static void SetScript(Handle<SharedFunctionInfo> shared,
6786 Handle<Object> script_object);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006787
6788 // Layout description of the optimized code map.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006789 static const int kSharedCodeIndex = 0;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006790 static const int kEntriesStart = 1;
6791 static const int kContextOffset = 0;
6792 static const int kCachedCodeOffset = 1;
6793 static const int kLiteralsOffset = 2;
6794 static const int kOsrAstIdOffset = 3;
6795 static const int kEntryLength = 4;
6796 static const int kInitialLength = kEntriesStart + kEntryLength;
Steve Blocka7e24c12009-10-30 11:49:00 +00006797
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006798 static const int kNotFound = -1;
6799
Ben Murdochc5610432016-08-08 18:44:38 +01006800 // Helpers for assembly code that does a backwards walk of the optimized code
6801 // map.
6802 static const int kOffsetToPreviousContext =
6803 FixedArray::kHeaderSize + kPointerSize * (kContextOffset - kEntryLength);
6804 static const int kOffsetToPreviousCachedCode =
6805 FixedArray::kHeaderSize +
6806 kPointerSize * (kCachedCodeOffset - kEntryLength);
6807 static const int kOffsetToPreviousLiterals =
6808 FixedArray::kHeaderSize + kPointerSize * (kLiteralsOffset - kEntryLength);
6809 static const int kOffsetToPreviousOsrAstId =
6810 FixedArray::kHeaderSize + kPointerSize * (kOsrAstIdOffset - kEntryLength);
6811
Ben Murdoch3bec4d22010-07-22 14:51:16 +01006812 // [scope_info]: Scope info.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006813 DECL_ACCESSORS(scope_info, ScopeInfo)
Ben Murdoch3bec4d22010-07-22 14:51:16 +01006814
Steve Blocka7e24c12009-10-30 11:49:00 +00006815 // [construct stub]: Code stub for constructing instances of this function.
6816 DECL_ACCESSORS(construct_stub, Code)
6817
6818 // Returns if this function has been compiled to native code yet.
6819 inline bool is_compiled();
6820
6821 // [length]: The function length - usually the number of declared parameters.
6822 // Use up to 2^30 parameters.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006823 inline int length() const;
Steve Blocka7e24c12009-10-30 11:49:00 +00006824 inline void set_length(int value);
6825
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006826 // [internal formal parameter count]: The declared number of parameters.
6827 // For subclass constructors, also includes new.target.
6828 // The size of function's frame is internal_formal_parameter_count + 1.
6829 inline int internal_formal_parameter_count() const;
6830 inline void set_internal_formal_parameter_count(int value);
Steve Blocka7e24c12009-10-30 11:49:00 +00006831
6832 // Set the formal parameter count so the function code will be
6833 // called without using argument adaptor frames.
6834 inline void DontAdaptArguments();
6835
6836 // [expected_nof_properties]: Expected number of properties for the function.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006837 inline int expected_nof_properties() const;
Steve Blocka7e24c12009-10-30 11:49:00 +00006838 inline void set_expected_nof_properties(int value);
6839
Ben Murdoch61f157c2016-09-16 13:49:30 +01006840 // [feedback_metadata] - describes ast node feedback from full-codegen and
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006841 // (increasingly) from crankshafted code where sufficient feedback isn't
6842 // available.
Ben Murdoch61f157c2016-09-16 13:49:30 +01006843 DECL_ACCESSORS(feedback_metadata, TypeFeedbackMetadata)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006844
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006845#if TRACE_MAPS
6846 // [unique_id] - For --trace-maps purposes, an identifier that's persistent
6847 // even if the GC moves this SharedFunctionInfo.
6848 inline int unique_id() const;
6849 inline void set_unique_id(int value);
6850#endif
6851
Steve Blocka7e24c12009-10-30 11:49:00 +00006852 // [instance class name]: class name for instances.
6853 DECL_ACCESSORS(instance_class_name, Object)
6854
Steve Block6ded16b2010-05-10 14:33:55 +01006855 // [function data]: This field holds some additional data for function.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006856 // Currently it has one of:
6857 // - a FunctionTemplateInfo to make benefit the API [IsApiFunction()].
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006858 // - a BytecodeArray for the interpreter [HasBytecodeArray()].
Steve Blocka7e24c12009-10-30 11:49:00 +00006859 DECL_ACCESSORS(function_data, Object)
6860
Steve Block6ded16b2010-05-10 14:33:55 +01006861 inline bool IsApiFunction();
6862 inline FunctionTemplateInfo* get_api_func_data();
Ben Murdochda12d292016-06-02 14:46:10 +01006863 inline void set_api_func_data(FunctionTemplateInfo* data);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006864 inline bool HasBytecodeArray();
6865 inline BytecodeArray* bytecode_array();
Ben Murdochda12d292016-06-02 14:46:10 +01006866 inline void set_bytecode_array(BytecodeArray* bytecode);
6867 inline void ClearBytecodeArray();
6868
6869 // [function identifier]: This field holds an additional identifier for the
6870 // function.
6871 // - a Smi identifying a builtin function [HasBuiltinFunctionId()].
6872 // - a String identifying the function's inferred name [HasInferredName()].
6873 // The inferred_name is inferred from variable or property
6874 // assignment of this function. It is used to facilitate debugging and
6875 // profiling of JavaScript code written in OO style, where almost
6876 // all functions are anonymous but are assigned to object
6877 // properties.
6878 DECL_ACCESSORS(function_identifier, Object)
6879
6880 inline bool HasBuiltinFunctionId();
6881 inline BuiltinFunctionId builtin_function_id();
6882 inline void set_builtin_function_id(BuiltinFunctionId id);
6883 inline bool HasInferredName();
6884 inline String* inferred_name();
6885 inline void set_inferred_name(String* inferred_name);
Steve Block6ded16b2010-05-10 14:33:55 +01006886
Steve Blocka7e24c12009-10-30 11:49:00 +00006887 // [script info]: Script from which the function originates.
6888 DECL_ACCESSORS(script, Object)
6889
Steve Block6ded16b2010-05-10 14:33:55 +01006890 // [num_literals]: Number of literals used by this function.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006891 inline int num_literals() const;
Steve Block6ded16b2010-05-10 14:33:55 +01006892 inline void set_num_literals(int value);
6893
Steve Blocka7e24c12009-10-30 11:49:00 +00006894 // [start_position_and_type]: Field used to store both the source code
6895 // position, whether or not the function is a function expression,
6896 // and whether or not the function is a toplevel function. The two
6897 // least significants bit indicates whether the function is an
6898 // expression and the rest contains the source code position.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006899 inline int start_position_and_type() const;
Steve Blocka7e24c12009-10-30 11:49:00 +00006900 inline void set_start_position_and_type(int value);
6901
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006902 // The function is subject to debugging if a debug info is attached.
6903 inline bool HasDebugInfo();
6904 inline DebugInfo* GetDebugInfo();
6905
6906 // A function has debug code if the compiled code has debug break slots.
6907 inline bool HasDebugCode();
6908
Steve Blocka7e24c12009-10-30 11:49:00 +00006909 // [debug info]: Debug information.
6910 DECL_ACCESSORS(debug_info, Object)
6911
Ben Murdochf87a2032010-10-22 12:50:53 +01006912 // The function's name if it is non-empty, otherwise the inferred name.
6913 String* DebugName();
6914
Ben Murdochda12d292016-06-02 14:46:10 +01006915 // Used for flags such as --hydrogen-filter.
6916 bool PassesFilter(const char* raw_filter);
6917
Steve Blocka7e24c12009-10-30 11:49:00 +00006918 // Position of the 'function' token in the script source.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006919 inline int function_token_position() const;
Steve Blocka7e24c12009-10-30 11:49:00 +00006920 inline void set_function_token_position(int function_token_position);
6921
6922 // Position of this function in the script source.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006923 inline int start_position() const;
Steve Blocka7e24c12009-10-30 11:49:00 +00006924 inline void set_start_position(int start_position);
6925
6926 // End position of this function in the script source.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006927 inline int end_position() const;
Steve Blocka7e24c12009-10-30 11:49:00 +00006928 inline void set_end_position(int end_position);
6929
Ben Murdoch097c5b22016-05-18 11:27:45 +01006930 // Is this function a named function expression in the source code.
6931 DECL_BOOLEAN_ACCESSORS(is_named_expression)
Steve Blocka7e24c12009-10-30 11:49:00 +00006932
6933 // Is this function a top-level function (scripts, evals).
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00006934 DECL_BOOLEAN_ACCESSORS(is_toplevel)
Steve Blocka7e24c12009-10-30 11:49:00 +00006935
6936 // Bit field containing various information collected by the compiler to
6937 // drive optimization.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006938 inline int compiler_hints() const;
Steve Blocka7e24c12009-10-30 11:49:00 +00006939 inline void set_compiler_hints(int value);
6940
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006941 inline int ast_node_count() const;
Ben Murdoch8f9999f2012-04-23 10:39:17 +01006942 inline void set_ast_node_count(int count);
6943
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006944 inline int profiler_ticks() const;
6945 inline void set_profiler_ticks(int ticks);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006946
Ben Murdoch8f9999f2012-04-23 10:39:17 +01006947 // Inline cache age is used to infer whether the function survived a context
6948 // disposal or not. In the former case we reset the opt_count.
6949 inline int ic_age();
6950 inline void set_ic_age(int age);
Ben Murdochb0fe1622011-05-05 13:52:32 +01006951
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01006952 // Indicates if this function can be lazy compiled.
6953 // This is used to determine if we can safely flush code from a function
6954 // when doing GC if we expect that the function will no longer be used.
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00006955 DECL_BOOLEAN_ACCESSORS(allows_lazy_compilation)
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01006956
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006957 // Indicates if this function can be lazy compiled without a context.
6958 // This is used to determine if we can force compilation without reaching
6959 // the function through program execution but through other means (e.g. heap
6960 // iteration by the debugger).
6961 DECL_BOOLEAN_ACCESSORS(allows_lazy_compilation_without_context)
Iain Merrick75681382010-08-19 15:07:18 +01006962
Ben Murdochb0fe1622011-05-05 13:52:32 +01006963 // Indicates whether optimizations have been disabled for this
6964 // shared function info. If a function is repeatedly optimized or if
6965 // we cannot optimize the function we disable optimization to avoid
6966 // spending time attempting to optimize it again.
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00006967 DECL_BOOLEAN_ACCESSORS(optimization_disabled)
Ben Murdochb0fe1622011-05-05 13:52:32 +01006968
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006969 // Indicates the language mode.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006970 inline LanguageMode language_mode();
6971 inline void set_language_mode(LanguageMode language_mode);
Steve Block1e0659c2011-05-24 12:43:12 +01006972
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00006973 // False if the function definitely does not allocate an arguments object.
6974 DECL_BOOLEAN_ACCESSORS(uses_arguments)
6975
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006976 // Indicates that this function uses a super property (or an eval that may
6977 // use a super property).
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006978 // This is needed to set up the [[HomeObject]] on the function instance.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006979 DECL_BOOLEAN_ACCESSORS(needs_home_object)
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006980
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00006981 // True if the function has any duplicated parameter names.
6982 DECL_BOOLEAN_ACCESSORS(has_duplicate_parameters)
6983
6984 // Indicates whether the function is a native function.
Ben Murdoch589d6972011-11-30 16:04:58 +00006985 // These needs special treatment in .call and .apply since
Ben Murdoch257744e2011-11-30 15:57:28 +00006986 // null passed as the receiver should not be translated to the
6987 // global object.
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00006988 DECL_BOOLEAN_ACCESSORS(native)
6989
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006990 // Indicate that this function should always be inlined in optimized code.
6991 DECL_BOOLEAN_ACCESSORS(force_inline)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006992
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00006993 // Indicates that the function was created by the Function function.
6994 // Though it's anonymous, toString should treat it as if it had the name
6995 // "anonymous". We don't set the name itself so that the system does not
6996 // see a binding for it.
6997 DECL_BOOLEAN_ACCESSORS(name_should_print_as_anonymous)
6998
Ben Murdoch097c5b22016-05-18 11:27:45 +01006999 // Indicates that the function is either an anonymous expression
7000 // or an arrow function (the name field can be set through the API,
7001 // which does not change this flag).
7002 DECL_BOOLEAN_ACCESSORS(is_anonymous_expression)
Ben Murdoch257744e2011-11-30 15:57:28 +00007003
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007004 // Is this a function or top-level/eval code.
7005 DECL_BOOLEAN_ACCESSORS(is_function)
7006
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007007 // Indicates that code for this function cannot be compiled with Crankshaft.
7008 DECL_BOOLEAN_ACCESSORS(dont_crankshaft)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007009
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007010 // Indicates that code for this function cannot be flushed.
7011 DECL_BOOLEAN_ACCESSORS(dont_flush)
7012
7013 // Indicates that this function is a generator.
7014 DECL_BOOLEAN_ACCESSORS(is_generator)
7015
Ben Murdochc5610432016-08-08 18:44:38 +01007016 // Indicates that this function is an async function.
7017 DECL_BOOLEAN_ACCESSORS(is_async)
7018
7019 // Indicates that this function can be suspended, either via YieldExpressions
7020 // or AwaitExpressions.
7021 inline bool is_resumable() const;
7022
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007023 // Indicates that this function is an arrow function.
7024 DECL_BOOLEAN_ACCESSORS(is_arrow)
7025
7026 // Indicates that this function is a concise method.
7027 DECL_BOOLEAN_ACCESSORS(is_concise_method)
7028
Ben Murdoch097c5b22016-05-18 11:27:45 +01007029 // Indicates that this function is a getter.
7030 DECL_BOOLEAN_ACCESSORS(is_getter_function)
7031
7032 // Indicates that this function is a setter.
7033 DECL_BOOLEAN_ACCESSORS(is_setter_function)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007034
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007035 // Indicates that this function is a default constructor.
7036 DECL_BOOLEAN_ACCESSORS(is_default_constructor)
7037
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007038 // Indicates that this function is an asm function.
7039 DECL_BOOLEAN_ACCESSORS(asm_function)
7040
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007041 // Indicates that the the shared function info is deserialized from cache.
7042 DECL_BOOLEAN_ACCESSORS(deserialized)
7043
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007044 // Indicates that the the shared function info has never been compiled before.
7045 DECL_BOOLEAN_ACCESSORS(never_compiled)
7046
Ben Murdoch097c5b22016-05-18 11:27:45 +01007047 // Whether this function was created from a FunctionDeclaration.
7048 DECL_BOOLEAN_ACCESSORS(is_declaration)
7049
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007050 inline FunctionKind kind();
7051 inline void set_kind(FunctionKind kind);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007052
Ben Murdochb0fe1622011-05-05 13:52:32 +01007053 // Indicates whether or not the code in the shared function support
7054 // deoptimization.
7055 inline bool has_deoptimization_support();
7056
7057 // Enable deoptimization support through recompiled code.
7058 void EnableDeoptimizationSupport(Code* recompiled);
7059
Ben Murdoch257744e2011-11-30 15:57:28 +00007060 // Disable (further) attempted optimization of all functions sharing this
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007061 // shared function info.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007062 void DisableOptimization(BailoutReason reason);
Ben Murdoch257744e2011-11-30 15:57:28 +00007063
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007064 inline BailoutReason disable_optimization_reason();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007065
7066 // Lookup the bailout ID and DCHECK that it exists in the non-optimized
Ben Murdochb0fe1622011-05-05 13:52:32 +01007067 // code, returns whether it asserted (i.e., always true if assertions are
7068 // disabled).
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007069 bool VerifyBailoutId(BailoutId id);
Steve Blocka7e24c12009-10-30 11:49:00 +00007070
7071 // [source code]: Source code for the function.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007072 bool HasSourceCode() const;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007073 Handle<Object> GetSourceCode();
Steve Blocka7e24c12009-10-30 11:49:00 +00007074
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007075 // Number of times the function was optimized.
Ben Murdochb0fe1622011-05-05 13:52:32 +01007076 inline int opt_count();
7077 inline void set_opt_count(int opt_count);
7078
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007079 // Number of times the function was deoptimized.
7080 inline void set_deopt_count(int value);
7081 inline int deopt_count();
7082 inline void increment_deopt_count();
7083
7084 // Number of time we tried to re-enable optimization after it
7085 // was disabled due to high number of deoptimizations.
7086 inline void set_opt_reenable_tries(int value);
7087 inline int opt_reenable_tries();
7088
7089 inline void TryReenableOptimization();
7090
7091 // Stores deopt_count, opt_reenable_tries and ic_age as bit-fields.
7092 inline void set_counters(int value);
7093 inline int counters() const;
7094
7095 // Stores opt_count and bailout_reason as bit-fields.
7096 inline void set_opt_count_and_bailout_reason(int value);
7097 inline int opt_count_and_bailout_reason() const;
7098
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007099 inline void set_disable_optimization_reason(BailoutReason reason);
7100
7101 // Tells whether this function should be subject to debugging.
7102 inline bool IsSubjectToDebugging();
7103
7104 // Whether this function is defined in native code or extensions.
7105 inline bool IsBuiltin();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007106
7107 // Check whether or not this function is inlineable.
7108 bool IsInlineable();
7109
Ben Murdochb0fe1622011-05-05 13:52:32 +01007110 // Source size of this function.
7111 int SourceSize();
7112
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007113 // Returns `false` if formal parameters include rest parameters, optional
7114 // parameters, or destructuring parameters.
7115 // TODO(caitp): make this a flag set during parsing
7116 inline bool has_simple_parameters();
Steve Blocka7e24c12009-10-30 11:49:00 +00007117
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007118 // Initialize a SharedFunctionInfo from a parsed function literal.
7119 static void InitFromFunctionLiteral(Handle<SharedFunctionInfo> shared_info,
7120 FunctionLiteral* lit);
Steve Blocka7e24c12009-10-30 11:49:00 +00007121
7122 // Dispatched behavior.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007123 DECLARE_PRINTER(SharedFunctionInfo)
7124 DECLARE_VERIFIER(SharedFunctionInfo)
Steve Blocka7e24c12009-10-30 11:49:00 +00007125
Ben Murdoch8f9999f2012-04-23 10:39:17 +01007126 void ResetForNewContext(int new_ic_age);
7127
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007128 // Iterate over all shared function infos.
7129 class Iterator {
7130 public:
7131 explicit Iterator(Isolate* isolate);
7132 SharedFunctionInfo* Next();
7133
7134 private:
7135 bool NextScript();
7136
7137 Script::Iterator script_iterator_;
7138 WeakFixedArray::Iterator sfi_iterator_;
7139 DisallowHeapAllocation no_gc_;
7140 DISALLOW_COPY_AND_ASSIGN(Iterator);
7141 };
7142
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007143 DECLARE_CAST(SharedFunctionInfo)
Steve Blocka7e24c12009-10-30 11:49:00 +00007144
7145 // Constants.
7146 static const int kDontAdaptArgumentsSentinel = -1;
7147
7148 // Layout description.
Steve Block6ded16b2010-05-10 14:33:55 +01007149 // Pointer fields.
Steve Blocka7e24c12009-10-30 11:49:00 +00007150 static const int kNameOffset = HeapObject::kHeaderSize;
7151 static const int kCodeOffset = kNameOffset + kPointerSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007152 static const int kOptimizedCodeMapOffset = kCodeOffset + kPointerSize;
7153 static const int kScopeInfoOffset = kOptimizedCodeMapOffset + kPointerSize;
Ben Murdoch3bec4d22010-07-22 14:51:16 +01007154 static const int kConstructStubOffset = kScopeInfoOffset + kPointerSize;
Steve Block6ded16b2010-05-10 14:33:55 +01007155 static const int kInstanceClassNameOffset =
7156 kConstructStubOffset + kPointerSize;
7157 static const int kFunctionDataOffset =
7158 kInstanceClassNameOffset + kPointerSize;
7159 static const int kScriptOffset = kFunctionDataOffset + kPointerSize;
7160 static const int kDebugInfoOffset = kScriptOffset + kPointerSize;
Ben Murdochda12d292016-06-02 14:46:10 +01007161 static const int kFunctionIdentifierOffset = kDebugInfoOffset + kPointerSize;
Ben Murdoch61f157c2016-09-16 13:49:30 +01007162 static const int kFeedbackMetadataOffset =
Ben Murdochda12d292016-06-02 14:46:10 +01007163 kFunctionIdentifierOffset + kPointerSize;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007164#if TRACE_MAPS
Ben Murdoch61f157c2016-09-16 13:49:30 +01007165 static const int kUniqueIdOffset = kFeedbackMetadataOffset + kPointerSize;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007166 static const int kLastPointerFieldOffset = kUniqueIdOffset;
7167#else
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007168 // Just to not break the postmortrem support with conditional offsets
Ben Murdoch61f157c2016-09-16 13:49:30 +01007169 static const int kUniqueIdOffset = kFeedbackMetadataOffset;
7170 static const int kLastPointerFieldOffset = kFeedbackMetadataOffset;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007171#endif
7172
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01007173#if V8_HOST_ARCH_32_BIT
7174 // Smi fields.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007175 static const int kLengthOffset = kLastPointerFieldOffset + kPointerSize;
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01007176 static const int kFormalParameterCountOffset = kLengthOffset + kPointerSize;
7177 static const int kExpectedNofPropertiesOffset =
7178 kFormalParameterCountOffset + kPointerSize;
7179 static const int kNumLiteralsOffset =
7180 kExpectedNofPropertiesOffset + kPointerSize;
7181 static const int kStartPositionAndTypeOffset =
7182 kNumLiteralsOffset + kPointerSize;
7183 static const int kEndPositionOffset =
7184 kStartPositionAndTypeOffset + kPointerSize;
7185 static const int kFunctionTokenPositionOffset =
7186 kEndPositionOffset + kPointerSize;
7187 static const int kCompilerHintsOffset =
7188 kFunctionTokenPositionOffset + kPointerSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007189 static const int kOptCountAndBailoutReasonOffset =
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01007190 kCompilerHintsOffset + kPointerSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007191 static const int kCountersOffset =
7192 kOptCountAndBailoutReasonOffset + kPointerSize;
7193 static const int kAstNodeCountOffset =
7194 kCountersOffset + kPointerSize;
7195 static const int kProfilerTicksOffset =
7196 kAstNodeCountOffset + kPointerSize;
Ben Murdoch8f9999f2012-04-23 10:39:17 +01007197
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01007198 // Total size.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007199 static const int kSize = kProfilerTicksOffset + kPointerSize;
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01007200#else
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007201// The only reason to use smi fields instead of int fields is to allow
7202// iteration without maps decoding during garbage collections.
7203// To avoid wasting space on 64-bit architectures we use the following trick:
7204// we group integer fields into pairs
7205// The least significant integer in each pair is shifted left by 1. By doing
7206// this we guarantee that LSB of each kPointerSize aligned word is not set and
7207// thus this word cannot be treated as pointer to HeapObject during old space
7208// traversal.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007209#if V8_TARGET_LITTLE_ENDIAN
7210 static const int kLengthOffset = kLastPointerFieldOffset + kPointerSize;
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01007211 static const int kFormalParameterCountOffset =
7212 kLengthOffset + kIntSize;
7213
Steve Blocka7e24c12009-10-30 11:49:00 +00007214 static const int kExpectedNofPropertiesOffset =
7215 kFormalParameterCountOffset + kIntSize;
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01007216 static const int kNumLiteralsOffset =
7217 kExpectedNofPropertiesOffset + kIntSize;
7218
7219 static const int kEndPositionOffset =
Steve Block6ded16b2010-05-10 14:33:55 +01007220 kNumLiteralsOffset + kIntSize;
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01007221 static const int kStartPositionAndTypeOffset =
7222 kEndPositionOffset + kIntSize;
7223
7224 static const int kFunctionTokenPositionOffset =
7225 kStartPositionAndTypeOffset + kIntSize;
Steve Block6ded16b2010-05-10 14:33:55 +01007226 static const int kCompilerHintsOffset =
Steve Blocka7e24c12009-10-30 11:49:00 +00007227 kFunctionTokenPositionOffset + kIntSize;
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01007228
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007229 static const int kOptCountAndBailoutReasonOffset =
Steve Block6ded16b2010-05-10 14:33:55 +01007230 kCompilerHintsOffset + kIntSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007231 static const int kCountersOffset =
7232 kOptCountAndBailoutReasonOffset + kIntSize;
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01007233
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007234 static const int kAstNodeCountOffset =
7235 kCountersOffset + kIntSize;
7236 static const int kProfilerTicksOffset =
7237 kAstNodeCountOffset + kIntSize;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007238
Steve Block6ded16b2010-05-10 14:33:55 +01007239 // Total size.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007240 static const int kSize = kProfilerTicksOffset + kIntSize;
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01007241
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007242#elif V8_TARGET_BIG_ENDIAN
7243 static const int kFormalParameterCountOffset =
7244 kLastPointerFieldOffset + kPointerSize;
7245 static const int kLengthOffset = kFormalParameterCountOffset + kIntSize;
7246
7247 static const int kNumLiteralsOffset = kLengthOffset + kIntSize;
7248 static const int kExpectedNofPropertiesOffset = kNumLiteralsOffset + kIntSize;
7249
7250 static const int kStartPositionAndTypeOffset =
7251 kExpectedNofPropertiesOffset + kIntSize;
7252 static const int kEndPositionOffset = kStartPositionAndTypeOffset + kIntSize;
7253
7254 static const int kCompilerHintsOffset = kEndPositionOffset + kIntSize;
7255 static const int kFunctionTokenPositionOffset =
7256 kCompilerHintsOffset + kIntSize;
7257
7258 static const int kCountersOffset = kFunctionTokenPositionOffset + kIntSize;
7259 static const int kOptCountAndBailoutReasonOffset = kCountersOffset + kIntSize;
7260
7261 static const int kProfilerTicksOffset =
7262 kOptCountAndBailoutReasonOffset + kIntSize;
7263 static const int kAstNodeCountOffset = kProfilerTicksOffset + kIntSize;
7264
7265 // Total size.
7266 static const int kSize = kAstNodeCountOffset + kIntSize;
7267
7268#else
7269#error Unknown byte ordering
7270#endif // Big endian
7271#endif // 64-bit
7272
Kristian Monsen0d5e1162010-09-30 15:31:59 +01007273
Steve Block6ded16b2010-05-10 14:33:55 +01007274 static const int kAlignedSize = POINTER_SIZE_ALIGN(kSize);
Steve Blocka7e24c12009-10-30 11:49:00 +00007275
Iain Merrick75681382010-08-19 15:07:18 +01007276 typedef FixedBodyDescriptor<kNameOffset,
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007277 kLastPointerFieldOffset + kPointerSize,
Iain Merrick75681382010-08-19 15:07:18 +01007278 kSize> BodyDescriptor;
7279
Steve Blocka7e24c12009-10-30 11:49:00 +00007280 // Bit positions in start_position_and_type.
7281 // The source code start position is in the 30 most significant bits of
7282 // the start_position_and_type field.
Ben Murdoch097c5b22016-05-18 11:27:45 +01007283 static const int kIsNamedExpressionBit = 0;
7284 static const int kIsTopLevelBit = 1;
Steve Blocka7e24c12009-10-30 11:49:00 +00007285 static const int kStartPositionShift = 2;
Ben Murdoch097c5b22016-05-18 11:27:45 +01007286 static const int kStartPositionMask = ~((1 << kStartPositionShift) - 1);
Steve Blocka7e24c12009-10-30 11:49:00 +00007287
7288 // Bit positions in compiler_hints.
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00007289 enum CompilerHints {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007290 // byte 0
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00007291 kAllowLazyCompilation,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007292 kAllowLazyCompilationWithoutContext,
7293 kOptimizationDisabled,
Ben Murdochda12d292016-06-02 14:46:10 +01007294 kNeverCompiled,
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00007295 kNative,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007296 kStrictModeFunction,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007297 kUsesArguments,
7298 kNeedsHomeObject,
7299 // byte 1
7300 kHasDuplicateParameters,
7301 kForceInline,
7302 kIsAsmFunction,
Ben Murdoch097c5b22016-05-18 11:27:45 +01007303 kIsAnonymousExpression,
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00007304 kNameShouldPrintAsAnonymous,
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007305 kIsFunction,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007306 kDontCrankshaft,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007307 kDontFlush,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007308 // byte 2
7309 kFunctionKind,
7310 kIsArrow = kFunctionKind,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007311 kIsGenerator,
7312 kIsConciseMethod,
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007313 kIsDefaultConstructor,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007314 kIsSubclassConstructor,
7315 kIsBaseConstructor,
Ben Murdoch097c5b22016-05-18 11:27:45 +01007316 kIsGetterFunction,
7317 kIsSetterFunction,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007318 // byte 3
Ben Murdochc5610432016-08-08 18:44:38 +01007319 kIsAsyncFunction,
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007320 kDeserialized,
Ben Murdoch097c5b22016-05-18 11:27:45 +01007321 kIsDeclaration,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007322 kCompilerHintsCount, // Pseudo entry
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00007323 };
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007324 // Add hints for other modes when they're added.
7325 STATIC_ASSERT(LANGUAGE_END == 3);
7326 // kFunctionKind has to be byte-aligned
7327 STATIC_ASSERT((kFunctionKind % kBitsPerByte) == 0);
7328// Make sure that FunctionKind and byte 2 are in sync:
7329#define ASSERT_FUNCTION_KIND_ORDER(functionKind, compilerFunctionKind) \
7330 STATIC_ASSERT(FunctionKind::functionKind == \
7331 1 << (compilerFunctionKind - kFunctionKind))
7332 ASSERT_FUNCTION_KIND_ORDER(kArrowFunction, kIsArrow);
7333 ASSERT_FUNCTION_KIND_ORDER(kGeneratorFunction, kIsGenerator);
7334 ASSERT_FUNCTION_KIND_ORDER(kConciseMethod, kIsConciseMethod);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007335 ASSERT_FUNCTION_KIND_ORDER(kDefaultConstructor, kIsDefaultConstructor);
7336 ASSERT_FUNCTION_KIND_ORDER(kSubclassConstructor, kIsSubclassConstructor);
7337 ASSERT_FUNCTION_KIND_ORDER(kBaseConstructor, kIsBaseConstructor);
Ben Murdoch097c5b22016-05-18 11:27:45 +01007338 ASSERT_FUNCTION_KIND_ORDER(kGetterFunction, kIsGetterFunction);
7339 ASSERT_FUNCTION_KIND_ORDER(kSetterFunction, kIsSetterFunction);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007340#undef ASSERT_FUNCTION_KIND_ORDER
Steve Blocka7e24c12009-10-30 11:49:00 +00007341
Ben Murdochc5610432016-08-08 18:44:38 +01007342 class FunctionKindBits : public BitField<FunctionKind, kIsArrow, 9> {};
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007343
7344 class DeoptCountBits : public BitField<int, 0, 4> {};
7345 class OptReenableTriesBits : public BitField<int, 4, 18> {};
7346 class ICAgeBits : public BitField<int, 22, 8> {};
7347
7348 class OptCountBits : public BitField<int, 0, 22> {};
7349 class DisabledOptimizationReasonBits : public BitField<int, 22, 8> {};
7350
Ben Murdoche0cee9b2011-05-25 10:26:03 +01007351 private:
7352#if V8_HOST_ARCH_32_BIT
7353 // On 32 bit platforms, compiler hints is a smi.
7354 static const int kCompilerHintsSmiTagSize = kSmiTagSize;
7355 static const int kCompilerHintsSize = kPointerSize;
7356#else
7357 // On 64 bit platforms, compiler hints is not a smi, see comment above.
7358 static const int kCompilerHintsSmiTagSize = 0;
7359 static const int kCompilerHintsSize = kIntSize;
7360#endif
7361
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00007362 STATIC_ASSERT(SharedFunctionInfo::kCompilerHintsCount <=
7363 SharedFunctionInfo::kCompilerHintsSize * kBitsPerByte);
7364
Ben Murdoche0cee9b2011-05-25 10:26:03 +01007365 public:
Ben Murdoch257744e2011-11-30 15:57:28 +00007366 // Constants for optimizing codegen for strict mode function and
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007367 // native tests when using integer-width instructions.
7368 static const int kStrictModeBit =
7369 kStrictModeFunction + kCompilerHintsSmiTagSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007370 static const int kNativeBit = kNative + kCompilerHintsSmiTagSize;
Ben Murdochc5610432016-08-08 18:44:38 +01007371 static const int kHasDuplicateParametersBit =
7372 kHasDuplicateParameters + kCompilerHintsSmiTagSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007373
7374 static const int kClassConstructorBits =
7375 FunctionKind::kClassConstructor
7376 << (kFunctionKind + kCompilerHintsSmiTagSize);
7377
7378 // Constants for optimizing codegen for strict mode function and
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00007379 // native tests.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007380 // Allows to use byte-width instructions.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007381 static const int kStrictModeBitWithinByte = kStrictModeBit % kBitsPerByte;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007382 static const int kNativeBitWithinByte = kNativeBit % kBitsPerByte;
Ben Murdochc5610432016-08-08 18:44:38 +01007383 static const int kHasDuplicateParametersBitWithinByte =
7384 kHasDuplicateParametersBit % kBitsPerByte;
Ben Murdoche0cee9b2011-05-25 10:26:03 +01007385
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007386 static const int kClassConstructorBitsWithinByte =
7387 FunctionKind::kClassConstructor << kCompilerHintsSmiTagSize;
7388 STATIC_ASSERT(kClassConstructorBitsWithinByte < (1 << kBitsPerByte));
Ben Murdoch257744e2011-11-30 15:57:28 +00007389
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007390#if defined(V8_TARGET_LITTLE_ENDIAN)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007391#define BYTE_OFFSET(compiler_hint) \
7392 kCompilerHintsOffset + \
7393 (compiler_hint + kCompilerHintsSmiTagSize) / kBitsPerByte
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007394#elif defined(V8_TARGET_BIG_ENDIAN)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007395#define BYTE_OFFSET(compiler_hint) \
7396 kCompilerHintsOffset + (kCompilerHintsSize - 1) - \
7397 ((compiler_hint + kCompilerHintsSmiTagSize) / kBitsPerByte)
Ben Murdoche0cee9b2011-05-25 10:26:03 +01007398#else
7399#error Unknown byte ordering
7400#endif
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007401 static const int kStrictModeByteOffset = BYTE_OFFSET(kStrictModeFunction);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007402 static const int kNativeByteOffset = BYTE_OFFSET(kNative);
7403 static const int kFunctionKindByteOffset = BYTE_OFFSET(kFunctionKind);
Ben Murdochc5610432016-08-08 18:44:38 +01007404 static const int kHasDuplicateParametersByteOffset =
7405 BYTE_OFFSET(kHasDuplicateParameters);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007406#undef BYTE_OFFSET
Ben Murdoche0cee9b2011-05-25 10:26:03 +01007407
7408 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007409 // Returns entry from optimized code map for specified context and OSR entry.
7410 // The result is either kNotFound, kSharedCodeIndex for context-independent
7411 // entry or a start index of the context-dependent entry.
7412 int SearchOptimizedCodeMapEntry(Context* native_context,
7413 BailoutId osr_ast_id);
7414
Steve Blocka7e24c12009-10-30 11:49:00 +00007415 DISALLOW_IMPLICIT_CONSTRUCTORS(SharedFunctionInfo);
7416};
7417
7418
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007419// Printing support.
7420struct SourceCodeOf {
7421 explicit SourceCodeOf(SharedFunctionInfo* v, int max = -1)
7422 : value(v), max_length(max) {}
7423 const SharedFunctionInfo* value;
7424 int max_length;
7425};
7426
7427
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007428std::ostream& operator<<(std::ostream& os, const SourceCodeOf& v);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007429
7430
7431class JSGeneratorObject: public JSObject {
7432 public:
7433 // [function]: The function corresponding to this generator object.
7434 DECL_ACCESSORS(function, JSFunction)
7435
7436 // [context]: The context of the suspended computation.
7437 DECL_ACCESSORS(context, Context)
7438
7439 // [receiver]: The receiver of the suspended computation.
7440 DECL_ACCESSORS(receiver, Object)
7441
Ben Murdoch61f157c2016-09-16 13:49:30 +01007442 // [input_or_debug_pos]
7443 // For executing generators: the most recent input value.
7444 // For suspended new-style generators: debug information (bytecode offset).
7445 // For suspended old-style generators: unused.
7446 // There is currently no need to remember the most recent input value for a
7447 // suspended generator.
7448 DECL_ACCESSORS(input_or_debug_pos, Object)
Ben Murdoch097c5b22016-05-18 11:27:45 +01007449
Ben Murdochc5610432016-08-08 18:44:38 +01007450 // [resume_mode]: The most recent resume mode.
7451 enum ResumeMode { kNext, kReturn, kThrow };
7452 DECL_INT_ACCESSORS(resume_mode)
7453
Ben Murdoch61f157c2016-09-16 13:49:30 +01007454 // [continuation]
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007455 //
Ben Murdoch61f157c2016-09-16 13:49:30 +01007456 // A positive value indicates a suspended generator. The special
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007457 // kGeneratorExecuting and kGeneratorClosed values indicate that a generator
7458 // cannot be resumed.
7459 inline int continuation() const;
7460 inline void set_continuation(int continuation);
Ben Murdoch61f157c2016-09-16 13:49:30 +01007461 inline bool is_closed() const;
7462 inline bool is_executing() const;
7463 inline bool is_suspended() const;
7464
7465 // For suspended generators: the source position at which the generator
7466 // is suspended.
7467 int source_position() const;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007468
7469 // [operand_stack]: Saved operand stack.
7470 DECL_ACCESSORS(operand_stack, FixedArray)
7471
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007472 DECLARE_CAST(JSGeneratorObject)
7473
7474 // Dispatched behavior.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007475 DECLARE_VERIFIER(JSGeneratorObject)
7476
7477 // Magic sentinel values for the continuation.
Ben Murdochc5610432016-08-08 18:44:38 +01007478 static const int kGeneratorExecuting = -2;
7479 static const int kGeneratorClosed = -1;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007480
7481 // Layout description.
7482 static const int kFunctionOffset = JSObject::kHeaderSize;
7483 static const int kContextOffset = kFunctionOffset + kPointerSize;
7484 static const int kReceiverOffset = kContextOffset + kPointerSize;
Ben Murdoch61f157c2016-09-16 13:49:30 +01007485 static const int kInputOrDebugPosOffset = kReceiverOffset + kPointerSize;
7486 static const int kResumeModeOffset = kInputOrDebugPosOffset + kPointerSize;
Ben Murdochc5610432016-08-08 18:44:38 +01007487 static const int kContinuationOffset = kResumeModeOffset + kPointerSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007488 static const int kOperandStackOffset = kContinuationOffset + kPointerSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007489 static const int kSize = kOperandStackOffset + kPointerSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007490
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007491 private:
7492 DISALLOW_IMPLICIT_CONSTRUCTORS(JSGeneratorObject);
7493};
7494
7495
7496// Representation for module instance objects.
7497class JSModule: public JSObject {
7498 public:
7499 // [context]: the context holding the module's locals, or undefined if none.
7500 DECL_ACCESSORS(context, Object)
7501
7502 // [scope_info]: Scope info.
7503 DECL_ACCESSORS(scope_info, ScopeInfo)
7504
7505 DECLARE_CAST(JSModule)
7506
7507 // Dispatched behavior.
7508 DECLARE_PRINTER(JSModule)
7509 DECLARE_VERIFIER(JSModule)
7510
7511 // Layout description.
7512 static const int kContextOffset = JSObject::kHeaderSize;
7513 static const int kScopeInfoOffset = kContextOffset + kPointerSize;
7514 static const int kSize = kScopeInfoOffset + kPointerSize;
7515
7516 private:
7517 DISALLOW_IMPLICIT_CONSTRUCTORS(JSModule);
7518};
7519
7520
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007521// JSBoundFunction describes a bound function exotic object.
7522class JSBoundFunction : public JSObject {
7523 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007524 // [bound_target_function]: The wrapped function object.
7525 DECL_ACCESSORS(bound_target_function, JSReceiver)
7526
7527 // [bound_this]: The value that is always passed as the this value when
7528 // calling the wrapped function.
7529 DECL_ACCESSORS(bound_this, Object)
7530
7531 // [bound_arguments]: A list of values whose elements are used as the first
7532 // arguments to any call to the wrapped function.
7533 DECL_ACCESSORS(bound_arguments, FixedArray)
7534
Ben Murdochc5610432016-08-08 18:44:38 +01007535 static MaybeHandle<String> GetName(Isolate* isolate,
7536 Handle<JSBoundFunction> function);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007537 static MaybeHandle<Context> GetFunctionRealm(
7538 Handle<JSBoundFunction> function);
7539
7540 DECLARE_CAST(JSBoundFunction)
7541
7542 // Dispatched behavior.
7543 DECLARE_PRINTER(JSBoundFunction)
7544 DECLARE_VERIFIER(JSBoundFunction)
7545
7546 // The bound function's string representation implemented according
7547 // to ES6 section 19.2.3.5 Function.prototype.toString ( ).
7548 static Handle<String> ToString(Handle<JSBoundFunction> function);
7549
7550 // Layout description.
7551 static const int kBoundTargetFunctionOffset = JSObject::kHeaderSize;
7552 static const int kBoundThisOffset = kBoundTargetFunctionOffset + kPointerSize;
7553 static const int kBoundArgumentsOffset = kBoundThisOffset + kPointerSize;
Ben Murdochc5610432016-08-08 18:44:38 +01007554 static const int kSize = kBoundArgumentsOffset + kPointerSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007555
7556 private:
7557 DISALLOW_IMPLICIT_CONSTRUCTORS(JSBoundFunction);
7558};
7559
7560
Steve Blocka7e24c12009-10-30 11:49:00 +00007561// JSFunction describes JavaScript functions.
7562class JSFunction: public JSObject {
7563 public:
7564 // [prototype_or_initial_map]:
7565 DECL_ACCESSORS(prototype_or_initial_map, Object)
7566
Ben Murdoch589d6972011-11-30 16:04:58 +00007567 // [shared]: The information about the function that
Steve Blocka7e24c12009-10-30 11:49:00 +00007568 // can be shared by instances.
7569 DECL_ACCESSORS(shared, SharedFunctionInfo)
7570
Ben Murdoch61f157c2016-09-16 13:49:30 +01007571 static const int kLengthDescriptorIndex = 0;
7572 static const int kNameDescriptorIndex = 1;
7573
Steve Blocka7e24c12009-10-30 11:49:00 +00007574 // [context]: The context for this function.
7575 inline Context* context();
Steve Blocka7e24c12009-10-30 11:49:00 +00007576 inline void set_context(Object* context);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007577 inline JSObject* global_proxy();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007578 inline Context* native_context();
7579
Ben Murdochc5610432016-08-08 18:44:38 +01007580 static Handle<Object> GetName(Isolate* isolate, Handle<JSFunction> function);
7581 static MaybeHandle<Smi> GetLength(Isolate* isolate,
7582 Handle<JSFunction> function);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007583 static Handle<Context> GetFunctionRealm(Handle<JSFunction> function);
Steve Blocka7e24c12009-10-30 11:49:00 +00007584
7585 // [code]: The generated code object for this function. Executed
7586 // when the function is invoked, e.g. foo() or new foo(). See
7587 // [[Call]] and [[Construct]] description in ECMA-262, section
7588 // 8.6.2, page 27.
7589 inline Code* code();
Ben Murdochb0fe1622011-05-05 13:52:32 +01007590 inline void set_code(Code* code);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007591 inline void set_code_no_write_barrier(Code* code);
Ben Murdochb0fe1622011-05-05 13:52:32 +01007592 inline void ReplaceCode(Code* code);
Steve Blocka7e24c12009-10-30 11:49:00 +00007593
Ben Murdochda12d292016-06-02 14:46:10 +01007594 // Get the abstract code associated with the function, which will either be
7595 // a Code object or a BytecodeArray.
7596 inline AbstractCode* abstract_code();
7597
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007598 // Tells whether this function inlines the given shared function info.
7599 bool Inlines(SharedFunctionInfo* candidate);
Ben Murdochb0fe1622011-05-05 13:52:32 +01007600
7601 // Tells whether or not this function has been optimized.
7602 inline bool IsOptimized();
7603
Ben Murdochc5610432016-08-08 18:44:38 +01007604 // Mark this function for lazy recompilation. The function will be recompiled
7605 // the next time it is executed.
7606 void MarkForBaseline();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007607 void MarkForOptimization();
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007608 void AttemptConcurrentOptimization();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007609
Ben Murdochc5610432016-08-08 18:44:38 +01007610 // Tells whether or not the function is already marked for lazy recompilation.
7611 inline bool IsMarkedForBaseline();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007612 inline bool IsMarkedForOptimization();
7613 inline bool IsMarkedForConcurrentOptimization();
Ben Murdochb0fe1622011-05-05 13:52:32 +01007614
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007615 // Tells whether or not the function is on the concurrent recompilation queue.
7616 inline bool IsInOptimizationQueue();
7617
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007618 // Completes inobject slack tracking on initial map if it is active.
7619 inline void CompleteInobjectSlackTrackingIfActive();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007620
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007621 // [literals]: Fixed array holding the materialized literals.
Steve Blocka7e24c12009-10-30 11:49:00 +00007622 //
7623 // If the function contains object, regexp or array literals, the
7624 // literals array prefix contains the object, regexp, and array
7625 // function to be used when creating these literals. This is
7626 // necessary so that we do not dynamically lookup the object, regexp
7627 // or array functions. Performing a dynamic lookup, we might end up
7628 // using the functions from a new context that we should not have
7629 // access to.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007630 DECL_ACCESSORS(literals, LiteralsArray)
Steve Blocka7e24c12009-10-30 11:49:00 +00007631
Ben Murdoch61f157c2016-09-16 13:49:30 +01007632 static void EnsureLiterals(Handle<JSFunction> function);
7633 inline TypeFeedbackVector* feedback_vector();
7634
7635 // Unconditionally clear the type feedback vector (including vector ICs).
7636 void ClearTypeFeedbackInfo();
7637
7638 // Clear the type feedback vector with a more subtle policy at GC time.
7639 void ClearTypeFeedbackInfoAtGCTime();
7640
Steve Blocka7e24c12009-10-30 11:49:00 +00007641 // The initial map for an object created by this constructor.
7642 inline Map* initial_map();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007643 static void SetInitialMap(Handle<JSFunction> function, Handle<Map> map,
7644 Handle<Object> prototype);
Steve Blocka7e24c12009-10-30 11:49:00 +00007645 inline bool has_initial_map();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007646 static void EnsureHasInitialMap(Handle<JSFunction> function);
Steve Blocka7e24c12009-10-30 11:49:00 +00007647
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007648 // Creates a map that matches the constructor's initial map, but with
7649 // [[prototype]] being new.target.prototype. Because new.target can be a
7650 // JSProxy, this can call back into JavaScript.
7651 static MUST_USE_RESULT MaybeHandle<Map> GetDerivedMap(
7652 Isolate* isolate, Handle<JSFunction> constructor,
7653 Handle<JSReceiver> new_target);
7654
Steve Blocka7e24c12009-10-30 11:49:00 +00007655 // Get and set the prototype property on a JSFunction. If the
7656 // function has an initial map the prototype is set on the initial
7657 // map. Otherwise, the prototype is put in the initial map field
7658 // until an initial map is needed.
7659 inline bool has_prototype();
7660 inline bool has_instance_prototype();
7661 inline Object* prototype();
7662 inline Object* instance_prototype();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007663 static void SetPrototype(Handle<JSFunction> function,
7664 Handle<Object> value);
7665 static void SetInstancePrototype(Handle<JSFunction> function,
7666 Handle<Object> value);
7667
Steve Block6ded16b2010-05-10 14:33:55 +01007668 // After prototype is removed, it will not be created when accessed, and
7669 // [[Construct]] from this function will not be allowed.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007670 bool RemovePrototype();
Steve Blocka7e24c12009-10-30 11:49:00 +00007671
7672 // Returns if this function has been compiled to native code yet.
7673 inline bool is_compiled();
7674
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007675 // [next_function_link]: Links functions into various lists, e.g. the list
7676 // of optimized functions hanging off the native_context. The CodeFlusher
7677 // uses this link to chain together flushing candidates. Treated weakly
7678 // by the garbage collector.
Ben Murdochb0fe1622011-05-05 13:52:32 +01007679 DECL_ACCESSORS(next_function_link, Object)
7680
7681 // Prints the name of the function using PrintF.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007682 void PrintName(FILE* out = stdout);
Ben Murdochb0fe1622011-05-05 13:52:32 +01007683
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007684 DECLARE_CAST(JSFunction)
Steve Blocka7e24c12009-10-30 11:49:00 +00007685
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007686 // Calculate the instance size and in-object properties count.
7687 void CalculateInstanceSize(InstanceType instance_type,
7688 int requested_internal_fields, int* instance_size,
7689 int* in_object_properties);
7690 void CalculateInstanceSizeForDerivedClass(InstanceType instance_type,
7691 int requested_internal_fields,
7692 int* instance_size,
7693 int* in_object_properties);
Ben Murdochda12d292016-06-02 14:46:10 +01007694 static void CalculateInstanceSizeHelper(InstanceType instance_type,
7695 int requested_internal_fields,
7696 int requested_in_object_properties,
7697 int* instance_size,
7698 int* in_object_properties);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007699 // Visiting policy flags define whether the code entry or next function
7700 // should be visited or not.
7701 enum BodyVisitingPolicy {
7702 kVisitCodeEntry = 1 << 0,
7703 kVisitNextFunction = 1 << 1,
7704
7705 kSkipCodeEntryAndNextFunction = 0,
7706 kVisitCodeEntryAndNextFunction = kVisitCodeEntry | kVisitNextFunction
7707 };
7708 // Iterates the function object according to the visiting policy.
7709 template <BodyVisitingPolicy>
7710 class BodyDescriptorImpl;
7711
7712 // Visit the whole object.
7713 typedef BodyDescriptorImpl<kVisitCodeEntryAndNextFunction> BodyDescriptor;
7714
7715 // Don't visit next function.
7716 typedef BodyDescriptorImpl<kVisitCodeEntry> BodyDescriptorStrongCode;
7717 typedef BodyDescriptorImpl<kSkipCodeEntryAndNextFunction>
7718 BodyDescriptorWeakCode;
Steve Block791712a2010-08-27 10:21:07 +01007719
Steve Blocka7e24c12009-10-30 11:49:00 +00007720 // Dispatched behavior.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007721 DECLARE_PRINTER(JSFunction)
7722 DECLARE_VERIFIER(JSFunction)
Steve Blocka7e24c12009-10-30 11:49:00 +00007723
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007724 // The function's name if it is configured, otherwise shared function info
7725 // debug name.
7726 static Handle<String> GetName(Handle<JSFunction> function);
7727
Ben Murdoch097c5b22016-05-18 11:27:45 +01007728 // ES6 section 9.2.11 SetFunctionName
7729 // Because of the way this abstract operation is used in the spec,
7730 // it should never fail.
7731 static void SetName(Handle<JSFunction> function, Handle<Name> name,
7732 Handle<String> prefix);
7733
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007734 // The function's displayName if it is set, otherwise name if it is
7735 // configured, otherwise shared function info
7736 // debug name.
7737 static Handle<String> GetDebugName(Handle<JSFunction> function);
7738
7739 // The function's string representation implemented according to
7740 // ES6 section 19.2.3.5 Function.prototype.toString ( ).
7741 static Handle<String> ToString(Handle<JSFunction> function);
7742
Ben Murdochb0fe1622011-05-05 13:52:32 +01007743 // Layout descriptors. The last property (from kNonWeakFieldsEndOffset to
7744 // kSize) is weak and has special handling during garbage collection.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007745 static const int kPrototypeOrInitialMapOffset = JSObject::kHeaderSize;
Steve Blocka7e24c12009-10-30 11:49:00 +00007746 static const int kSharedFunctionInfoOffset =
7747 kPrototypeOrInitialMapOffset + kPointerSize;
7748 static const int kContextOffset = kSharedFunctionInfoOffset + kPointerSize;
7749 static const int kLiteralsOffset = kContextOffset + kPointerSize;
Ben Murdochb0fe1622011-05-05 13:52:32 +01007750 static const int kNonWeakFieldsEndOffset = kLiteralsOffset + kPointerSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007751 static const int kCodeEntryOffset = kNonWeakFieldsEndOffset;
7752 static const int kNextFunctionLinkOffset = kCodeEntryOffset + kPointerSize;
Ben Murdochb0fe1622011-05-05 13:52:32 +01007753 static const int kSize = kNextFunctionLinkOffset + kPointerSize;
Steve Blocka7e24c12009-10-30 11:49:00 +00007754
Steve Blocka7e24c12009-10-30 11:49:00 +00007755 private:
7756 DISALLOW_IMPLICIT_CONSTRUCTORS(JSFunction);
7757};
7758
7759
7760// JSGlobalProxy's prototype must be a JSGlobalObject or null,
7761// and the prototype is hidden. JSGlobalProxy always delegates
7762// property accesses to its prototype if the prototype is not null.
7763//
7764// A JSGlobalProxy can be reinitialized which will preserve its identity.
7765//
7766// Accessing a JSGlobalProxy requires security check.
7767
7768class JSGlobalProxy : public JSObject {
7769 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007770 // [native_context]: the owner native context of this global proxy object.
Steve Blocka7e24c12009-10-30 11:49:00 +00007771 // It is null value if this object is not used by any context.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007772 DECL_ACCESSORS(native_context, Object)
Steve Blocka7e24c12009-10-30 11:49:00 +00007773
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007774 // [hash]: The hash code property (undefined if not initialized yet).
7775 DECL_ACCESSORS(hash, Object)
7776
7777 DECLARE_CAST(JSGlobalProxy)
7778
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007779 inline bool IsDetachedFrom(JSGlobalObject* global) const;
Steve Blocka7e24c12009-10-30 11:49:00 +00007780
7781 // Dispatched behavior.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007782 DECLARE_PRINTER(JSGlobalProxy)
7783 DECLARE_VERIFIER(JSGlobalProxy)
Steve Blocka7e24c12009-10-30 11:49:00 +00007784
7785 // Layout description.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007786 static const int kNativeContextOffset = JSObject::kHeaderSize;
7787 static const int kHashOffset = kNativeContextOffset + kPointerSize;
7788 static const int kSize = kHashOffset + kPointerSize;
Steve Blocka7e24c12009-10-30 11:49:00 +00007789
7790 private:
Steve Blocka7e24c12009-10-30 11:49:00 +00007791 DISALLOW_IMPLICIT_CONSTRUCTORS(JSGlobalProxy);
7792};
7793
7794
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007795// JavaScript global object.
7796class JSGlobalObject : public JSObject {
Steve Blocka7e24c12009-10-30 11:49:00 +00007797 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007798 // [native context]: the natives corresponding to this global object.
7799 DECL_ACCESSORS(native_context, Context)
7800
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007801 // [global proxy]: the global proxy object of the context
7802 DECL_ACCESSORS(global_proxy, JSObject)
Steve Blocka7e24c12009-10-30 11:49:00 +00007803
Steve Blocka7e24c12009-10-30 11:49:00 +00007804
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007805 static void InvalidatePropertyCell(Handle<JSGlobalObject> object,
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007806 Handle<Name> name);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007807 // Ensure that the global object has a cell for the given property name.
7808 static Handle<PropertyCell> EnsurePropertyCell(Handle<JSGlobalObject> global,
7809 Handle<Name> name);
7810
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007811 DECLARE_CAST(JSGlobalObject)
7812
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007813 inline bool IsDetached();
Steve Blocka7e24c12009-10-30 11:49:00 +00007814
7815 // Dispatched behavior.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007816 DECLARE_PRINTER(JSGlobalObject)
7817 DECLARE_VERIFIER(JSGlobalObject)
Steve Blocka7e24c12009-10-30 11:49:00 +00007818
7819 // Layout description.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007820 static const int kNativeContextOffset = JSObject::kHeaderSize;
7821 static const int kGlobalProxyOffset = kNativeContextOffset + kPointerSize;
7822 static const int kHeaderSize = kGlobalProxyOffset + kPointerSize;
7823 static const int kSize = kHeaderSize;
Steve Blocka7e24c12009-10-30 11:49:00 +00007824
7825 private:
7826 DISALLOW_IMPLICIT_CONSTRUCTORS(JSGlobalObject);
7827};
7828
7829
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007830// Representation for JS Wrapper objects, String, Number, Boolean, etc.
Steve Blocka7e24c12009-10-30 11:49:00 +00007831class JSValue: public JSObject {
7832 public:
7833 // [value]: the object being wrapped.
7834 DECL_ACCESSORS(value, Object)
7835
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007836 DECLARE_CAST(JSValue)
Steve Blocka7e24c12009-10-30 11:49:00 +00007837
7838 // Dispatched behavior.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007839 DECLARE_PRINTER(JSValue)
7840 DECLARE_VERIFIER(JSValue)
Steve Blocka7e24c12009-10-30 11:49:00 +00007841
7842 // Layout description.
7843 static const int kValueOffset = JSObject::kHeaderSize;
7844 static const int kSize = kValueOffset + kPointerSize;
7845
7846 private:
7847 DISALLOW_IMPLICIT_CONSTRUCTORS(JSValue);
7848};
7849
Steve Block1e0659c2011-05-24 12:43:12 +01007850
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007851class DateCache;
7852
7853// Representation for JS date objects.
7854class JSDate: public JSObject {
7855 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007856 static MUST_USE_RESULT MaybeHandle<JSDate> New(Handle<JSFunction> constructor,
7857 Handle<JSReceiver> new_target,
7858 double tv);
7859
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007860 // If one component is NaN, all of them are, indicating a NaN time value.
7861 // [value]: the time value.
7862 DECL_ACCESSORS(value, Object)
7863 // [year]: caches year. Either undefined, smi, or NaN.
7864 DECL_ACCESSORS(year, Object)
7865 // [month]: caches month. Either undefined, smi, or NaN.
7866 DECL_ACCESSORS(month, Object)
7867 // [day]: caches day. Either undefined, smi, or NaN.
7868 DECL_ACCESSORS(day, Object)
7869 // [weekday]: caches day of week. Either undefined, smi, or NaN.
7870 DECL_ACCESSORS(weekday, Object)
7871 // [hour]: caches hours. Either undefined, smi, or NaN.
7872 DECL_ACCESSORS(hour, Object)
7873 // [min]: caches minutes. Either undefined, smi, or NaN.
7874 DECL_ACCESSORS(min, Object)
7875 // [sec]: caches seconds. Either undefined, smi, or NaN.
7876 DECL_ACCESSORS(sec, Object)
7877 // [cache stamp]: sample of the date cache stamp at the
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007878 // moment when chached fields were cached.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007879 DECL_ACCESSORS(cache_stamp, Object)
7880
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007881 DECLARE_CAST(JSDate)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007882
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007883 // Returns the time value (UTC) identifying the current time.
7884 static double CurrentTimeValue(Isolate* isolate);
7885
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007886 // Returns the date field with the specified index.
7887 // See FieldIndex for the list of date fields.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007888 static Object* GetField(Object* date, Smi* index);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007889
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007890 static Handle<Object> SetValue(Handle<JSDate> date, double v);
7891
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007892 void SetValue(Object* value, bool is_value_nan);
7893
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007894 // ES6 section 20.3.4.45 Date.prototype [ @@toPrimitive ]
7895 static MUST_USE_RESULT MaybeHandle<Object> ToPrimitive(
7896 Handle<JSReceiver> receiver, Handle<Object> hint);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007897
7898 // Dispatched behavior.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007899 DECLARE_PRINTER(JSDate)
7900 DECLARE_VERIFIER(JSDate)
7901
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007902 // The order is important. It must be kept in sync with date macros
7903 // in macros.py.
7904 enum FieldIndex {
7905 kDateValue,
7906 kYear,
7907 kMonth,
7908 kDay,
7909 kWeekday,
7910 kHour,
7911 kMinute,
7912 kSecond,
7913 kFirstUncachedField,
7914 kMillisecond = kFirstUncachedField,
7915 kDays,
7916 kTimeInDay,
7917 kFirstUTCField,
7918 kYearUTC = kFirstUTCField,
7919 kMonthUTC,
7920 kDayUTC,
7921 kWeekdayUTC,
7922 kHourUTC,
7923 kMinuteUTC,
7924 kSecondUTC,
7925 kMillisecondUTC,
7926 kDaysUTC,
7927 kTimeInDayUTC,
7928 kTimezoneOffset
7929 };
7930
7931 // Layout description.
7932 static const int kValueOffset = JSObject::kHeaderSize;
7933 static const int kYearOffset = kValueOffset + kPointerSize;
7934 static const int kMonthOffset = kYearOffset + kPointerSize;
7935 static const int kDayOffset = kMonthOffset + kPointerSize;
7936 static const int kWeekdayOffset = kDayOffset + kPointerSize;
7937 static const int kHourOffset = kWeekdayOffset + kPointerSize;
7938 static const int kMinOffset = kHourOffset + kPointerSize;
7939 static const int kSecOffset = kMinOffset + kPointerSize;
7940 static const int kCacheStampOffset = kSecOffset + kPointerSize;
7941 static const int kSize = kCacheStampOffset + kPointerSize;
7942
7943 private:
7944 inline Object* DoGetField(FieldIndex index);
7945
7946 Object* GetUTCField(FieldIndex index, double value, DateCache* date_cache);
7947
7948 // Computes and caches the cacheable fields of the date.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007949 inline void SetCachedFields(int64_t local_time_ms, DateCache* date_cache);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007950
7951
7952 DISALLOW_IMPLICIT_CONSTRUCTORS(JSDate);
7953};
7954
7955
Steve Block1e0659c2011-05-24 12:43:12 +01007956// Representation of message objects used for error reporting through
7957// the API. The messages are formatted in JavaScript so this object is
7958// a real JavaScript object. The information used for formatting the
7959// error messages are not directly accessible from JavaScript to
7960// prevent leaking information to user code called during error
7961// formatting.
7962class JSMessageObject: public JSObject {
7963 public:
7964 // [type]: the type of error message.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007965 inline int type() const;
7966 inline void set_type(int value);
Steve Block1e0659c2011-05-24 12:43:12 +01007967
7968 // [arguments]: the arguments for formatting the error message.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007969 DECL_ACCESSORS(argument, Object)
Steve Block1e0659c2011-05-24 12:43:12 +01007970
7971 // [script]: the script from which the error message originated.
7972 DECL_ACCESSORS(script, Object)
7973
Steve Block1e0659c2011-05-24 12:43:12 +01007974 // [stack_frames]: an array of stack frames for this error object.
7975 DECL_ACCESSORS(stack_frames, Object)
7976
7977 // [start_position]: the start position in the script for the error message.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007978 inline int start_position() const;
Steve Block1e0659c2011-05-24 12:43:12 +01007979 inline void set_start_position(int value);
7980
7981 // [end_position]: the end position in the script for the error message.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007982 inline int end_position() const;
Steve Block1e0659c2011-05-24 12:43:12 +01007983 inline void set_end_position(int value);
7984
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007985 DECLARE_CAST(JSMessageObject)
Steve Block1e0659c2011-05-24 12:43:12 +01007986
7987 // Dispatched behavior.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007988 DECLARE_PRINTER(JSMessageObject)
7989 DECLARE_VERIFIER(JSMessageObject)
Steve Block1e0659c2011-05-24 12:43:12 +01007990
7991 // Layout description.
7992 static const int kTypeOffset = JSObject::kHeaderSize;
7993 static const int kArgumentsOffset = kTypeOffset + kPointerSize;
7994 static const int kScriptOffset = kArgumentsOffset + kPointerSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007995 static const int kStackFramesOffset = kScriptOffset + kPointerSize;
Steve Block1e0659c2011-05-24 12:43:12 +01007996 static const int kStartPositionOffset = kStackFramesOffset + kPointerSize;
7997 static const int kEndPositionOffset = kStartPositionOffset + kPointerSize;
7998 static const int kSize = kEndPositionOffset + kPointerSize;
7999
8000 typedef FixedBodyDescriptor<HeapObject::kMapOffset,
8001 kStackFramesOffset + kPointerSize,
8002 kSize> BodyDescriptor;
8003};
8004
8005
Steve Blocka7e24c12009-10-30 11:49:00 +00008006// Regular expressions
8007// The regular expression holds a single reference to a FixedArray in
8008// the kDataOffset field.
8009// The FixedArray contains the following data:
8010// - tag : type of regexp implementation (not compiled yet, atom or irregexp)
8011// - reference to the original source string
8012// - reference to the original flag string
8013// If it is an atom regexp
8014// - a reference to a literal string to search for
8015// If it is an irregexp regexp:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008016// - a reference to code for Latin1 inputs (bytecode or compiled), or a smi
Ben Murdoch257744e2011-11-30 15:57:28 +00008017// used for tracking the last usage (used for code flushing).
8018// - a reference to code for UC16 inputs (bytecode or compiled), or a smi
8019// used for tracking the last usage (used for code flushing)..
Steve Blocka7e24c12009-10-30 11:49:00 +00008020// - max number of registers used by irregexp implementations.
8021// - number of capture registers (output values) of the regexp.
8022class JSRegExp: public JSObject {
8023 public:
8024 // Meaning of Type:
8025 // NOT_COMPILED: Initial value. No data has been stored in the JSRegExp yet.
8026 // ATOM: A simple string to match against using an indexOf operation.
8027 // IRREGEXP: Compiled with Irregexp.
Steve Blocka7e24c12009-10-30 11:49:00 +00008028 enum Type { NOT_COMPILED, ATOM, IRREGEXP };
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008029 enum Flag {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008030 kNone = 0,
8031 kGlobal = 1 << 0,
8032 kIgnoreCase = 1 << 1,
8033 kMultiline = 1 << 2,
8034 kSticky = 1 << 3,
8035 kUnicode = 1 << 4,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008036 };
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008037 typedef base::Flags<Flag> Flags;
Steve Blocka7e24c12009-10-30 11:49:00 +00008038
8039 DECL_ACCESSORS(data, Object)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008040 DECL_ACCESSORS(flags, Object)
8041 DECL_ACCESSORS(source, Object)
8042
8043 static MaybeHandle<JSRegExp> New(Handle<String> source, Flags flags);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008044 static Handle<JSRegExp> Copy(Handle<JSRegExp> regexp);
8045
8046 static MaybeHandle<JSRegExp> Initialize(Handle<JSRegExp> regexp,
8047 Handle<String> source, Flags flags);
8048 static MaybeHandle<JSRegExp> Initialize(Handle<JSRegExp> regexp,
8049 Handle<String> source,
8050 Handle<String> flags_string);
Steve Blocka7e24c12009-10-30 11:49:00 +00008051
8052 inline Type TypeTag();
8053 inline int CaptureCount();
8054 inline Flags GetFlags();
8055 inline String* Pattern();
8056 inline Object* DataAt(int index);
8057 // Set implementation data after the object has been prepared.
8058 inline void SetDataAt(int index, Object* value);
Ben Murdoch257744e2011-11-30 15:57:28 +00008059
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008060 static int code_index(bool is_latin1) {
8061 if (is_latin1) {
8062 return kIrregexpLatin1CodeIndex;
Steve Blocka7e24c12009-10-30 11:49:00 +00008063 } else {
8064 return kIrregexpUC16CodeIndex;
8065 }
8066 }
8067
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008068 static int saved_code_index(bool is_latin1) {
8069 if (is_latin1) {
8070 return kIrregexpLatin1CodeSavedIndex;
Ben Murdoch257744e2011-11-30 15:57:28 +00008071 } else {
8072 return kIrregexpUC16CodeSavedIndex;
8073 }
8074 }
8075
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008076 DECLARE_CAST(JSRegExp)
Steve Blocka7e24c12009-10-30 11:49:00 +00008077
8078 // Dispatched behavior.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008079 DECLARE_PRINTER(JSRegExp)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008080 DECLARE_VERIFIER(JSRegExp)
Steve Blocka7e24c12009-10-30 11:49:00 +00008081
8082 static const int kDataOffset = JSObject::kHeaderSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008083 static const int kSourceOffset = kDataOffset + kPointerSize;
8084 static const int kFlagsOffset = kSourceOffset + kPointerSize;
8085 static const int kSize = kFlagsOffset + kPointerSize;
Steve Blocka7e24c12009-10-30 11:49:00 +00008086
8087 // Indices in the data array.
8088 static const int kTagIndex = 0;
8089 static const int kSourceIndex = kTagIndex + 1;
8090 static const int kFlagsIndex = kSourceIndex + 1;
8091 static const int kDataIndex = kFlagsIndex + 1;
8092 // The data fields are used in different ways depending on the
8093 // value of the tag.
8094 // Atom regexps (literal strings).
8095 static const int kAtomPatternIndex = kDataIndex;
8096
8097 static const int kAtomDataSize = kAtomPatternIndex + 1;
8098
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008099 // Irregexp compiled code or bytecode for Latin1. If compilation
Steve Blocka7e24c12009-10-30 11:49:00 +00008100 // fails, this fields hold an exception object that should be
8101 // thrown if the regexp is used again.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008102 static const int kIrregexpLatin1CodeIndex = kDataIndex;
Steve Blocka7e24c12009-10-30 11:49:00 +00008103 // Irregexp compiled code or bytecode for UC16. If compilation
8104 // fails, this fields hold an exception object that should be
8105 // thrown if the regexp is used again.
8106 static const int kIrregexpUC16CodeIndex = kDataIndex + 1;
Ben Murdoch257744e2011-11-30 15:57:28 +00008107
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008108 // Saved instance of Irregexp compiled code or bytecode for Latin1 that
Ben Murdoch257744e2011-11-30 15:57:28 +00008109 // is a potential candidate for flushing.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008110 static const int kIrregexpLatin1CodeSavedIndex = kDataIndex + 2;
Ben Murdoch257744e2011-11-30 15:57:28 +00008111 // Saved instance of Irregexp compiled code or bytecode for UC16 that is
8112 // a potential candidate for flushing.
8113 static const int kIrregexpUC16CodeSavedIndex = kDataIndex + 3;
8114
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008115 // Maximal number of registers used by either Latin1 or UC16.
Steve Blocka7e24c12009-10-30 11:49:00 +00008116 // Only used to check that there is enough stack space
Ben Murdoch257744e2011-11-30 15:57:28 +00008117 static const int kIrregexpMaxRegisterCountIndex = kDataIndex + 4;
Steve Blocka7e24c12009-10-30 11:49:00 +00008118 // Number of captures in the compiled regexp.
Ben Murdoch257744e2011-11-30 15:57:28 +00008119 static const int kIrregexpCaptureCountIndex = kDataIndex + 5;
Ben Murdoch61f157c2016-09-16 13:49:30 +01008120 // Maps names of named capture groups (at indices 2i) to their corresponding
8121 // capture group indices (at indices 2i + 1).
8122 static const int kIrregexpCaptureNameMapIndex = kDataIndex + 6;
Steve Blocka7e24c12009-10-30 11:49:00 +00008123
Ben Murdoch61f157c2016-09-16 13:49:30 +01008124 static const int kIrregexpDataSize = kIrregexpCaptureNameMapIndex + 1;
Leon Clarkee46be812010-01-19 14:06:41 +00008125
8126 // Offsets directly into the data fixed array.
8127 static const int kDataTagOffset =
8128 FixedArray::kHeaderSize + kTagIndex * kPointerSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008129 static const int kDataOneByteCodeOffset =
8130 FixedArray::kHeaderSize + kIrregexpLatin1CodeIndex * kPointerSize;
Leon Clarked91b9f72010-01-27 17:25:45 +00008131 static const int kDataUC16CodeOffset =
8132 FixedArray::kHeaderSize + kIrregexpUC16CodeIndex * kPointerSize;
Leon Clarkee46be812010-01-19 14:06:41 +00008133 static const int kIrregexpCaptureCountOffset =
8134 FixedArray::kHeaderSize + kIrregexpCaptureCountIndex * kPointerSize;
Steve Block6ded16b2010-05-10 14:33:55 +01008135
8136 // In-object fields.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008137 static const int kLastIndexFieldIndex = 0;
8138 static const int kInObjectFieldCount = 1;
Ben Murdoch257744e2011-11-30 15:57:28 +00008139
8140 // The uninitialized value for a regexp code object.
8141 static const int kUninitializedValue = -1;
8142
8143 // The compilation error value for the regexp code object. The real error
8144 // object is in the saved code field.
8145 static const int kCompilationErrorValue = -2;
8146
8147 // When we store the sweep generation at which we moved the code from the
8148 // code index to the saved code index we mask it of to be in the [0:255]
8149 // range.
8150 static const int kCodeAgeMask = 0xff;
Steve Blocka7e24c12009-10-30 11:49:00 +00008151};
8152
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008153DEFINE_OPERATORS_FOR_FLAGS(JSRegExp::Flags)
8154
Steve Blocka7e24c12009-10-30 11:49:00 +00008155
Ben Murdochc7cc0282012-03-05 14:35:55 +00008156class CompilationCacheShape : public BaseShape<HashTableKey*> {
Steve Blocka7e24c12009-10-30 11:49:00 +00008157 public:
8158 static inline bool IsMatch(HashTableKey* key, Object* value) {
8159 return key->IsMatch(value);
8160 }
8161
8162 static inline uint32_t Hash(HashTableKey* key) {
8163 return key->Hash();
8164 }
8165
8166 static inline uint32_t HashForObject(HashTableKey* key, Object* object) {
8167 return key->HashForObject(object);
8168 }
8169
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008170 static inline Handle<Object> AsHandle(Isolate* isolate, HashTableKey* key);
Steve Blocka7e24c12009-10-30 11:49:00 +00008171
8172 static const int kPrefixSize = 0;
8173 static const int kEntrySize = 2;
8174};
8175
Steve Block3ce2e202009-11-05 08:53:23 +00008176
Emily Bernierd0a1eb72015-03-24 16:35:39 -04008177// This cache is used in two different variants. For regexp caching, it simply
8178// maps identifying info of the regexp to the cached regexp object. Scripts and
8179// eval code only gets cached after a second probe for the code object. To do
8180// so, on first "put" only a hash identifying the source is entered into the
8181// cache, mapping it to a lifetime count of the hash. On each call to Age all
8182// such lifetimes get reduced, and removed once they reach zero. If a second put
8183// is called while such a hash is live in the cache, the hash gets replaced by
8184// an actual cache entry. Age also removes stale live entries from the cache.
8185// Such entries are identified by SharedFunctionInfos pointing to either the
8186// recompilation stub, or to "old" code. This avoids memory leaks due to
8187// premature caching of scripts and eval strings that are never needed later.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008188class CompilationCacheTable: public HashTable<CompilationCacheTable,
8189 CompilationCacheShape,
Steve Blocka7e24c12009-10-30 11:49:00 +00008190 HashTableKey*> {
8191 public:
8192 // Find cached value for a string key, otherwise return null.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008193 Handle<Object> Lookup(
8194 Handle<String> src, Handle<Context> context, LanguageMode language_mode);
8195 Handle<Object> LookupEval(
8196 Handle<String> src, Handle<SharedFunctionInfo> shared,
8197 LanguageMode language_mode, int scope_position);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008198 Handle<Object> LookupRegExp(Handle<String> source, JSRegExp::Flags flags);
8199 static Handle<CompilationCacheTable> Put(
8200 Handle<CompilationCacheTable> cache, Handle<String> src,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008201 Handle<Context> context, LanguageMode language_mode,
8202 Handle<Object> value);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008203 static Handle<CompilationCacheTable> PutEval(
8204 Handle<CompilationCacheTable> cache, Handle<String> src,
8205 Handle<SharedFunctionInfo> context, Handle<SharedFunctionInfo> value,
8206 int scope_position);
8207 static Handle<CompilationCacheTable> PutRegExp(
8208 Handle<CompilationCacheTable> cache, Handle<String> src,
8209 JSRegExp::Flags flags, Handle<FixedArray> value);
Ben Murdochb0fe1622011-05-05 13:52:32 +01008210 void Remove(Object* value);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04008211 void Age();
8212 static const int kHashGenerations = 10;
Ben Murdochb0fe1622011-05-05 13:52:32 +01008213
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008214 DECLARE_CAST(CompilationCacheTable)
Steve Blocka7e24c12009-10-30 11:49:00 +00008215
8216 private:
8217 DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationCacheTable);
8218};
8219
8220
Ben Murdochc7cc0282012-03-05 14:35:55 +00008221class CodeCacheHashTableShape : public BaseShape<HashTableKey*> {
Steve Block6ded16b2010-05-10 14:33:55 +01008222 public:
8223 static inline bool IsMatch(HashTableKey* key, Object* value) {
8224 return key->IsMatch(value);
8225 }
8226
8227 static inline uint32_t Hash(HashTableKey* key) {
8228 return key->Hash();
8229 }
8230
8231 static inline uint32_t HashForObject(HashTableKey* key, Object* object) {
8232 return key->HashForObject(object);
8233 }
8234
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008235 static inline Handle<Object> AsHandle(Isolate* isolate, HashTableKey* key);
Steve Block6ded16b2010-05-10 14:33:55 +01008236
8237 static const int kPrefixSize = 0;
Ben Murdochc5610432016-08-08 18:44:38 +01008238 // The both the key (name + flags) and value (code object) can be derived from
8239 // the fixed array that stores both the name and code.
8240 // TODO(verwaest): Don't allocate a fixed array but inline name and code.
8241 // Rewrite IsMatch to get table + index as input rather than just the raw key.
8242 static const int kEntrySize = 1;
Steve Block6ded16b2010-05-10 14:33:55 +01008243};
8244
8245
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008246class CodeCacheHashTable: public HashTable<CodeCacheHashTable,
8247 CodeCacheHashTableShape,
Steve Block6ded16b2010-05-10 14:33:55 +01008248 HashTableKey*> {
8249 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008250 static Handle<CodeCacheHashTable> Put(
8251 Handle<CodeCacheHashTable> table,
8252 Handle<Name> name,
8253 Handle<Code> code);
Steve Block6ded16b2010-05-10 14:33:55 +01008254
Ben Murdochc5610432016-08-08 18:44:38 +01008255 Code* Lookup(Name* name, Code::Flags flags);
Steve Block6ded16b2010-05-10 14:33:55 +01008256
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008257 DECLARE_CAST(CodeCacheHashTable)
Steve Block6ded16b2010-05-10 14:33:55 +01008258
Steve Block6ded16b2010-05-10 14:33:55 +01008259 private:
8260 DISALLOW_IMPLICIT_CONSTRUCTORS(CodeCacheHashTable);
8261};
8262
8263
Ben Murdoch3ef787d2012-04-12 10:51:47 +01008264class TypeFeedbackInfo: public Struct {
8265 public:
8266 inline int ic_total_count();
8267 inline void set_ic_total_count(int count);
8268
Ben Murdoch8f9999f2012-04-23 10:39:17 +01008269 inline int ic_with_type_info_count();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008270 inline void change_ic_with_type_info_count(int delta);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01008271
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008272 inline int ic_generic_count();
8273 inline void change_ic_generic_count(int delta);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01008274
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008275 inline void initialize_storage();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01008276
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008277 inline void change_own_type_change_checksum();
8278 inline int own_type_change_checksum();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01008279
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008280 inline void set_inlined_type_change_checksum(int checksum);
8281 inline bool matches_inlined_type_change_checksum(int checksum);
8282
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008283 DECLARE_CAST(TypeFeedbackInfo)
8284
8285 // Dispatched behavior.
8286 DECLARE_PRINTER(TypeFeedbackInfo)
8287 DECLARE_VERIFIER(TypeFeedbackInfo)
8288
8289 static const int kStorage1Offset = HeapObject::kHeaderSize;
8290 static const int kStorage2Offset = kStorage1Offset + kPointerSize;
8291 static const int kStorage3Offset = kStorage2Offset + kPointerSize;
8292 static const int kSize = kStorage3Offset + kPointerSize;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01008293
8294 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008295 static const int kTypeChangeChecksumBits = 7;
8296
8297 class ICTotalCountField: public BitField<int, 0,
8298 kSmiValueSize - kTypeChangeChecksumBits> {}; // NOLINT
8299 class OwnTypeChangeChecksum: public BitField<int,
8300 kSmiValueSize - kTypeChangeChecksumBits,
8301 kTypeChangeChecksumBits> {}; // NOLINT
8302 class ICsWithTypeInfoCountField: public BitField<int, 0,
8303 kSmiValueSize - kTypeChangeChecksumBits> {}; // NOLINT
8304 class InlinedTypeChangeChecksum: public BitField<int,
8305 kSmiValueSize - kTypeChangeChecksumBits,
8306 kTypeChangeChecksumBits> {}; // NOLINT
8307
Ben Murdoch3ef787d2012-04-12 10:51:47 +01008308 DISALLOW_IMPLICIT_CONSTRUCTORS(TypeFeedbackInfo);
8309};
8310
8311
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008312enum AllocationSiteMode {
8313 DONT_TRACK_ALLOCATION_SITE,
8314 TRACK_ALLOCATION_SITE,
8315 LAST_ALLOCATION_SITE_MODE = TRACK_ALLOCATION_SITE
8316};
8317
8318
8319class AllocationSite: public Struct {
8320 public:
8321 static const uint32_t kMaximumArrayBytesToPretransition = 8 * 1024;
8322 static const double kPretenureRatio;
8323 static const int kPretenureMinimumCreated = 100;
8324
8325 // Values for pretenure decision field.
8326 enum PretenureDecision {
8327 kUndecided = 0,
8328 kDontTenure = 1,
8329 kMaybeTenure = 2,
8330 kTenure = 3,
8331 kZombie = 4,
8332 kLastPretenureDecisionValue = kZombie
8333 };
8334
8335 const char* PretenureDecisionName(PretenureDecision decision);
8336
8337 DECL_ACCESSORS(transition_info, Object)
8338 // nested_site threads a list of sites that represent nested literals
8339 // walked in a particular order. So [[1, 2], 1, 2] will have one
8340 // nested_site, but [[1, 2], 3, [4]] will have a list of two.
8341 DECL_ACCESSORS(nested_site, Object)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008342 DECL_INT_ACCESSORS(pretenure_data)
8343 DECL_INT_ACCESSORS(pretenure_create_count)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008344 DECL_ACCESSORS(dependent_code, DependentCode)
8345 DECL_ACCESSORS(weak_next, Object)
8346
8347 inline void Initialize();
8348
8349 // This method is expensive, it should only be called for reporting.
8350 bool IsNestedSite();
8351
8352 // transition_info bitfields, for constructed array transition info.
8353 class ElementsKindBits: public BitField<ElementsKind, 0, 15> {};
8354 class UnusedBits: public BitField<int, 15, 14> {};
8355 class DoNotInlineBit: public BitField<bool, 29, 1> {};
8356
8357 // Bitfields for pretenure_data
8358 class MementoFoundCountBits: public BitField<int, 0, 26> {};
8359 class PretenureDecisionBits: public BitField<PretenureDecision, 26, 3> {};
8360 class DeoptDependentCodeBit: public BitField<bool, 29, 1> {};
8361 STATIC_ASSERT(PretenureDecisionBits::kMax >= kLastPretenureDecisionValue);
8362
8363 // Increments the mementos found counter and returns true when the first
8364 // memento was found for a given allocation site.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008365 inline bool IncrementMementoFoundCount(int increment = 1);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008366
8367 inline void IncrementMementoCreateCount();
8368
8369 PretenureFlag GetPretenureMode();
8370
8371 void ResetPretenureDecision();
8372
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008373 inline PretenureDecision pretenure_decision();
8374 inline void set_pretenure_decision(PretenureDecision decision);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008375
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008376 inline bool deopt_dependent_code();
8377 inline void set_deopt_dependent_code(bool deopt);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008378
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008379 inline int memento_found_count();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008380 inline void set_memento_found_count(int count);
8381
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008382 inline int memento_create_count();
8383 inline void set_memento_create_count(int count);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008384
8385 // The pretenuring decision is made during gc, and the zombie state allows
8386 // us to recognize when an allocation site is just being kept alive because
8387 // a later traversal of new space may discover AllocationMementos that point
8388 // to this AllocationSite.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008389 inline bool IsZombie();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008390
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008391 inline bool IsMaybeTenure();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008392
8393 inline void MarkZombie();
8394
8395 inline bool MakePretenureDecision(PretenureDecision current_decision,
8396 double ratio,
8397 bool maximum_size_scavenge);
8398
8399 inline bool DigestPretenuringFeedback(bool maximum_size_scavenge);
8400
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008401 inline ElementsKind GetElementsKind();
8402 inline void SetElementsKind(ElementsKind kind);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008403
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008404 inline bool CanInlineCall();
8405 inline void SetDoNotInlineCall();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008406
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008407 inline bool SitePointsToLiteral();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008408
8409 static void DigestTransitionFeedback(Handle<AllocationSite> site,
8410 ElementsKind to_kind);
8411
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008412 DECLARE_PRINTER(AllocationSite)
8413 DECLARE_VERIFIER(AllocationSite)
8414
8415 DECLARE_CAST(AllocationSite)
8416 static inline AllocationSiteMode GetMode(
8417 ElementsKind boilerplate_elements_kind);
8418 static inline AllocationSiteMode GetMode(ElementsKind from, ElementsKind to);
8419 static inline bool CanTrack(InstanceType type);
8420
8421 static const int kTransitionInfoOffset = HeapObject::kHeaderSize;
8422 static const int kNestedSiteOffset = kTransitionInfoOffset + kPointerSize;
8423 static const int kPretenureDataOffset = kNestedSiteOffset + kPointerSize;
8424 static const int kPretenureCreateCountOffset =
8425 kPretenureDataOffset + kPointerSize;
8426 static const int kDependentCodeOffset =
8427 kPretenureCreateCountOffset + kPointerSize;
8428 static const int kWeakNextOffset = kDependentCodeOffset + kPointerSize;
8429 static const int kSize = kWeakNextOffset + kPointerSize;
8430
8431 // During mark compact we need to take special care for the dependent code
8432 // field.
8433 static const int kPointerFieldsBeginOffset = kTransitionInfoOffset;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008434 static const int kPointerFieldsEndOffset = kWeakNextOffset;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008435
8436 // For other visitors, use the fixed body descriptor below.
Ben Murdoch097c5b22016-05-18 11:27:45 +01008437 typedef FixedBodyDescriptor<HeapObject::kHeaderSize, kSize, kSize>
8438 BodyDescriptor;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008439
8440 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008441 inline bool PretenuringDecisionMade();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008442
8443 DISALLOW_IMPLICIT_CONSTRUCTORS(AllocationSite);
8444};
8445
8446
8447class AllocationMemento: public Struct {
8448 public:
8449 static const int kAllocationSiteOffset = HeapObject::kHeaderSize;
8450 static const int kSize = kAllocationSiteOffset + kPointerSize;
8451
8452 DECL_ACCESSORS(allocation_site, Object)
8453
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008454 inline bool IsValid();
8455 inline AllocationSite* GetAllocationSite();
Ben Murdoch097c5b22016-05-18 11:27:45 +01008456 inline Address GetAllocationSiteUnchecked();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008457
8458 DECLARE_PRINTER(AllocationMemento)
8459 DECLARE_VERIFIER(AllocationMemento)
8460
8461 DECLARE_CAST(AllocationMemento)
8462
8463 private:
8464 DISALLOW_IMPLICIT_CONSTRUCTORS(AllocationMemento);
8465};
8466
8467
8468// Representation of a slow alias as part of a sloppy arguments objects.
8469// For fast aliases (if HasSloppyArgumentsElements()):
Ben Murdoch3ef787d2012-04-12 10:51:47 +01008470// - the parameter map contains an index into the context
8471// - all attributes of the element have default values
8472// For slow aliases (if HasDictionaryArgumentsElements()):
8473// - the parameter map contains no fast alias mapping (i.e. the hole)
8474// - this struct (in the slow backing store) contains an index into the context
8475// - all attributes are available as part if the property details
8476class AliasedArgumentsEntry: public Struct {
8477 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008478 inline int aliased_context_slot() const;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01008479 inline void set_aliased_context_slot(int count);
8480
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008481 DECLARE_CAST(AliasedArgumentsEntry)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01008482
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008483 // Dispatched behavior.
8484 DECLARE_PRINTER(AliasedArgumentsEntry)
8485 DECLARE_VERIFIER(AliasedArgumentsEntry)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01008486
8487 static const int kAliasedContextSlot = HeapObject::kHeaderSize;
8488 static const int kSize = kAliasedContextSlot + kPointerSize;
8489
8490 private:
8491 DISALLOW_IMPLICIT_CONSTRUCTORS(AliasedArgumentsEntry);
8492};
8493
8494
Steve Blocka7e24c12009-10-30 11:49:00 +00008495enum AllowNullsFlag {ALLOW_NULLS, DISALLOW_NULLS};
8496enum RobustnessFlag {ROBUST_STRING_TRAVERSAL, FAST_STRING_TRAVERSAL};
8497
8498
8499class StringHasher {
8500 public:
Ben Murdochc7cc0282012-03-05 14:35:55 +00008501 explicit inline StringHasher(int length, uint32_t seed);
Steve Blocka7e24c12009-10-30 11:49:00 +00008502
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008503 template <typename schar>
8504 static inline uint32_t HashSequentialString(const schar* chars,
8505 int length,
8506 uint32_t seed);
Steve Blocka7e24c12009-10-30 11:49:00 +00008507
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008508 // Reads all the data, even for long strings and computes the utf16 length.
8509 static uint32_t ComputeUtf8Hash(Vector<const char> chars,
8510 uint32_t seed,
8511 int* utf16_length_out);
Steve Blocka7e24c12009-10-30 11:49:00 +00008512
Kristian Monsen80d68ea2010-09-08 11:05:35 +01008513 // Calculated hash value for a string consisting of 1 to
8514 // String::kMaxArrayIndexSize digits with no leading zeros (except "0").
8515 // value is represented decimal value.
Iain Merrick9ac36c92010-09-13 15:29:50 +01008516 static uint32_t MakeArrayIndexHash(uint32_t value, int length);
Kristian Monsen80d68ea2010-09-08 11:05:35 +01008517
Ben Murdochc7cc0282012-03-05 14:35:55 +00008518 // No string is allowed to have a hash of zero. That value is reserved
8519 // for internal properties. If the hash calculation yields zero then we
8520 // use 27 instead.
8521 static const int kZeroHash = 27;
8522
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008523 // Reusable parts of the hashing algorithm.
8524 INLINE(static uint32_t AddCharacterCore(uint32_t running_hash, uint16_t c));
8525 INLINE(static uint32_t GetHashCore(uint32_t running_hash));
Emily Bernierd0a1eb72015-03-24 16:35:39 -04008526 INLINE(static uint32_t ComputeRunningHash(uint32_t running_hash,
8527 const uc16* chars, int length));
8528 INLINE(static uint32_t ComputeRunningHashOneByte(uint32_t running_hash,
8529 const char* chars,
8530 int length));
Steve Blocka7e24c12009-10-30 11:49:00 +00008531
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008532 protected:
8533 // Returns the value to store in the hash field of a string with
8534 // the given length and contents.
8535 uint32_t GetHashField();
8536 // Returns true if the hash of this string can be computed without
8537 // looking at the contents.
8538 inline bool has_trivial_hash();
8539 // Adds a block of characters to the hash.
8540 template<typename Char>
8541 inline void AddCharacters(const Char* chars, int len);
8542
8543 private:
8544 // Add a character to the hash.
8545 inline void AddCharacter(uint16_t c);
8546 // Update index. Returns true if string is still an index.
8547 inline bool UpdateIndex(uint16_t c);
Steve Blocka7e24c12009-10-30 11:49:00 +00008548
8549 int length_;
8550 uint32_t raw_running_hash_;
8551 uint32_t array_index_;
8552 bool is_array_index_;
8553 bool is_first_char_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008554 DISALLOW_COPY_AND_ASSIGN(StringHasher);
Steve Blocka7e24c12009-10-30 11:49:00 +00008555};
8556
8557
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008558class IteratingStringHasher : public StringHasher {
8559 public:
8560 static inline uint32_t Hash(String* string, uint32_t seed);
8561 inline void VisitOneByteString(const uint8_t* chars, int length);
8562 inline void VisitTwoByteString(const uint16_t* chars, int length);
8563
8564 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008565 inline IteratingStringHasher(int len, uint32_t seed);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04008566 void VisitConsString(ConsString* cons_string);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008567 DISALLOW_COPY_AND_ASSIGN(IteratingStringHasher);
8568};
Steve Block44f0eee2011-05-26 01:26:41 +01008569
8570
Steve Blocka7e24c12009-10-30 11:49:00 +00008571// The characteristics of a string are stored in its map. Retrieving these
8572// few bits of information is moderately expensive, involving two memory
8573// loads where the second is dependent on the first. To improve efficiency
8574// the shape of the string is given its own class so that it can be retrieved
8575// once and used for several string operations. A StringShape is small enough
8576// to be passed by value and is immutable, but be aware that flattening a
8577// string can potentially alter its shape. Also be aware that a GC caused by
8578// something else can alter the shape of a string due to ConsString
8579// shortcutting. Keeping these restrictions in mind has proven to be error-
8580// prone and so we no longer put StringShapes in variables unless there is a
8581// concrete performance benefit at that particular point in the code.
8582class StringShape BASE_EMBEDDED {
8583 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008584 inline explicit StringShape(const String* s);
Steve Blocka7e24c12009-10-30 11:49:00 +00008585 inline explicit StringShape(Map* s);
8586 inline explicit StringShape(InstanceType t);
8587 inline bool IsSequential();
8588 inline bool IsExternal();
8589 inline bool IsCons();
Ben Murdoch69a99ed2011-11-30 16:03:39 +00008590 inline bool IsSliced();
8591 inline bool IsIndirect();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008592 inline bool IsExternalOneByte();
Steve Blocka7e24c12009-10-30 11:49:00 +00008593 inline bool IsExternalTwoByte();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008594 inline bool IsSequentialOneByte();
Steve Blocka7e24c12009-10-30 11:49:00 +00008595 inline bool IsSequentialTwoByte();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008596 inline bool IsInternalized();
Steve Blocka7e24c12009-10-30 11:49:00 +00008597 inline StringRepresentationTag representation_tag();
Ben Murdoch69a99ed2011-11-30 16:03:39 +00008598 inline uint32_t encoding_tag();
Steve Blocka7e24c12009-10-30 11:49:00 +00008599 inline uint32_t full_representation_tag();
8600 inline uint32_t size_tag();
8601#ifdef DEBUG
8602 inline uint32_t type() { return type_; }
8603 inline void invalidate() { valid_ = false; }
8604 inline bool valid() { return valid_; }
8605#else
8606 inline void invalidate() { }
8607#endif
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00008608
Steve Blocka7e24c12009-10-30 11:49:00 +00008609 private:
8610 uint32_t type_;
8611#ifdef DEBUG
8612 inline void set_valid() { valid_ = true; }
8613 bool valid_;
8614#else
8615 inline void set_valid() { }
8616#endif
8617};
8618
8619
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008620// The Name abstract class captures anything that can be used as a property
8621// name, i.e., strings and symbols. All names store a hash value.
8622class Name: public HeapObject {
8623 public:
8624 // Get and set the hash field of the name.
8625 inline uint32_t hash_field();
8626 inline void set_hash_field(uint32_t value);
8627
8628 // Tells whether the hash code has been computed.
8629 inline bool HasHashCode();
8630
8631 // Returns a hash value used for the property table
8632 inline uint32_t Hash();
8633
8634 // Equality operations.
8635 inline bool Equals(Name* other);
8636 inline static bool Equals(Handle<Name> one, Handle<Name> two);
8637
8638 // Conversion.
8639 inline bool AsArrayIndex(uint32_t* index);
8640
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008641 // If the name is private, it can only name own properties.
8642 inline bool IsPrivate();
8643
Ben Murdoch097c5b22016-05-18 11:27:45 +01008644 inline bool IsUniqueName() const;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008645
8646 // Return a string version of this name that is converted according to the
8647 // rules described in ES6 section 9.2.11.
8648 MUST_USE_RESULT static MaybeHandle<String> ToFunctionName(Handle<Name> name);
Ben Murdoch61f157c2016-09-16 13:49:30 +01008649 MUST_USE_RESULT static MaybeHandle<String> ToFunctionName(
8650 Handle<Name> name, Handle<String> prefix);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008651
8652 DECLARE_CAST(Name)
8653
8654 DECLARE_PRINTER(Name)
Emily Bernierd0a1eb72015-03-24 16:35:39 -04008655#if TRACE_MAPS
8656 void NameShortPrint();
8657 int NameShortPrint(Vector<char> str);
8658#endif
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008659
8660 // Layout description.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04008661 static const int kHashFieldSlot = HeapObject::kHeaderSize;
8662#if V8_TARGET_LITTLE_ENDIAN || !V8_HOST_ARCH_64_BIT
8663 static const int kHashFieldOffset = kHashFieldSlot;
8664#else
8665 static const int kHashFieldOffset = kHashFieldSlot + kIntSize;
8666#endif
8667 static const int kSize = kHashFieldSlot + kPointerSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008668
8669 // Mask constant for checking if a name has a computed hash code
8670 // and if it is a string that is an array index. The least significant bit
8671 // indicates whether a hash code has been computed. If the hash code has
8672 // been computed the 2nd bit tells whether the string can be used as an
8673 // array index.
8674 static const int kHashNotComputedMask = 1;
8675 static const int kIsNotArrayIndexMask = 1 << 1;
8676 static const int kNofHashBitFields = 2;
8677
8678 // Shift constant retrieving hash code from hash field.
8679 static const int kHashShift = kNofHashBitFields;
8680
8681 // Only these bits are relevant in the hash, since the top two are shifted
8682 // out.
8683 static const uint32_t kHashBitMask = 0xffffffffu >> kHashShift;
8684
8685 // Array index strings this short can keep their index in the hash field.
8686 static const int kMaxCachedArrayIndexLength = 7;
8687
Ben Murdoch61f157c2016-09-16 13:49:30 +01008688 // Maximum number of characters to consider when trying to convert a string
8689 // value into an array index.
8690 static const int kMaxArrayIndexSize = 10;
8691
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008692 // For strings which are array indexes the hash value has the string length
8693 // mixed into the hash, mainly to avoid a hash value of zero which would be
8694 // the case for the string '0'. 24 bits are used for the array index value.
8695 static const int kArrayIndexValueBits = 24;
8696 static const int kArrayIndexLengthBits =
8697 kBitsPerInt - kArrayIndexValueBits - kNofHashBitFields;
8698
Ben Murdoch61f157c2016-09-16 13:49:30 +01008699 STATIC_ASSERT(kArrayIndexLengthBits > 0);
8700 STATIC_ASSERT(kMaxArrayIndexSize < (1 << kArrayIndexLengthBits));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008701
8702 class ArrayIndexValueBits : public BitField<unsigned int, kNofHashBitFields,
8703 kArrayIndexValueBits> {}; // NOLINT
8704 class ArrayIndexLengthBits : public BitField<unsigned int,
8705 kNofHashBitFields + kArrayIndexValueBits,
8706 kArrayIndexLengthBits> {}; // NOLINT
8707
8708 // Check that kMaxCachedArrayIndexLength + 1 is a power of two so we
8709 // could use a mask to test if the length of string is less than or equal to
8710 // kMaxCachedArrayIndexLength.
8711 STATIC_ASSERT(IS_POWER_OF_TWO(kMaxCachedArrayIndexLength + 1));
8712
8713 static const unsigned int kContainsCachedArrayIndexMask =
8714 (~static_cast<unsigned>(kMaxCachedArrayIndexLength)
8715 << ArrayIndexLengthBits::kShift) |
8716 kIsNotArrayIndexMask;
8717
8718 // Value of empty hash field indicating that the hash is not computed.
8719 static const int kEmptyHashField =
8720 kIsNotArrayIndexMask | kHashNotComputedMask;
8721
8722 protected:
8723 static inline bool IsHashFieldComputed(uint32_t field);
8724
8725 private:
8726 DISALLOW_IMPLICIT_CONSTRUCTORS(Name);
8727};
8728
8729
8730// ES6 symbols.
8731class Symbol: public Name {
8732 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008733 // [name]: The print name of a symbol, or undefined if none.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008734 DECL_ACCESSORS(name, Object)
8735
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008736 DECL_INT_ACCESSORS(flags)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008737
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008738 // [is_private]: Whether this is a private symbol. Private symbols can only
8739 // be used to designate own properties of objects.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008740 DECL_BOOLEAN_ACCESSORS(is_private)
8741
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008742 // [is_well_known_symbol]: Whether this is a spec-defined well-known symbol,
8743 // or not. Well-known symbols do not throw when an access check fails during
8744 // a load.
8745 DECL_BOOLEAN_ACCESSORS(is_well_known_symbol)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008746
8747 DECLARE_CAST(Symbol)
8748
8749 // Dispatched behavior.
8750 DECLARE_PRINTER(Symbol)
8751 DECLARE_VERIFIER(Symbol)
8752
8753 // Layout description.
8754 static const int kNameOffset = Name::kSize;
8755 static const int kFlagsOffset = kNameOffset + kPointerSize;
8756 static const int kSize = kFlagsOffset + kPointerSize;
8757
8758 typedef FixedBodyDescriptor<kNameOffset, kFlagsOffset, kSize> BodyDescriptor;
8759
Emily Bernierd0a1eb72015-03-24 16:35:39 -04008760 void SymbolShortPrint(std::ostream& os);
8761
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008762 private:
8763 static const int kPrivateBit = 0;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008764 static const int kWellKnownSymbolBit = 1;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008765
Emily Bernierd0a1eb72015-03-24 16:35:39 -04008766 const char* PrivateSymbolToName() const;
8767
8768#if TRACE_MAPS
8769 friend class Name; // For PrivateSymbolToName.
8770#endif
8771
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008772 DISALLOW_IMPLICIT_CONSTRUCTORS(Symbol);
8773};
8774
8775
8776class ConsString;
8777
Steve Blocka7e24c12009-10-30 11:49:00 +00008778// The String abstract class captures JavaScript string values:
8779//
8780// Ecma-262:
8781// 4.3.16 String Value
8782// A string value is a member of the type String and is a finite
8783// ordered sequence of zero or more 16-bit unsigned integer values.
8784//
8785// All string values have a length field.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008786class String: public Name {
Steve Blocka7e24c12009-10-30 11:49:00 +00008787 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008788 enum Encoding { ONE_BYTE_ENCODING, TWO_BYTE_ENCODING };
8789
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008790 class SubStringRange {
8791 public:
8792 explicit inline SubStringRange(String* string, int first = 0,
8793 int length = -1);
8794 class iterator;
8795 inline iterator begin();
8796 inline iterator end();
8797
8798 private:
8799 String* string_;
8800 int first_;
8801 int length_;
8802 };
8803
Ben Murdoch69a99ed2011-11-30 16:03:39 +00008804 // Representation of the flat content of a String.
8805 // A non-flat string doesn't have flat content.
8806 // A flat string has content that's encoded as a sequence of either
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008807 // one-byte chars or two-byte UC16.
Ben Murdoch69a99ed2011-11-30 16:03:39 +00008808 // Returned by String::GetFlatContent().
8809 class FlatContent {
8810 public:
8811 // Returns true if the string is flat and this structure contains content.
Ben Murdochc5610432016-08-08 18:44:38 +01008812 bool IsFlat() const { return state_ != NON_FLAT; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008813 // Returns true if the structure contains one-byte content.
Ben Murdochc5610432016-08-08 18:44:38 +01008814 bool IsOneByte() const { return state_ == ONE_BYTE; }
Ben Murdoch69a99ed2011-11-30 16:03:39 +00008815 // Returns true if the structure contains two-byte content.
Ben Murdochc5610432016-08-08 18:44:38 +01008816 bool IsTwoByte() const { return state_ == TWO_BYTE; }
Ben Murdoch69a99ed2011-11-30 16:03:39 +00008817
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008818 // Return the one byte content of the string. Only use if IsOneByte()
8819 // returns true.
Ben Murdochc5610432016-08-08 18:44:38 +01008820 Vector<const uint8_t> ToOneByteVector() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008821 DCHECK_EQ(ONE_BYTE, state_);
8822 return Vector<const uint8_t>(onebyte_start, length_);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00008823 }
8824 // Return the two-byte content of the string. Only use if IsTwoByte()
8825 // returns true.
Ben Murdochc5610432016-08-08 18:44:38 +01008826 Vector<const uc16> ToUC16Vector() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008827 DCHECK_EQ(TWO_BYTE, state_);
8828 return Vector<const uc16>(twobyte_start, length_);
8829 }
8830
Ben Murdochc5610432016-08-08 18:44:38 +01008831 uc16 Get(int i) const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008832 DCHECK(i < length_);
8833 DCHECK(state_ != NON_FLAT);
8834 if (state_ == ONE_BYTE) return onebyte_start[i];
8835 return twobyte_start[i];
Ben Murdoch69a99ed2011-11-30 16:03:39 +00008836 }
8837
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008838 bool UsesSameString(const FlatContent& other) const {
8839 return onebyte_start == other.onebyte_start;
8840 }
8841
Ben Murdoch69a99ed2011-11-30 16:03:39 +00008842 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008843 enum State { NON_FLAT, ONE_BYTE, TWO_BYTE };
Ben Murdoch69a99ed2011-11-30 16:03:39 +00008844
8845 // Constructors only used by String::GetFlatContent().
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008846 explicit FlatContent(const uint8_t* start, int length)
8847 : onebyte_start(start), length_(length), state_(ONE_BYTE) {}
8848 explicit FlatContent(const uc16* start, int length)
8849 : twobyte_start(start), length_(length), state_(TWO_BYTE) { }
8850 FlatContent() : onebyte_start(NULL), length_(0), state_(NON_FLAT) { }
Ben Murdoch69a99ed2011-11-30 16:03:39 +00008851
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008852 union {
8853 const uint8_t* onebyte_start;
8854 const uc16* twobyte_start;
8855 };
8856 int length_;
Ben Murdoch69a99ed2011-11-30 16:03:39 +00008857 State state_;
8858
8859 friend class String;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008860 friend class IterableSubString;
Ben Murdoch69a99ed2011-11-30 16:03:39 +00008861 };
8862
Emily Bernierd0a1eb72015-03-24 16:35:39 -04008863 template <typename Char>
8864 INLINE(Vector<const Char> GetCharVector());
8865
Steve Blocka7e24c12009-10-30 11:49:00 +00008866 // Get and set the length of the string.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008867 inline int length() const;
Steve Blocka7e24c12009-10-30 11:49:00 +00008868 inline void set_length(int value);
8869
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008870 // Get and set the length of the string using acquire loads and release
8871 // stores.
8872 inline int synchronized_length() const;
8873 inline void synchronized_set_length(int value);
Steve Blocka7e24c12009-10-30 11:49:00 +00008874
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008875 // Returns whether this string has only one-byte chars, i.e. all of them can
8876 // be one-byte encoded. This might be the case even if the string is
Ben Murdoch69a99ed2011-11-30 16:03:39 +00008877 // two-byte. Such strings may appear when the embedder prefers
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008878 // two-byte external representations even for one-byte data.
8879 inline bool IsOneByteRepresentation() const;
8880 inline bool IsTwoByteRepresentation() const;
Steve Blocka7e24c12009-10-30 11:49:00 +00008881
Ben Murdoch69a99ed2011-11-30 16:03:39 +00008882 // Cons and slices have an encoding flag that may not represent the actual
8883 // encoding of the underlying string. This is taken into account here.
8884 // Requires: this->IsFlat()
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008885 inline bool IsOneByteRepresentationUnderneath();
Ben Murdoch69a99ed2011-11-30 16:03:39 +00008886 inline bool IsTwoByteRepresentationUnderneath();
8887
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01008888 // NOTE: this should be considered only a hint. False negatives are
8889 // possible.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008890 inline bool HasOnlyOneByteChars();
Steve Block6ded16b2010-05-10 14:33:55 +01008891
Steve Blocka7e24c12009-10-30 11:49:00 +00008892 // Get and set individual two byte chars in the string.
8893 inline void Set(int index, uint16_t value);
8894 // Get individual two byte char in the string. Repeated calls
8895 // to this method are not efficient unless the string is flat.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008896 INLINE(uint16_t Get(int index));
Steve Blocka7e24c12009-10-30 11:49:00 +00008897
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008898 // ES6 section 7.1.3.1 ToNumber Applied to the String Type
8899 static Handle<Object> ToNumber(Handle<String> subject);
8900
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008901 // Flattens the string. Checks first inline to see if it is
Leon Clarkef7060e22010-06-03 12:02:55 +01008902 // necessary. Does nothing if the string is not a cons string.
8903 // Flattening allocates a sequential string with the same data as
8904 // the given string and mutates the cons string to a degenerate
8905 // form, where the first component is the new sequential string and
8906 // the second component is the empty string. If allocation fails,
8907 // this function returns a failure. If flattening succeeds, this
8908 // function returns the sequential string that is now the first
8909 // component of the cons string.
8910 //
8911 // Degenerate cons strings are handled specially by the garbage
8912 // collector (see IsShortcutCandidate).
Steve Blocka7e24c12009-10-30 11:49:00 +00008913
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008914 static inline Handle<String> Flatten(Handle<String> string,
8915 PretenureFlag pretenure = NOT_TENURED);
Leon Clarkef7060e22010-06-03 12:02:55 +01008916
Ben Murdoch69a99ed2011-11-30 16:03:39 +00008917 // Tries to return the content of a flat string as a structure holding either
8918 // a flat vector of char or of uc16.
8919 // If the string isn't flat, and therefore doesn't have flat content, the
8920 // returned structure will report so, and can't provide a vector of either
8921 // kind.
8922 FlatContent GetFlatContent();
8923
8924 // Returns the parent of a sliced string or first part of a flat cons string.
8925 // Requires: StringShape(this).IsIndirect() && this->IsFlat()
8926 inline String* GetUnderlying();
Steve Blocka7e24c12009-10-30 11:49:00 +00008927
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008928 // String relational comparison, implemented according to ES6 section 7.2.11
8929 // Abstract Relational Comparison (step 5): The comparison of Strings uses a
8930 // simple lexicographic ordering on sequences of code unit values. There is no
8931 // attempt to use the more complex, semantically oriented definitions of
8932 // character or string equality and collating order defined in the Unicode
8933 // specification. Therefore String values that are canonically equal according
8934 // to the Unicode standard could test as unequal. In effect this algorithm
8935 // assumes that both Strings are already in normalized form. Also, note that
8936 // for strings containing supplementary characters, lexicographic ordering on
8937 // sequences of UTF-16 code unit values differs from that on sequences of code
8938 // point values.
8939 MUST_USE_RESULT static ComparisonResult Compare(Handle<String> x,
8940 Handle<String> y);
Steve Blocka7e24c12009-10-30 11:49:00 +00008941
Steve Blocka7e24c12009-10-30 11:49:00 +00008942 // String equality operations.
8943 inline bool Equals(String* other);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008944 inline static bool Equals(Handle<String> one, Handle<String> two);
8945 bool IsUtf8EqualTo(Vector<const char> str, bool allow_prefix_match = false);
8946 bool IsOneByteEqualTo(Vector<const uint8_t> str);
Steve Block9fac8402011-05-12 15:51:54 +01008947 bool IsTwoByteEqualTo(Vector<const uc16> str);
Steve Blocka7e24c12009-10-30 11:49:00 +00008948
8949 // Return a UTF8 representation of the string. The string is null
8950 // terminated but may optionally contain nulls. Length is returned
8951 // in length_output if length_output is not a null pointer The string
8952 // should be nearly flat, otherwise the performance of this method may
8953 // be very slow (quadratic in the length). Setting robustness_flag to
8954 // ROBUST_STRING_TRAVERSAL invokes behaviour that is robust This means it
8955 // handles unexpected data without causing assert failures and it does not
8956 // do any heap allocations. This is useful when printing stack traces.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008957 base::SmartArrayPointer<char> ToCString(AllowNullsFlag allow_nulls,
8958 RobustnessFlag robustness_flag,
8959 int offset, int length,
8960 int* length_output = 0);
8961 base::SmartArrayPointer<char> ToCString(
Steve Blocka7e24c12009-10-30 11:49:00 +00008962 AllowNullsFlag allow_nulls = DISALLOW_NULLS,
8963 RobustnessFlag robustness_flag = FAST_STRING_TRAVERSAL,
8964 int* length_output = 0);
8965
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008966 bool ComputeArrayIndex(uint32_t* index);
Steve Blocka7e24c12009-10-30 11:49:00 +00008967
8968 // Externalization.
8969 bool MakeExternal(v8::String::ExternalStringResource* resource);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008970 bool MakeExternal(v8::String::ExternalOneByteStringResource* resource);
Steve Blocka7e24c12009-10-30 11:49:00 +00008971
8972 // Conversion.
8973 inline bool AsArrayIndex(uint32_t* index);
8974
Ben Murdoch61f157c2016-09-16 13:49:30 +01008975 // Trimming.
8976 enum TrimMode { kTrim, kTrimLeft, kTrimRight };
8977 static Handle<String> Trim(Handle<String> string, TrimMode mode);
8978
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008979 DECLARE_CAST(String)
Steve Blocka7e24c12009-10-30 11:49:00 +00008980
8981 void PrintOn(FILE* out);
8982
8983 // For use during stack traces. Performs rudimentary sanity check.
8984 bool LooksValid();
8985
8986 // Dispatched behavior.
Ben Murdoch61f157c2016-09-16 13:49:30 +01008987 void StringShortPrint(StringStream* accumulator, bool show_details = true);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04008988 void PrintUC16(std::ostream& os, int start = 0, int end = -1); // NOLINT
8989#if defined(DEBUG) || defined(OBJECT_PRINT)
Ben Murdoch69a99ed2011-11-30 16:03:39 +00008990 char* ToAsciiArray();
Ben Murdochb0fe1622011-05-05 13:52:32 +01008991#endif
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008992 DECLARE_PRINTER(String)
8993 DECLARE_VERIFIER(String)
8994
Steve Blocka7e24c12009-10-30 11:49:00 +00008995 inline bool IsFlat();
8996
8997 // Layout description.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008998 static const int kLengthOffset = Name::kSize;
8999 static const int kSize = kLengthOffset + kPointerSize;
Steve Blocka7e24c12009-10-30 11:49:00 +00009000
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009001 // Max char codes.
9002 static const int32_t kMaxOneByteCharCode = unibrow::Latin1::kMaxChar;
9003 static const uint32_t kMaxOneByteCharCodeU = unibrow::Latin1::kMaxChar;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01009004 static const int kMaxUtf16CodeUnit = 0xffff;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009005 static const uint32_t kMaxUtf16CodeUnitU = kMaxUtf16CodeUnit;
Ben Murdoch097c5b22016-05-18 11:27:45 +01009006 static const uc32 kMaxCodePoint = 0x10ffff;
Steve Blockd0582a62009-12-15 09:54:21 +00009007
9008 // Maximal string length.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009009 static const int kMaxLength = (1 << 28) - 16;
Steve Blockd0582a62009-12-15 09:54:21 +00009010
9011 // Max length for computing hash. For strings longer than this limit the
9012 // string length is used as the hash value.
9013 static const int kMaxHashCalcLength = 16383;
Steve Blocka7e24c12009-10-30 11:49:00 +00009014
9015 // Limit for truncation in short printing.
9016 static const int kMaxShortPrintLength = 1024;
9017
9018 // Support for regular expressions.
Steve Blocka7e24c12009-10-30 11:49:00 +00009019 const uc16* GetTwoByteData(unsigned start);
9020
Steve Blocka7e24c12009-10-30 11:49:00 +00009021 // Helper function for flattening strings.
9022 template <typename sinkchar>
9023 static void WriteToFlat(String* source,
9024 sinkchar* sink,
9025 int from,
9026 int to);
9027
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009028 // The return value may point to the first aligned word containing the first
9029 // non-one-byte character, rather than directly to the non-one-byte character.
9030 // If the return value is >= the passed length, the entire string was
9031 // one-byte.
9032 static inline int NonAsciiStart(const char* chars, int length) {
9033 const char* start = chars;
Steve Block9fac8402011-05-12 15:51:54 +01009034 const char* limit = chars + length;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009035
9036 if (length >= kIntptrSize) {
9037 // Check unaligned bytes.
9038 while (!IsAligned(reinterpret_cast<intptr_t>(chars), sizeof(uintptr_t))) {
9039 if (static_cast<uint8_t>(*chars) > unibrow::Utf8::kMaxOneByteChar) {
9040 return static_cast<int>(chars - start);
9041 }
9042 ++chars;
Steve Block9fac8402011-05-12 15:51:54 +01009043 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009044 // Check aligned words.
9045 DCHECK(unibrow::Utf8::kMaxOneByteChar == 0x7F);
9046 const uintptr_t non_one_byte_mask = kUintptrAllBitsSet / 0xFF * 0x80;
9047 while (chars + sizeof(uintptr_t) <= limit) {
9048 if (*reinterpret_cast<const uintptr_t*>(chars) & non_one_byte_mask) {
9049 return static_cast<int>(chars - start);
9050 }
9051 chars += sizeof(uintptr_t);
9052 }
Steve Block9fac8402011-05-12 15:51:54 +01009053 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009054 // Check remaining unaligned bytes.
Steve Block9fac8402011-05-12 15:51:54 +01009055 while (chars < limit) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009056 if (static_cast<uint8_t>(*chars) > unibrow::Utf8::kMaxOneByteChar) {
9057 return static_cast<int>(chars - start);
9058 }
Steve Block9fac8402011-05-12 15:51:54 +01009059 ++chars;
9060 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009061
9062 return static_cast<int>(chars - start);
Steve Block9fac8402011-05-12 15:51:54 +01009063 }
9064
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009065 static inline bool IsAscii(const char* chars, int length) {
9066 return NonAsciiStart(chars, length) >= length;
9067 }
9068
9069 static inline bool IsAscii(const uint8_t* chars, int length) {
9070 return
9071 NonAsciiStart(reinterpret_cast<const char*>(chars), length) >= length;
9072 }
9073
9074 static inline int NonOneByteStart(const uc16* chars, int length) {
Steve Block9fac8402011-05-12 15:51:54 +01009075 const uc16* limit = chars + length;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009076 const uc16* start = chars;
Steve Block9fac8402011-05-12 15:51:54 +01009077 while (chars < limit) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009078 if (*chars > kMaxOneByteCharCodeU) return static_cast<int>(chars - start);
Steve Block9fac8402011-05-12 15:51:54 +01009079 ++chars;
9080 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009081 return static_cast<int>(chars - start);
Steve Block9fac8402011-05-12 15:51:54 +01009082 }
9083
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009084 static inline bool IsOneByte(const uc16* chars, int length) {
9085 return NonOneByteStart(chars, length) >= length;
9086 }
Steve Blocka7e24c12009-10-30 11:49:00 +00009087
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009088 template<class Visitor>
9089 static inline ConsString* VisitFlat(Visitor* visitor,
9090 String* string,
9091 int offset = 0);
9092
9093 static Handle<FixedArray> CalculateLineEnds(Handle<String> string,
9094 bool include_ending_line);
9095
9096 // Use the hash field to forward to the canonical internalized string
9097 // when deserializing an internalized string.
9098 inline void SetForwardedInternalizedString(String* string);
9099 inline String* GetForwardedInternalizedString();
Steve Blocka7e24c12009-10-30 11:49:00 +00009100
9101 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009102 friend class Name;
9103 friend class StringTableInsertionKey;
Leon Clarkef7060e22010-06-03 12:02:55 +01009104
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009105 static Handle<String> SlowFlatten(Handle<ConsString> cons,
9106 PretenureFlag tenure);
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01009107
Steve Blocka7e24c12009-10-30 11:49:00 +00009108 // Slow case of String::Equals. This implementation works on any strings
9109 // but it is most efficient on strings that are almost flat.
9110 bool SlowEquals(String* other);
9111
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009112 static bool SlowEquals(Handle<String> one, Handle<String> two);
9113
Steve Blocka7e24c12009-10-30 11:49:00 +00009114 // Slow case of AsArrayIndex.
9115 bool SlowAsArrayIndex(uint32_t* index);
9116
9117 // Compute and set the hash code.
9118 uint32_t ComputeAndSetHash();
9119
9120 DISALLOW_IMPLICIT_CONSTRUCTORS(String);
9121};
9122
9123
9124// The SeqString abstract class captures sequential string values.
9125class SeqString: public String {
9126 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009127 DECLARE_CAST(SeqString)
Steve Blocka7e24c12009-10-30 11:49:00 +00009128
Ben Murdoch3ef787d2012-04-12 10:51:47 +01009129 // Layout description.
9130 static const int kHeaderSize = String::kSize;
9131
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009132 // Truncate the string in-place if possible and return the result.
9133 // In case of new_length == 0, the empty string is returned without
9134 // truncating the original string.
9135 MUST_USE_RESULT static Handle<String> Truncate(Handle<SeqString> string,
9136 int new_length);
Steve Blocka7e24c12009-10-30 11:49:00 +00009137 private:
9138 DISALLOW_IMPLICIT_CONSTRUCTORS(SeqString);
9139};
9140
9141
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009142// The OneByteString class captures sequential one-byte string objects.
9143// Each character in the OneByteString is an one-byte character.
9144class SeqOneByteString: public SeqString {
Steve Blocka7e24c12009-10-30 11:49:00 +00009145 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009146 static const bool kHasOneByteEncoding = true;
Leon Clarkeac952652010-07-15 11:15:24 +01009147
Steve Blocka7e24c12009-10-30 11:49:00 +00009148 // Dispatched behavior.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009149 inline uint16_t SeqOneByteStringGet(int index);
9150 inline void SeqOneByteStringSet(int index, uint16_t value);
Steve Blocka7e24c12009-10-30 11:49:00 +00009151
9152 // Get the address of the characters in this string.
9153 inline Address GetCharsAddress();
9154
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009155 inline uint8_t* GetChars();
Steve Blocka7e24c12009-10-30 11:49:00 +00009156
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009157 DECLARE_CAST(SeqOneByteString)
Steve Blocka7e24c12009-10-30 11:49:00 +00009158
9159 // Garbage collection support. This method is called by the
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009160 // garbage collector to compute the actual size of an OneByteString
Steve Blocka7e24c12009-10-30 11:49:00 +00009161 // instance.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009162 inline int SeqOneByteStringSize(InstanceType instance_type);
Steve Blocka7e24c12009-10-30 11:49:00 +00009163
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009164 // Computes the size for an OneByteString instance of a given length.
Steve Blocka7e24c12009-10-30 11:49:00 +00009165 static int SizeFor(int length) {
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01009166 return OBJECT_POINTER_ALIGN(kHeaderSize + length * kCharSize);
Steve Blocka7e24c12009-10-30 11:49:00 +00009167 }
9168
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009169 // Maximal memory usage for a single sequential one-byte string.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01009170 static const int kMaxSize = 512 * MB - 1;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009171 STATIC_ASSERT((kMaxSize - kHeaderSize) >= String::kMaxLength);
Steve Blocka7e24c12009-10-30 11:49:00 +00009172
9173 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009174 DISALLOW_IMPLICIT_CONSTRUCTORS(SeqOneByteString);
Steve Blocka7e24c12009-10-30 11:49:00 +00009175};
9176
9177
9178// The TwoByteString class captures sequential unicode string objects.
9179// Each character in the TwoByteString is a two-byte uint16_t.
9180class SeqTwoByteString: public SeqString {
9181 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009182 static const bool kHasOneByteEncoding = false;
Leon Clarkeac952652010-07-15 11:15:24 +01009183
Steve Blocka7e24c12009-10-30 11:49:00 +00009184 // Dispatched behavior.
9185 inline uint16_t SeqTwoByteStringGet(int index);
9186 inline void SeqTwoByteStringSet(int index, uint16_t value);
9187
9188 // Get the address of the characters in this string.
9189 inline Address GetCharsAddress();
9190
9191 inline uc16* GetChars();
9192
9193 // For regexp code.
9194 const uint16_t* SeqTwoByteStringGetData(unsigned start);
9195
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009196 DECLARE_CAST(SeqTwoByteString)
Steve Blocka7e24c12009-10-30 11:49:00 +00009197
9198 // Garbage collection support. This method is called by the
9199 // garbage collector to compute the actual size of a TwoByteString
9200 // instance.
9201 inline int SeqTwoByteStringSize(InstanceType instance_type);
9202
9203 // Computes the size for a TwoByteString instance of a given length.
9204 static int SizeFor(int length) {
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01009205 return OBJECT_POINTER_ALIGN(kHeaderSize + length * kShortSize);
Steve Blocka7e24c12009-10-30 11:49:00 +00009206 }
9207
Leon Clarkee46be812010-01-19 14:06:41 +00009208 // Maximal memory usage for a single sequential two-byte string.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01009209 static const int kMaxSize = 512 * MB - 1;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009210 STATIC_ASSERT(static_cast<int>((kMaxSize - kHeaderSize)/sizeof(uint16_t)) >=
9211 String::kMaxLength);
Steve Blocka7e24c12009-10-30 11:49:00 +00009212
9213 private:
9214 DISALLOW_IMPLICIT_CONSTRUCTORS(SeqTwoByteString);
9215};
9216
9217
9218// The ConsString class describes string values built by using the
9219// addition operator on strings. A ConsString is a pair where the
9220// first and second components are pointers to other string values.
9221// One or both components of a ConsString can be pointers to other
9222// ConsStrings, creating a binary tree of ConsStrings where the leaves
9223// are non-ConsString string values. The string value represented by
9224// a ConsString can be obtained by concatenating the leaf string
9225// values in a left-to-right depth-first traversal of the tree.
9226class ConsString: public String {
9227 public:
9228 // First string of the cons cell.
9229 inline String* first();
9230 // Doesn't check that the result is a string, even in debug mode. This is
9231 // useful during GC where the mark bits confuse the checks.
9232 inline Object* unchecked_first();
9233 inline void set_first(String* first,
9234 WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
9235
9236 // Second string of the cons cell.
9237 inline String* second();
9238 // Doesn't check that the result is a string, even in debug mode. This is
9239 // useful during GC where the mark bits confuse the checks.
9240 inline Object* unchecked_second();
9241 inline void set_second(String* second,
9242 WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
9243
9244 // Dispatched behavior.
9245 uint16_t ConsStringGet(int index);
9246
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009247 DECLARE_CAST(ConsString)
Steve Blocka7e24c12009-10-30 11:49:00 +00009248
Steve Blocka7e24c12009-10-30 11:49:00 +00009249 // Layout description.
9250 static const int kFirstOffset = POINTER_SIZE_ALIGN(String::kSize);
9251 static const int kSecondOffset = kFirstOffset + kPointerSize;
9252 static const int kSize = kSecondOffset + kPointerSize;
9253
Steve Blocka7e24c12009-10-30 11:49:00 +00009254 // Minimum length for a cons string.
9255 static const int kMinLength = 13;
9256
Iain Merrick75681382010-08-19 15:07:18 +01009257 typedef FixedBodyDescriptor<kFirstOffset, kSecondOffset + kPointerSize, kSize>
9258 BodyDescriptor;
9259
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009260 DECLARE_VERIFIER(ConsString)
Ben Murdoch69a99ed2011-11-30 16:03:39 +00009261
Steve Blocka7e24c12009-10-30 11:49:00 +00009262 private:
9263 DISALLOW_IMPLICIT_CONSTRUCTORS(ConsString);
9264};
9265
9266
Ben Murdoch69a99ed2011-11-30 16:03:39 +00009267// The Sliced String class describes strings that are substrings of another
9268// sequential string. The motivation is to save time and memory when creating
9269// a substring. A Sliced String is described as a pointer to the parent,
9270// the offset from the start of the parent string and the length. Using
9271// a Sliced String therefore requires unpacking of the parent string and
9272// adding the offset to the start address. A substring of a Sliced String
9273// are not nested since the double indirection is simplified when creating
9274// such a substring.
9275// Currently missing features are:
9276// - handling externalized parent strings
9277// - external strings as parent
9278// - truncating sliced string to enable otherwise unneeded parent to be GC'ed.
9279class SlicedString: public String {
9280 public:
Ben Murdoch69a99ed2011-11-30 16:03:39 +00009281 inline String* parent();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009282 inline void set_parent(String* parent,
9283 WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
9284 inline int offset() const;
Ben Murdoch69a99ed2011-11-30 16:03:39 +00009285 inline void set_offset(int offset);
9286
9287 // Dispatched behavior.
9288 uint16_t SlicedStringGet(int index);
9289
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009290 DECLARE_CAST(SlicedString)
Ben Murdoch69a99ed2011-11-30 16:03:39 +00009291
9292 // Layout description.
9293 static const int kParentOffset = POINTER_SIZE_ALIGN(String::kSize);
9294 static const int kOffsetOffset = kParentOffset + kPointerSize;
9295 static const int kSize = kOffsetOffset + kPointerSize;
9296
Ben Murdoch69a99ed2011-11-30 16:03:39 +00009297 // Minimum length for a sliced string.
9298 static const int kMinLength = 13;
9299
9300 typedef FixedBodyDescriptor<kParentOffset,
9301 kOffsetOffset + kPointerSize, kSize>
9302 BodyDescriptor;
9303
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009304 DECLARE_VERIFIER(SlicedString)
Ben Murdoch69a99ed2011-11-30 16:03:39 +00009305
9306 private:
9307 DISALLOW_IMPLICIT_CONSTRUCTORS(SlicedString);
9308};
9309
9310
Steve Blocka7e24c12009-10-30 11:49:00 +00009311// The ExternalString class describes string values that are backed by
9312// a string resource that lies outside the V8 heap. ExternalStrings
9313// consist of the length field common to all strings, a pointer to the
9314// external resource. It is important to ensure (externally) that the
9315// resource is not deallocated while the ExternalString is live in the
9316// V8 heap.
9317//
9318// The API expects that all ExternalStrings are created through the
9319// API. Therefore, ExternalStrings should not be used internally.
9320class ExternalString: public String {
9321 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009322 DECLARE_CAST(ExternalString)
Steve Blocka7e24c12009-10-30 11:49:00 +00009323
9324 // Layout description.
9325 static const int kResourceOffset = POINTER_SIZE_ALIGN(String::kSize);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01009326 static const int kShortSize = kResourceOffset + kPointerSize;
9327 static const int kResourceDataOffset = kResourceOffset + kPointerSize;
9328 static const int kSize = kResourceDataOffset + kPointerSize;
9329
9330 // Return whether external string is short (data pointer is not cached).
9331 inline bool is_short();
Steve Blocka7e24c12009-10-30 11:49:00 +00009332
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009333 STATIC_ASSERT(kResourceOffset == Internals::kStringResourceOffset);
Steve Blocka7e24c12009-10-30 11:49:00 +00009334
9335 private:
9336 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalString);
9337};
9338
9339
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009340// The ExternalOneByteString class is an external string backed by an
9341// one-byte string.
9342class ExternalOneByteString : public ExternalString {
Steve Blocka7e24c12009-10-30 11:49:00 +00009343 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009344 static const bool kHasOneByteEncoding = true;
Leon Clarkeac952652010-07-15 11:15:24 +01009345
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009346 typedef v8::String::ExternalOneByteStringResource Resource;
Steve Blocka7e24c12009-10-30 11:49:00 +00009347
9348 // The underlying resource.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01009349 inline const Resource* resource();
9350 inline void set_resource(const Resource* buffer);
9351
9352 // Update the pointer cache to the external character array.
9353 // The cached pointer is always valid, as the external character array does =
9354 // not move during lifetime. Deserialization is the only exception, after
9355 // which the pointer cache has to be refreshed.
9356 inline void update_data_cache();
9357
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009358 inline const uint8_t* GetChars();
Steve Blocka7e24c12009-10-30 11:49:00 +00009359
9360 // Dispatched behavior.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009361 inline uint16_t ExternalOneByteStringGet(int index);
Steve Blocka7e24c12009-10-30 11:49:00 +00009362
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009363 DECLARE_CAST(ExternalOneByteString)
Steve Blocka7e24c12009-10-30 11:49:00 +00009364
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009365 class BodyDescriptor;
Steve Blocka7e24c12009-10-30 11:49:00 +00009366
Steve Blocka7e24c12009-10-30 11:49:00 +00009367 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009368 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalOneByteString);
Steve Blocka7e24c12009-10-30 11:49:00 +00009369};
9370
9371
9372// The ExternalTwoByteString class is an external string backed by a UTF-16
9373// encoded string.
9374class ExternalTwoByteString: public ExternalString {
9375 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009376 static const bool kHasOneByteEncoding = false;
Leon Clarkeac952652010-07-15 11:15:24 +01009377
Steve Blocka7e24c12009-10-30 11:49:00 +00009378 typedef v8::String::ExternalStringResource Resource;
9379
9380 // The underlying string resource.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01009381 inline const Resource* resource();
9382 inline void set_resource(const Resource* buffer);
9383
9384 // Update the pointer cache to the external character array.
9385 // The cached pointer is always valid, as the external character array does =
9386 // not move during lifetime. Deserialization is the only exception, after
9387 // which the pointer cache has to be refreshed.
9388 inline void update_data_cache();
9389
9390 inline const uint16_t* GetChars();
Steve Blocka7e24c12009-10-30 11:49:00 +00009391
9392 // Dispatched behavior.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01009393 inline uint16_t ExternalTwoByteStringGet(int index);
Steve Blocka7e24c12009-10-30 11:49:00 +00009394
9395 // For regexp code.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01009396 inline const uint16_t* ExternalTwoByteStringGetData(unsigned start);
Steve Blocka7e24c12009-10-30 11:49:00 +00009397
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009398 DECLARE_CAST(ExternalTwoByteString)
Steve Blocka7e24c12009-10-30 11:49:00 +00009399
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009400 class BodyDescriptor;
Iain Merrick75681382010-08-19 15:07:18 +01009401
Steve Blocka7e24c12009-10-30 11:49:00 +00009402 private:
9403 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalTwoByteString);
9404};
9405
9406
9407// Utility superclass for stack-allocated objects that must be updated
9408// on gc. It provides two ways for the gc to update instances, either
9409// iterating or updating after gc.
9410class Relocatable BASE_EMBEDDED {
9411 public:
Steve Block44f0eee2011-05-26 01:26:41 +01009412 explicit inline Relocatable(Isolate* isolate);
9413 inline virtual ~Relocatable();
Steve Blocka7e24c12009-10-30 11:49:00 +00009414 virtual void IterateInstance(ObjectVisitor* v) { }
9415 virtual void PostGarbageCollection() { }
9416
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009417 static void PostGarbageCollectionProcessing(Isolate* isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00009418 static int ArchiveSpacePerThread();
Ben Murdoch257744e2011-11-30 15:57:28 +00009419 static char* ArchiveState(Isolate* isolate, char* to);
9420 static char* RestoreState(Isolate* isolate, char* from);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009421 static void Iterate(Isolate* isolate, ObjectVisitor* v);
Steve Blocka7e24c12009-10-30 11:49:00 +00009422 static void Iterate(ObjectVisitor* v, Relocatable* top);
9423 static char* Iterate(ObjectVisitor* v, char* t);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009424
Steve Blocka7e24c12009-10-30 11:49:00 +00009425 private:
Steve Block44f0eee2011-05-26 01:26:41 +01009426 Isolate* isolate_;
Steve Blocka7e24c12009-10-30 11:49:00 +00009427 Relocatable* prev_;
9428};
9429
9430
9431// A flat string reader provides random access to the contents of a
9432// string independent of the character width of the string. The handle
9433// must be valid as long as the reader is being used.
9434class FlatStringReader : public Relocatable {
9435 public:
Steve Block44f0eee2011-05-26 01:26:41 +01009436 FlatStringReader(Isolate* isolate, Handle<String> str);
9437 FlatStringReader(Isolate* isolate, Vector<const char> input);
Steve Blocka7e24c12009-10-30 11:49:00 +00009438 void PostGarbageCollection();
9439 inline uc32 Get(int index);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04009440 template <typename Char>
9441 inline Char Get(int index);
Steve Blocka7e24c12009-10-30 11:49:00 +00009442 int length() { return length_; }
9443 private:
9444 String** str_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009445 bool is_one_byte_;
Steve Blocka7e24c12009-10-30 11:49:00 +00009446 int length_;
9447 const void* start_;
9448};
9449
9450
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009451// This maintains an off-stack representation of the stack frames required
9452// to traverse a ConsString, allowing an entirely iterative and restartable
9453// traversal of the entire string
Emily Bernierd0a1eb72015-03-24 16:35:39 -04009454class ConsStringIterator {
Steve Blocka7e24c12009-10-30 11:49:00 +00009455 public:
Emily Bernierd0a1eb72015-03-24 16:35:39 -04009456 inline ConsStringIterator() {}
9457 inline explicit ConsStringIterator(ConsString* cons_string, int offset = 0) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009458 Reset(cons_string, offset);
9459 }
9460 inline void Reset(ConsString* cons_string, int offset = 0) {
9461 depth_ = 0;
9462 // Next will always return NULL.
9463 if (cons_string == NULL) return;
9464 Initialize(cons_string, offset);
9465 }
9466 // Returns NULL when complete.
9467 inline String* Next(int* offset_out) {
9468 *offset_out = 0;
9469 if (depth_ == 0) return NULL;
9470 return Continue(offset_out);
9471 }
9472
9473 private:
9474 static const int kStackSize = 32;
9475 // Use a mask instead of doing modulo operations for stack wrapping.
9476 static const int kDepthMask = kStackSize-1;
9477 STATIC_ASSERT(IS_POWER_OF_TWO(kStackSize));
9478 static inline int OffsetForDepth(int depth);
9479
9480 inline void PushLeft(ConsString* string);
9481 inline void PushRight(ConsString* string);
9482 inline void AdjustMaximumDepth();
9483 inline void Pop();
9484 inline bool StackBlown() { return maximum_depth_ - depth_ == kStackSize; }
9485 void Initialize(ConsString* cons_string, int offset);
9486 String* Continue(int* offset_out);
9487 String* NextLeaf(bool* blew_stack);
9488 String* Search(int* offset_out);
9489
9490 // Stack must always contain only frames for which right traversal
9491 // has not yet been performed.
9492 ConsString* frames_[kStackSize];
9493 ConsString* root_;
9494 int depth_;
9495 int maximum_depth_;
9496 int consumed_;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04009497 DISALLOW_COPY_AND_ASSIGN(ConsStringIterator);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009498};
9499
9500
9501class StringCharacterStream {
9502 public:
9503 inline StringCharacterStream(String* string,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009504 int offset = 0);
9505 inline uint16_t GetNext();
9506 inline bool HasMore();
9507 inline void Reset(String* string, int offset = 0);
9508 inline void VisitOneByteString(const uint8_t* chars, int length);
9509 inline void VisitTwoByteString(const uint16_t* chars, int length);
9510
9511 private:
Emily Bernierd0a1eb72015-03-24 16:35:39 -04009512 ConsStringIterator iter_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009513 bool is_one_byte_;
9514 union {
9515 const uint8_t* buffer8_;
9516 const uint16_t* buffer16_;
9517 };
9518 const uint8_t* end_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009519 DISALLOW_COPY_AND_ASSIGN(StringCharacterStream);
Steve Blocka7e24c12009-10-30 11:49:00 +00009520};
9521
9522
9523template <typename T>
9524class VectorIterator {
9525 public:
9526 VectorIterator(T* d, int l) : data_(Vector<const T>(d, l)), index_(0) { }
9527 explicit VectorIterator(Vector<const T> data) : data_(data), index_(0) { }
9528 T GetNext() { return data_[index_++]; }
9529 bool has_more() { return index_ < data_.length(); }
9530 private:
9531 Vector<const T> data_;
9532 int index_;
9533};
9534
9535
9536// The Oddball describes objects null, undefined, true, and false.
9537class Oddball: public HeapObject {
9538 public:
Ben Murdochc5610432016-08-08 18:44:38 +01009539 // [to_number_raw]: Cached raw to_number computed at startup.
9540 inline double to_number_raw() const;
9541 inline void set_to_number_raw(double value);
9542
Steve Blocka7e24c12009-10-30 11:49:00 +00009543 // [to_string]: Cached to_string computed at startup.
9544 DECL_ACCESSORS(to_string, String)
9545
9546 // [to_number]: Cached to_number computed at startup.
9547 DECL_ACCESSORS(to_number, Object)
9548
Ben Murdochda12d292016-06-02 14:46:10 +01009549 // [to_number]: Cached to_boolean computed at startup.
9550 DECL_ACCESSORS(to_boolean, Oddball)
9551
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009552 // [typeof]: Cached type_of computed at startup.
9553 DECL_ACCESSORS(type_of, String)
9554
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009555 inline byte kind() const;
Steve Block44f0eee2011-05-26 01:26:41 +01009556 inline void set_kind(byte kind);
9557
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009558 // ES6 section 7.1.3 ToNumber for Boolean, Null, Undefined.
9559 MUST_USE_RESULT static inline Handle<Object> ToNumber(Handle<Oddball> input);
9560
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009561 DECLARE_CAST(Oddball)
Steve Blocka7e24c12009-10-30 11:49:00 +00009562
9563 // Dispatched behavior.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009564 DECLARE_VERIFIER(Oddball)
Steve Blocka7e24c12009-10-30 11:49:00 +00009565
9566 // Initialize the fields.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009567 static void Initialize(Isolate* isolate, Handle<Oddball> oddball,
9568 const char* to_string, Handle<Object> to_number,
Ben Murdochda12d292016-06-02 14:46:10 +01009569 bool to_boolean, const char* type_of, byte kind);
Steve Blocka7e24c12009-10-30 11:49:00 +00009570
9571 // Layout description.
Ben Murdochc5610432016-08-08 18:44:38 +01009572 static const int kToNumberRawOffset = HeapObject::kHeaderSize;
9573 static const int kToStringOffset = kToNumberRawOffset + kDoubleSize;
Steve Blocka7e24c12009-10-30 11:49:00 +00009574 static const int kToNumberOffset = kToStringOffset + kPointerSize;
Ben Murdochda12d292016-06-02 14:46:10 +01009575 static const int kToBooleanOffset = kToNumberOffset + kPointerSize;
9576 static const int kTypeOfOffset = kToBooleanOffset + kPointerSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009577 static const int kKindOffset = kTypeOfOffset + kPointerSize;
Steve Block44f0eee2011-05-26 01:26:41 +01009578 static const int kSize = kKindOffset + kPointerSize;
9579
9580 static const byte kFalse = 0;
9581 static const byte kTrue = 1;
9582 static const byte kNotBooleanMask = ~1;
9583 static const byte kTheHole = 2;
9584 static const byte kNull = 3;
Ben Murdoch097c5b22016-05-18 11:27:45 +01009585 static const byte kArgumentsMarker = 4;
Steve Block44f0eee2011-05-26 01:26:41 +01009586 static const byte kUndefined = 5;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009587 static const byte kUninitialized = 6;
9588 static const byte kOther = 7;
9589 static const byte kException = 8;
Ben Murdochda12d292016-06-02 14:46:10 +01009590 static const byte kOptimizedOut = 9;
Ben Murdochc5610432016-08-08 18:44:38 +01009591 static const byte kStaleRegister = 10;
Steve Blocka7e24c12009-10-30 11:49:00 +00009592
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009593 typedef FixedBodyDescriptor<kToStringOffset, kTypeOfOffset + kPointerSize,
Iain Merrick75681382010-08-19 15:07:18 +01009594 kSize> BodyDescriptor;
9595
Ben Murdochc5610432016-08-08 18:44:38 +01009596 STATIC_ASSERT(kToNumberRawOffset == HeapNumber::kValueOffset);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009597 STATIC_ASSERT(kKindOffset == Internals::kOddballKindOffset);
9598 STATIC_ASSERT(kNull == Internals::kNullOddballKind);
9599 STATIC_ASSERT(kUndefined == Internals::kUndefinedOddballKind);
9600
Steve Blocka7e24c12009-10-30 11:49:00 +00009601 private:
9602 DISALLOW_IMPLICIT_CONSTRUCTORS(Oddball);
9603};
9604
9605
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009606class Cell: public HeapObject {
Steve Blocka7e24c12009-10-30 11:49:00 +00009607 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009608 // [value]: value of the cell.
Steve Blocka7e24c12009-10-30 11:49:00 +00009609 DECL_ACCESSORS(value, Object)
9610
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009611 DECLARE_CAST(Cell)
Steve Blocka7e24c12009-10-30 11:49:00 +00009612
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009613 static inline Cell* FromValueAddress(Address value) {
9614 Object* result = FromAddress(value - kValueOffset);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009615 return static_cast<Cell*>(result);
Ben Murdochb0fe1622011-05-05 13:52:32 +01009616 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009617
9618 inline Address ValueAddress() {
9619 return address() + kValueOffset;
9620 }
9621
9622 // Dispatched behavior.
9623 DECLARE_PRINTER(Cell)
9624 DECLARE_VERIFIER(Cell)
Steve Blocka7e24c12009-10-30 11:49:00 +00009625
9626 // Layout description.
9627 static const int kValueOffset = HeapObject::kHeaderSize;
9628 static const int kSize = kValueOffset + kPointerSize;
9629
Iain Merrick75681382010-08-19 15:07:18 +01009630 typedef FixedBodyDescriptor<kValueOffset,
9631 kValueOffset + kPointerSize,
9632 kSize> BodyDescriptor;
9633
Steve Blocka7e24c12009-10-30 11:49:00 +00009634 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009635 DISALLOW_IMPLICIT_CONSTRUCTORS(Cell);
9636};
9637
9638
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009639class PropertyCell : public HeapObject {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009640 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009641 // [property_details]: details of the global property.
9642 DECL_ACCESSORS(property_details_raw, Object)
9643 // [value]: value of the global property.
9644 DECL_ACCESSORS(value, Object)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009645 // [dependent_code]: dependent code that depends on the type of the global
9646 // property.
9647 DECL_ACCESSORS(dependent_code, DependentCode)
9648
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009649 inline PropertyDetails property_details();
9650 inline void set_property_details(PropertyDetails details);
9651
9652 PropertyCellConstantType GetConstantType();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009653
9654 // Computes the new type of the cell's contents for the given value, but
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009655 // without actually modifying the details.
9656 static PropertyCellType UpdatedType(Handle<PropertyCell> cell,
9657 Handle<Object> value,
9658 PropertyDetails details);
9659 static void UpdateCell(Handle<GlobalDictionary> dictionary, int entry,
9660 Handle<Object> value, PropertyDetails details);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009661
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009662 static Handle<PropertyCell> InvalidateEntry(
9663 Handle<GlobalDictionary> dictionary, int entry);
9664
9665 static void SetValueWithInvalidation(Handle<PropertyCell> cell,
9666 Handle<Object> new_value);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009667
9668 DECLARE_CAST(PropertyCell)
9669
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009670 // Dispatched behavior.
9671 DECLARE_PRINTER(PropertyCell)
9672 DECLARE_VERIFIER(PropertyCell)
9673
9674 // Layout description.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009675 static const int kDetailsOffset = HeapObject::kHeaderSize;
9676 static const int kValueOffset = kDetailsOffset + kPointerSize;
9677 static const int kDependentCodeOffset = kValueOffset + kPointerSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009678 static const int kSize = kDependentCodeOffset + kPointerSize;
9679
9680 static const int kPointerFieldsBeginOffset = kValueOffset;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009681 static const int kPointerFieldsEndOffset = kSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009682
9683 typedef FixedBodyDescriptor<kValueOffset,
9684 kSize,
9685 kSize> BodyDescriptor;
9686
9687 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009688 DISALLOW_IMPLICIT_CONSTRUCTORS(PropertyCell);
Steve Blocka7e24c12009-10-30 11:49:00 +00009689};
9690
9691
Emily Bernierd0a1eb72015-03-24 16:35:39 -04009692class WeakCell : public HeapObject {
9693 public:
9694 inline Object* value() const;
9695
9696 // This should not be called by anyone except GC.
9697 inline void clear();
9698
9699 // This should not be called by anyone except allocator.
9700 inline void initialize(HeapObject* value);
9701
9702 inline bool cleared() const;
9703
9704 DECL_ACCESSORS(next, Object)
9705
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009706 inline void clear_next(Object* the_hole_value);
9707
9708 inline bool next_cleared();
9709
Emily Bernierd0a1eb72015-03-24 16:35:39 -04009710 DECLARE_CAST(WeakCell)
9711
9712 DECLARE_PRINTER(WeakCell)
9713 DECLARE_VERIFIER(WeakCell)
9714
9715 // Layout description.
9716 static const int kValueOffset = HeapObject::kHeaderSize;
9717 static const int kNextOffset = kValueOffset + kPointerSize;
9718 static const int kSize = kNextOffset + kPointerSize;
9719
9720 typedef FixedBodyDescriptor<kValueOffset, kSize, kSize> BodyDescriptor;
9721
9722 private:
9723 DISALLOW_IMPLICIT_CONSTRUCTORS(WeakCell);
9724};
9725
9726
Ben Murdoch257744e2011-11-30 15:57:28 +00009727// The JSProxy describes EcmaScript Harmony proxies
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00009728class JSProxy: public JSReceiver {
Steve Blocka7e24c12009-10-30 11:49:00 +00009729 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009730 MUST_USE_RESULT static MaybeHandle<JSProxy> New(Isolate* isolate,
9731 Handle<Object>,
9732 Handle<Object>);
9733
Ben Murdoch257744e2011-11-30 15:57:28 +00009734 // [handler]: The handler property.
9735 DECL_ACCESSORS(handler, Object)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009736 // [target]: The target property.
9737 DECL_ACCESSORS(target, JSReceiver)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01009738 // [hash]: The hash code property (undefined if not initialized yet).
9739 DECL_ACCESSORS(hash, Object)
9740
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009741 static MaybeHandle<Context> GetFunctionRealm(Handle<JSProxy> proxy);
9742
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009743 DECLARE_CAST(JSProxy)
Steve Blocka7e24c12009-10-30 11:49:00 +00009744
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009745 INLINE(bool IsRevoked() const);
9746 static void Revoke(Handle<JSProxy> proxy);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00009747
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009748 // ES6 9.5.1
9749 static MaybeHandle<Object> GetPrototype(Handle<JSProxy> receiver);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01009750
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009751 // ES6 9.5.2
9752 MUST_USE_RESULT static Maybe<bool> SetPrototype(Handle<JSProxy> proxy,
9753 Handle<Object> value,
9754 bool from_javascript,
9755 ShouldThrow should_throw);
9756 // ES6 9.5.3
9757 MUST_USE_RESULT static Maybe<bool> IsExtensible(Handle<JSProxy> proxy);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00009758
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009759 // ES6 9.5.4 (when passed DONT_THROW)
9760 MUST_USE_RESULT static Maybe<bool> PreventExtensions(
9761 Handle<JSProxy> proxy, ShouldThrow should_throw);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00009762
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009763 // ES6 9.5.5
9764 MUST_USE_RESULT static Maybe<bool> GetOwnPropertyDescriptor(
9765 Isolate* isolate, Handle<JSProxy> proxy, Handle<Name> name,
9766 PropertyDescriptor* desc);
Ben Murdoch589d6972011-11-30 16:04:58 +00009767
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009768 // ES6 9.5.6
9769 MUST_USE_RESULT static Maybe<bool> DefineOwnProperty(
9770 Isolate* isolate, Handle<JSProxy> object, Handle<Object> key,
9771 PropertyDescriptor* desc, ShouldThrow should_throw);
9772
9773 // ES6 9.5.7
9774 MUST_USE_RESULT static Maybe<bool> HasProperty(Isolate* isolate,
9775 Handle<JSProxy> proxy,
9776 Handle<Name> name);
9777
9778 // ES6 9.5.8
9779 MUST_USE_RESULT static MaybeHandle<Object> GetProperty(
9780 Isolate* isolate, Handle<JSProxy> proxy, Handle<Name> name,
Ben Murdochda12d292016-06-02 14:46:10 +01009781 Handle<Object> receiver, bool* was_found);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009782
9783 // ES6 9.5.9
9784 MUST_USE_RESULT static Maybe<bool> SetProperty(Handle<JSProxy> proxy,
9785 Handle<Name> name,
9786 Handle<Object> value,
9787 Handle<Object> receiver,
9788 LanguageMode language_mode);
9789
9790 // ES6 9.5.10 (when passed SLOPPY)
9791 MUST_USE_RESULT static Maybe<bool> DeletePropertyOrElement(
9792 Handle<JSProxy> proxy, Handle<Name> name, LanguageMode language_mode);
9793
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009794 // ES6 9.5.12
9795 MUST_USE_RESULT static Maybe<bool> OwnPropertyKeys(
9796 Isolate* isolate, Handle<JSReceiver> receiver, Handle<JSProxy> proxy,
9797 PropertyFilter filter, KeyAccumulator* accumulator);
9798
9799 MUST_USE_RESULT static Maybe<PropertyAttributes> GetPropertyAttributes(
9800 LookupIterator* it);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01009801
Steve Blocka7e24c12009-10-30 11:49:00 +00009802 // Dispatched behavior.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009803 DECLARE_PRINTER(JSProxy)
9804 DECLARE_VERIFIER(JSProxy)
Ben Murdoch257744e2011-11-30 15:57:28 +00009805
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009806 // Layout description.
9807 static const int kTargetOffset = JSReceiver::kHeaderSize;
9808 static const int kHandlerOffset = kTargetOffset + kPointerSize;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01009809 static const int kHashOffset = kHandlerOffset + kPointerSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009810 static const int kSize = kHashOffset + kPointerSize;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00009811
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009812 typedef FixedBodyDescriptor<JSReceiver::kPropertiesOffset, kSize, kSize>
9813 BodyDescriptor;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009814
Ben Murdoch61f157c2016-09-16 13:49:30 +01009815 static Object* GetIdentityHash(Handle<JSProxy> receiver);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009816
Ben Murdoch61f157c2016-09-16 13:49:30 +01009817 static Smi* GetOrCreateIdentityHash(Isolate* isolate, Handle<JSProxy> proxy);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009818
Ben Murdoch097c5b22016-05-18 11:27:45 +01009819 static Maybe<bool> SetPrivateProperty(Isolate* isolate, Handle<JSProxy> proxy,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009820 Handle<Symbol> private_name,
9821 PropertyDescriptor* desc,
9822 ShouldThrow should_throw);
9823
Ben Murdoch097c5b22016-05-18 11:27:45 +01009824 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009825 DISALLOW_IMPLICIT_CONSTRUCTORS(JSProxy);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00009826};
9827
Ben Murdoch257744e2011-11-30 15:57:28 +00009828
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009829class JSCollection : public JSObject {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01009830 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009831 // [table]: the backing hash table
Ben Murdoch3ef787d2012-04-12 10:51:47 +01009832 DECL_ACCESSORS(table, Object)
9833
Ben Murdoch3ef787d2012-04-12 10:51:47 +01009834 static const int kTableOffset = JSObject::kHeaderSize;
9835 static const int kSize = kTableOffset + kPointerSize;
9836
9837 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009838 DISALLOW_IMPLICIT_CONSTRUCTORS(JSCollection);
9839};
9840
9841
9842// The JSSet describes EcmaScript Harmony sets
9843class JSSet : public JSCollection {
9844 public:
9845 DECLARE_CAST(JSSet)
9846
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009847 static void Initialize(Handle<JSSet> set, Isolate* isolate);
9848 static void Clear(Handle<JSSet> set);
9849
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009850 // Dispatched behavior.
9851 DECLARE_PRINTER(JSSet)
9852 DECLARE_VERIFIER(JSSet)
9853
9854 private:
Ben Murdoch3ef787d2012-04-12 10:51:47 +01009855 DISALLOW_IMPLICIT_CONSTRUCTORS(JSSet);
9856};
9857
9858
9859// The JSMap describes EcmaScript Harmony maps
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009860class JSMap : public JSCollection {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01009861 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009862 DECLARE_CAST(JSMap)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01009863
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009864 static void Initialize(Handle<JSMap> map, Isolate* isolate);
9865 static void Clear(Handle<JSMap> map);
9866
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009867 // Dispatched behavior.
9868 DECLARE_PRINTER(JSMap)
9869 DECLARE_VERIFIER(JSMap)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01009870
9871 private:
9872 DISALLOW_IMPLICIT_CONSTRUCTORS(JSMap);
9873};
9874
9875
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009876// OrderedHashTableIterator is an iterator that iterates over the keys and
9877// values of an OrderedHashTable.
9878//
9879// The iterator has a reference to the underlying OrderedHashTable data,
9880// [table], as well as the current [index] the iterator is at.
9881//
9882// When the OrderedHashTable is rehashed it adds a reference from the old table
9883// to the new table as well as storing enough data about the changes so that the
9884// iterator [index] can be adjusted accordingly.
9885//
9886// When the [Next] result from the iterator is requested, the iterator checks if
9887// there is a newer table that it needs to transition to.
9888template<class Derived, class TableType>
9889class OrderedHashTableIterator: public JSObject {
9890 public:
9891 // [table]: the backing hash table mapping keys to values.
9892 DECL_ACCESSORS(table, Object)
9893
9894 // [index]: The index into the data table.
9895 DECL_ACCESSORS(index, Object)
9896
9897 // [kind]: The kind of iteration this is. One of the [Kind] enum values.
9898 DECL_ACCESSORS(kind, Object)
9899
9900#ifdef OBJECT_PRINT
Emily Bernierd0a1eb72015-03-24 16:35:39 -04009901 void OrderedHashTableIteratorPrint(std::ostream& os); // NOLINT
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009902#endif
9903
9904 static const int kTableOffset = JSObject::kHeaderSize;
9905 static const int kIndexOffset = kTableOffset + kPointerSize;
9906 static const int kKindOffset = kIndexOffset + kPointerSize;
9907 static const int kSize = kKindOffset + kPointerSize;
9908
9909 enum Kind {
9910 kKindKeys = 1,
9911 kKindValues = 2,
9912 kKindEntries = 3
9913 };
9914
9915 // Whether the iterator has more elements. This needs to be called before
9916 // calling |CurrentKey| and/or |CurrentValue|.
9917 bool HasMore();
9918
9919 // Move the index forward one.
9920 void MoveNext() {
9921 set_index(Smi::FromInt(Smi::cast(index())->value() + 1));
9922 }
9923
9924 // Populates the array with the next key and value and then moves the iterator
9925 // forward.
9926 // This returns the |kind| or 0 if the iterator is already at the end.
9927 Smi* Next(JSArray* value_array);
9928
9929 // Returns the current key of the iterator. This should only be called when
9930 // |HasMore| returns true.
9931 inline Object* CurrentKey();
9932
9933 private:
9934 // Transitions the iterator to the non obsolete backing store. This is a NOP
9935 // if the [table] is not obsolete.
9936 void Transition();
9937
9938 DISALLOW_IMPLICIT_CONSTRUCTORS(OrderedHashTableIterator);
9939};
9940
9941
9942class JSSetIterator: public OrderedHashTableIterator<JSSetIterator,
9943 OrderedHashSet> {
9944 public:
9945 // Dispatched behavior.
9946 DECLARE_PRINTER(JSSetIterator)
9947 DECLARE_VERIFIER(JSSetIterator)
9948
9949 DECLARE_CAST(JSSetIterator)
9950
9951 // Called by |Next| to populate the array. This allows the subclasses to
9952 // populate the array differently.
9953 inline void PopulateValueArray(FixedArray* array);
9954
9955 private:
9956 DISALLOW_IMPLICIT_CONSTRUCTORS(JSSetIterator);
9957};
9958
9959
9960class JSMapIterator: public OrderedHashTableIterator<JSMapIterator,
9961 OrderedHashMap> {
9962 public:
9963 // Dispatched behavior.
9964 DECLARE_PRINTER(JSMapIterator)
9965 DECLARE_VERIFIER(JSMapIterator)
9966
9967 DECLARE_CAST(JSMapIterator)
9968
9969 // Called by |Next| to populate the array. This allows the subclasses to
9970 // populate the array differently.
9971 inline void PopulateValueArray(FixedArray* array);
9972
9973 private:
9974 // Returns the current value of the iterator. This should only be called when
9975 // |HasMore| returns true.
9976 inline Object* CurrentValue();
9977
9978 DISALLOW_IMPLICIT_CONSTRUCTORS(JSMapIterator);
9979};
9980
9981
9982// Base class for both JSWeakMap and JSWeakSet
9983class JSWeakCollection: public JSObject {
Ben Murdoch69a99ed2011-11-30 16:03:39 +00009984 public:
9985 // [table]: the backing hash table mapping keys to values.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01009986 DECL_ACCESSORS(table, Object)
Ben Murdoch69a99ed2011-11-30 16:03:39 +00009987
9988 // [next]: linked list of encountered weak maps during GC.
9989 DECL_ACCESSORS(next, Object)
9990
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009991 static void Initialize(Handle<JSWeakCollection> collection, Isolate* isolate);
9992 static void Set(Handle<JSWeakCollection> collection, Handle<Object> key,
9993 Handle<Object> value, int32_t hash);
9994 static bool Delete(Handle<JSWeakCollection> collection, Handle<Object> key,
9995 int32_t hash);
9996
Ben Murdoch69a99ed2011-11-30 16:03:39 +00009997 static const int kTableOffset = JSObject::kHeaderSize;
9998 static const int kNextOffset = kTableOffset + kPointerSize;
9999 static const int kSize = kNextOffset + kPointerSize;
10000
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010001 // Visiting policy defines whether the table and next collection fields
10002 // should be visited or not.
10003 enum BodyVisitingPolicy { kVisitStrong, kVisitWeak };
10004
10005 // Iterates the function object according to the visiting policy.
10006 template <BodyVisitingPolicy>
10007 class BodyDescriptorImpl;
10008
10009 // Visit the whole object.
10010 typedef BodyDescriptorImpl<kVisitStrong> BodyDescriptor;
10011
10012 // Don't visit table and next collection fields.
10013 typedef BodyDescriptorImpl<kVisitWeak> BodyDescriptorWeak;
10014
Ben Murdoch69a99ed2011-11-30 16:03:39 +000010015 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010016 DISALLOW_IMPLICIT_CONSTRUCTORS(JSWeakCollection);
10017};
10018
10019
10020// The JSWeakMap describes EcmaScript Harmony weak maps
10021class JSWeakMap: public JSWeakCollection {
10022 public:
10023 DECLARE_CAST(JSWeakMap)
10024
10025 // Dispatched behavior.
10026 DECLARE_PRINTER(JSWeakMap)
10027 DECLARE_VERIFIER(JSWeakMap)
10028
10029 private:
Ben Murdoch69a99ed2011-11-30 16:03:39 +000010030 DISALLOW_IMPLICIT_CONSTRUCTORS(JSWeakMap);
10031};
10032
10033
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010034// The JSWeakSet describes EcmaScript Harmony weak sets
10035class JSWeakSet: public JSWeakCollection {
10036 public:
10037 DECLARE_CAST(JSWeakSet)
10038
10039 // Dispatched behavior.
10040 DECLARE_PRINTER(JSWeakSet)
10041 DECLARE_VERIFIER(JSWeakSet)
10042
10043 private:
10044 DISALLOW_IMPLICIT_CONSTRUCTORS(JSWeakSet);
10045};
10046
10047
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010048// Whether a JSArrayBuffer is a SharedArrayBuffer or not.
10049enum class SharedFlag { kNotShared, kShared };
10050
10051
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010052class JSArrayBuffer: public JSObject {
10053 public:
10054 // [backing_store]: backing memory for this array
10055 DECL_ACCESSORS(backing_store, void)
10056
10057 // [byte_length]: length in bytes
10058 DECL_ACCESSORS(byte_length, Object)
10059
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010060 inline uint32_t bit_field() const;
10061 inline void set_bit_field(uint32_t bits);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010062
10063 inline bool is_external();
10064 inline void set_is_external(bool value);
10065
Emily Bernierd0a1eb72015-03-24 16:35:39 -040010066 inline bool is_neuterable();
10067 inline void set_is_neuterable(bool value);
10068
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010069 inline bool was_neutered();
10070 inline void set_was_neutered(bool value);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010071
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010072 inline bool is_shared();
10073 inline void set_is_shared(bool value);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010074
10075 DECLARE_CAST(JSArrayBuffer)
10076
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010077 void Neuter();
10078
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010079 static void Setup(Handle<JSArrayBuffer> array_buffer, Isolate* isolate,
10080 bool is_external, void* data, size_t allocated_length,
10081 SharedFlag shared = SharedFlag::kNotShared);
10082
10083 static bool SetupAllocatingData(Handle<JSArrayBuffer> array_buffer,
10084 Isolate* isolate, size_t allocated_length,
10085 bool initialize = true,
10086 SharedFlag shared = SharedFlag::kNotShared);
10087
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010088 // Dispatched behavior.
10089 DECLARE_PRINTER(JSArrayBuffer)
10090 DECLARE_VERIFIER(JSArrayBuffer)
10091
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010092 static const int kByteLengthOffset = JSObject::kHeaderSize;
10093 static const int kBackingStoreOffset = kByteLengthOffset + kPointerSize;
10094 static const int kBitFieldSlot = kBackingStoreOffset + kPointerSize;
10095#if V8_TARGET_LITTLE_ENDIAN || !V8_HOST_ARCH_64_BIT
10096 static const int kBitFieldOffset = kBitFieldSlot;
10097#else
10098 static const int kBitFieldOffset = kBitFieldSlot + kIntSize;
10099#endif
10100 static const int kSize = kBitFieldSlot + kPointerSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010101
10102 static const int kSizeWithInternalFields =
10103 kSize + v8::ArrayBuffer::kInternalFieldCount * kPointerSize;
10104
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010105 // Iterates all fields in the object including internal ones except
10106 // kBackingStoreOffset and kBitFieldSlot.
10107 class BodyDescriptor;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010108
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010109 class IsExternal : public BitField<bool, 1, 1> {};
10110 class IsNeuterable : public BitField<bool, 2, 1> {};
10111 class WasNeutered : public BitField<bool, 3, 1> {};
10112 class IsShared : public BitField<bool, 4, 1> {};
10113
10114 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010115 DISALLOW_IMPLICIT_CONSTRUCTORS(JSArrayBuffer);
10116};
10117
10118
10119class JSArrayBufferView: public JSObject {
10120 public:
10121 // [buffer]: ArrayBuffer that this typed array views.
10122 DECL_ACCESSORS(buffer, Object)
10123
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010124 // [byte_offset]: offset of typed array in bytes.
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010125 DECL_ACCESSORS(byte_offset, Object)
10126
10127 // [byte_length]: length of typed array in bytes.
10128 DECL_ACCESSORS(byte_length, Object)
10129
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010130 DECLARE_CAST(JSArrayBufferView)
10131
10132 DECLARE_VERIFIER(JSArrayBufferView)
10133
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010134 inline bool WasNeutered() const;
10135
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010136 static const int kBufferOffset = JSObject::kHeaderSize;
10137 static const int kByteOffsetOffset = kBufferOffset + kPointerSize;
10138 static const int kByteLengthOffset = kByteOffsetOffset + kPointerSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010139 static const int kViewSize = kByteLengthOffset + kPointerSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010140
10141 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010142#ifdef VERIFY_HEAP
10143 DECL_ACCESSORS(raw_byte_offset, Object)
10144 DECL_ACCESSORS(raw_byte_length, Object)
10145#endif
10146
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010147 DISALLOW_IMPLICIT_CONSTRUCTORS(JSArrayBufferView);
10148};
10149
10150
10151class JSTypedArray: public JSArrayBufferView {
10152 public:
10153 // [length]: length of typed array in elements.
10154 DECL_ACCESSORS(length, Object)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010155 inline uint32_t length_value() const;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010156
10157 DECLARE_CAST(JSTypedArray)
10158
10159 ExternalArrayType type();
10160 size_t element_size();
10161
10162 Handle<JSArrayBuffer> GetBuffer();
10163
10164 // Dispatched behavior.
10165 DECLARE_PRINTER(JSTypedArray)
10166 DECLARE_VERIFIER(JSTypedArray)
10167
10168 static const int kLengthOffset = kViewSize + kPointerSize;
10169 static const int kSize = kLengthOffset + kPointerSize;
10170
10171 static const int kSizeWithInternalFields =
10172 kSize + v8::ArrayBufferView::kInternalFieldCount * kPointerSize;
10173
10174 private:
10175 static Handle<JSArrayBuffer> MaterializeArrayBuffer(
10176 Handle<JSTypedArray> typed_array);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010177#ifdef VERIFY_HEAP
10178 DECL_ACCESSORS(raw_length, Object)
10179#endif
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010180
10181 DISALLOW_IMPLICIT_CONSTRUCTORS(JSTypedArray);
10182};
10183
10184
10185class JSDataView: public JSArrayBufferView {
10186 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010187 DECLARE_CAST(JSDataView)
10188
10189 // Dispatched behavior.
10190 DECLARE_PRINTER(JSDataView)
10191 DECLARE_VERIFIER(JSDataView)
10192
10193 static const int kSize = kViewSize;
10194
10195 static const int kSizeWithInternalFields =
10196 kSize + v8::ArrayBufferView::kInternalFieldCount * kPointerSize;
10197
10198 private:
10199 DISALLOW_IMPLICIT_CONSTRUCTORS(JSDataView);
10200};
10201
10202
Ben Murdoch257744e2011-11-30 15:57:28 +000010203// Foreign describes objects pointing from JavaScript to C structures.
Ben Murdoch257744e2011-11-30 15:57:28 +000010204class Foreign: public HeapObject {
10205 public:
10206 // [address]: field containing the address.
Ben Murdoch3ef787d2012-04-12 10:51:47 +010010207 inline Address foreign_address();
10208 inline void set_foreign_address(Address value);
Ben Murdoch257744e2011-11-30 15:57:28 +000010209
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010210 DECLARE_CAST(Foreign)
Ben Murdoch257744e2011-11-30 15:57:28 +000010211
10212 // Dispatched behavior.
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010213 DECLARE_PRINTER(Foreign)
10214 DECLARE_VERIFIER(Foreign)
Steve Blocka7e24c12009-10-30 11:49:00 +000010215
10216 // Layout description.
10217
Ben Murdoch3ef787d2012-04-12 10:51:47 +010010218 static const int kForeignAddressOffset = HeapObject::kHeaderSize;
10219 static const int kSize = kForeignAddressOffset + kPointerSize;
Steve Blocka7e24c12009-10-30 11:49:00 +000010220
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010221 STATIC_ASSERT(kForeignAddressOffset == Internals::kForeignAddressOffset);
Steve Blocka7e24c12009-10-30 11:49:00 +000010222
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010223 class BodyDescriptor;
10224
Steve Blocka7e24c12009-10-30 11:49:00 +000010225 private:
Ben Murdoch257744e2011-11-30 15:57:28 +000010226 DISALLOW_IMPLICIT_CONSTRUCTORS(Foreign);
Steve Blocka7e24c12009-10-30 11:49:00 +000010227};
10228
10229
10230// The JSArray describes JavaScript Arrays
10231// Such an array can be in one of two modes:
10232// - fast, backing storage is a FixedArray and length <= elements.length();
10233// Please note: push and pop can be used to grow and shrink the array.
10234// - slow, backing storage is a HashTable with numbers as keys.
10235class JSArray: public JSObject {
10236 public:
10237 // [length]: The length property.
10238 DECL_ACCESSORS(length, Object)
10239
Leon Clarke4515c472010-02-03 11:58:03 +000010240 // Overload the length setter to skip write barrier when the length
10241 // is set to a smi. This matches the set function on FixedArray.
10242 inline void set_length(Smi* length);
10243
Emily Bernierd0a1eb72015-03-24 16:35:39 -040010244 static bool HasReadOnlyLength(Handle<JSArray> array);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010245 static bool WouldChangeReadOnlyLength(Handle<JSArray> array, uint32_t index);
Emily Bernierd0a1eb72015-03-24 16:35:39 -040010246
Steve Blocka7e24c12009-10-30 11:49:00 +000010247 // Initialize the array with the given capacity. The function may
10248 // fail due to out-of-memory situations, but only if the requested
10249 // capacity is non-zero.
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010250 static void Initialize(Handle<JSArray> array, int capacity, int length = 0);
Steve Blocka7e24c12009-10-30 11:49:00 +000010251
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010252 // If the JSArray has fast elements, and new_length would result in
10253 // normalization, returns true.
10254 bool SetLengthWouldNormalize(uint32_t new_length);
10255 static inline bool SetLengthWouldNormalize(Heap* heap, uint32_t new_length);
10256
Ben Murdoch3ef787d2012-04-12 10:51:47 +010010257 // Initializes the array to a certain length.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010258 inline bool AllowsSetLength();
10259
10260 static void SetLength(Handle<JSArray> array, uint32_t length);
Ben Murdoch3ef787d2012-04-12 10:51:47 +010010261
Steve Blocka7e24c12009-10-30 11:49:00 +000010262 // Set the content of the array to the content of storage.
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010263 static inline void SetContent(Handle<JSArray> array,
10264 Handle<FixedArrayBase> storage);
Steve Blocka7e24c12009-10-30 11:49:00 +000010265
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010266 // ES6 9.4.2.1
10267 MUST_USE_RESULT static Maybe<bool> DefineOwnProperty(
10268 Isolate* isolate, Handle<JSArray> o, Handle<Object> name,
10269 PropertyDescriptor* desc, ShouldThrow should_throw);
10270
10271 static bool AnythingToArrayLength(Isolate* isolate,
10272 Handle<Object> length_object,
10273 uint32_t* output);
10274 MUST_USE_RESULT static Maybe<bool> ArraySetLength(Isolate* isolate,
10275 Handle<JSArray> a,
10276 PropertyDescriptor* desc,
10277 ShouldThrow should_throw);
10278
Ben Murdochda12d292016-06-02 14:46:10 +010010279 // Checks whether the Array has the current realm's Array.prototype as its
10280 // prototype. This function is best-effort and only gives a conservative
10281 // approximation, erring on the side of false, in particular with respect
10282 // to Proxies and objects with a hidden prototype.
10283 inline bool HasArrayPrototype(Isolate* isolate);
10284
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010285 DECLARE_CAST(JSArray)
Steve Blocka7e24c12009-10-30 11:49:00 +000010286
Steve Blocka7e24c12009-10-30 11:49:00 +000010287 // Dispatched behavior.
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010288 DECLARE_PRINTER(JSArray)
10289 DECLARE_VERIFIER(JSArray)
Steve Blocka7e24c12009-10-30 11:49:00 +000010290
10291 // Number of element slots to pre-allocate for an empty array.
10292 static const int kPreallocatedArrayElements = 4;
10293
10294 // Layout description.
10295 static const int kLengthOffset = JSObject::kHeaderSize;
10296 static const int kSize = kLengthOffset + kPointerSize;
10297
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010298 // 600 * KB is the Page::kMaxRegularHeapObjectSize defined in spaces.h which
10299 // we do not want to include in objects.h
10300 // Note that Page::kMaxRegularHeapObjectSize has to be in sync with
10301 // kInitialMaxFastElementArray which is checked in a DCHECK in heap.cc.
10302 static const int kInitialMaxFastElementArray =
10303 (600 * KB - FixedArray::kHeaderSize - kSize - AllocationMemento::kSize) /
10304 kPointerSize;
10305
Steve Blocka7e24c12009-10-30 11:49:00 +000010306 private:
Steve Blocka7e24c12009-10-30 11:49:00 +000010307 DISALLOW_IMPLICIT_CONSTRUCTORS(JSArray);
10308};
10309
10310
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010311Handle<Object> CacheInitialJSArrayMaps(Handle<Context> native_context,
10312 Handle<Map> initial_map);
10313
10314
Steve Block6ded16b2010-05-10 14:33:55 +010010315// JSRegExpResult is just a JSArray with a specific initial map.
10316// This initial map adds in-object properties for "index" and "input"
10317// properties, as assigned by RegExp.prototype.exec, which allows
10318// faster creation of RegExp exec results.
10319// This class just holds constants used when creating the result.
10320// After creation the result must be treated as a JSArray in all regards.
10321class JSRegExpResult: public JSArray {
10322 public:
10323 // Offsets of object fields.
10324 static const int kIndexOffset = JSArray::kSize;
10325 static const int kInputOffset = kIndexOffset + kPointerSize;
10326 static const int kSize = kInputOffset + kPointerSize;
10327 // Indices of in-object properties.
10328 static const int kIndexIndex = 0;
10329 static const int kInputIndex = 1;
10330 private:
10331 DISALLOW_IMPLICIT_CONSTRUCTORS(JSRegExpResult);
10332};
10333
10334
Ben Murdoch097c5b22016-05-18 11:27:45 +010010335// An accessor must have a getter, but can have no setter.
10336//
10337// When setting a property, V8 searches accessors in prototypes.
10338// If an accessor was found and it does not have a setter,
10339// the request is ignored.
10340//
10341// If the accessor in the prototype has the READ_ONLY property attribute, then
10342// a new value is added to the derived object when the property is set.
10343// This shadows the accessor in the prototype.
Steve Blocka7e24c12009-10-30 11:49:00 +000010344class AccessorInfo: public Struct {
10345 public:
Steve Blocka7e24c12009-10-30 11:49:00 +000010346 DECL_ACCESSORS(name, Object)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010347 DECL_INT_ACCESSORS(flag)
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010348 DECL_ACCESSORS(expected_receiver_type, Object)
Ben Murdochc5610432016-08-08 18:44:38 +010010349 // This directly points at a foreign C function to be used from the runtime.
Ben Murdoch097c5b22016-05-18 11:27:45 +010010350 DECL_ACCESSORS(getter, Object)
10351 DECL_ACCESSORS(setter, Object)
Ben Murdochc5610432016-08-08 18:44:38 +010010352 // This either points at the same as above, or a trampoline in case we are
10353 // running with the simulator. Use these entries from generated code.
10354 DECL_ACCESSORS(js_getter, Object)
Ben Murdoch097c5b22016-05-18 11:27:45 +010010355 DECL_ACCESSORS(data, Object)
10356
Ben Murdochc5610432016-08-08 18:44:38 +010010357 static Address redirect(Isolate* isolate, Address address,
10358 AccessorComponent component);
10359 Address redirected_getter() const;
10360
Ben Murdoch097c5b22016-05-18 11:27:45 +010010361 // Dispatched behavior.
10362 DECLARE_PRINTER(AccessorInfo)
Steve Blocka7e24c12009-10-30 11:49:00 +000010363
10364 inline bool all_can_read();
10365 inline void set_all_can_read(bool value);
10366
10367 inline bool all_can_write();
10368 inline void set_all_can_write(bool value);
10369
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010370 inline bool is_special_data_property();
10371 inline void set_is_special_data_property(bool value);
10372
Ben Murdochda12d292016-06-02 14:46:10 +010010373 inline bool is_sloppy();
10374 inline void set_is_sloppy(bool value);
10375
Steve Blocka7e24c12009-10-30 11:49:00 +000010376 inline PropertyAttributes property_attributes();
10377 inline void set_property_attributes(PropertyAttributes attributes);
10378
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010379 // Checks whether the given receiver is compatible with this accessor.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010380 static bool IsCompatibleReceiverMap(Isolate* isolate,
10381 Handle<AccessorInfo> info,
10382 Handle<Map> map);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010383 inline bool IsCompatibleReceiver(Object* receiver);
Steve Blocka7e24c12009-10-30 11:49:00 +000010384
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010385 DECLARE_CAST(AccessorInfo)
Steve Blocka7e24c12009-10-30 11:49:00 +000010386
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010387 // Dispatched behavior.
10388 DECLARE_VERIFIER(AccessorInfo)
10389
10390 // Append all descriptors to the array that are not already there.
10391 // Return number added.
10392 static int AppendUnique(Handle<Object> descriptors,
10393 Handle<FixedArray> array,
10394 int valid_descriptors);
10395
10396 static const int kNameOffset = HeapObject::kHeaderSize;
Steve Blocka7e24c12009-10-30 11:49:00 +000010397 static const int kFlagOffset = kNameOffset + kPointerSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010398 static const int kExpectedReceiverTypeOffset = kFlagOffset + kPointerSize;
Ben Murdochc5610432016-08-08 18:44:38 +010010399 static const int kSetterOffset = kExpectedReceiverTypeOffset + kPointerSize;
10400 static const int kGetterOffset = kSetterOffset + kPointerSize;
10401 static const int kJsGetterOffset = kGetterOffset + kPointerSize;
10402 static const int kDataOffset = kJsGetterOffset + kPointerSize;
Ben Murdoch097c5b22016-05-18 11:27:45 +010010403 static const int kSize = kDataOffset + kPointerSize;
10404
Steve Blocka7e24c12009-10-30 11:49:00 +000010405
10406 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010407 inline bool HasExpectedReceiverType();
10408
Steve Blocka7e24c12009-10-30 11:49:00 +000010409 // Bit positions in flag.
10410 static const int kAllCanReadBit = 0;
10411 static const int kAllCanWriteBit = 1;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010412 static const int kSpecialDataProperty = 2;
Ben Murdochda12d292016-06-02 14:46:10 +010010413 static const int kIsSloppy = 3;
10414 class AttributesField : public BitField<PropertyAttributes, 4, 3> {};
Steve Blocka7e24c12009-10-30 11:49:00 +000010415
10416 DISALLOW_IMPLICIT_CONSTRUCTORS(AccessorInfo);
10417};
10418
10419
Ben Murdoch3ef787d2012-04-12 10:51:47 +010010420// Support for JavaScript accessors: A pair of a getter and a setter. Each
10421// accessor can either be
10422// * a pointer to a JavaScript function or proxy: a real accessor
10423// * undefined: considered an accessor by the spec, too, strangely enough
10424// * the hole: an accessor which has not been set
10425// * a pointer to a map: a transition used to ensure map sharing
10426class AccessorPair: public Struct {
10427 public:
10428 DECL_ACCESSORS(getter, Object)
10429 DECL_ACCESSORS(setter, Object)
10430
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010431 DECLARE_CAST(AccessorPair)
Ben Murdoch3ef787d2012-04-12 10:51:47 +010010432
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010433 static Handle<AccessorPair> Copy(Handle<AccessorPair> pair);
10434
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010435 inline Object* get(AccessorComponent component);
10436 inline void set(AccessorComponent component, Object* value);
Ben Murdoch3ef787d2012-04-12 10:51:47 +010010437
10438 // Note: Returns undefined instead in case of a hole.
Ben Murdoch097c5b22016-05-18 11:27:45 +010010439 static Handle<Object> GetComponent(Handle<AccessorPair> accessor_pair,
10440 AccessorComponent component);
Ben Murdoch3ef787d2012-04-12 10:51:47 +010010441
10442 // Set both components, skipping arguments which are a JavaScript null.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010443 inline void SetComponents(Object* getter, Object* setter);
Ben Murdoch3ef787d2012-04-12 10:51:47 +010010444
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010445 inline bool Equals(AccessorPair* pair);
10446 inline bool Equals(Object* getter_value, Object* setter_value);
10447
10448 inline bool ContainsAccessor();
Ben Murdoch3ef787d2012-04-12 10:51:47 +010010449
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010450 // Dispatched behavior.
10451 DECLARE_PRINTER(AccessorPair)
10452 DECLARE_VERIFIER(AccessorPair)
Ben Murdoch3ef787d2012-04-12 10:51:47 +010010453
10454 static const int kGetterOffset = HeapObject::kHeaderSize;
10455 static const int kSetterOffset = kGetterOffset + kPointerSize;
10456 static const int kSize = kSetterOffset + kPointerSize;
10457
10458 private:
10459 // Strangely enough, in addition to functions and harmony proxies, the spec
10460 // requires us to consider undefined as a kind of accessor, too:
10461 // var obj = {};
10462 // Object.defineProperty(obj, "foo", {get: undefined});
10463 // assertTrue("foo" in obj);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010464 inline bool IsJSAccessor(Object* obj);
Ben Murdoch3ef787d2012-04-12 10:51:47 +010010465
10466 DISALLOW_IMPLICIT_CONSTRUCTORS(AccessorPair);
10467};
10468
10469
Steve Blocka7e24c12009-10-30 11:49:00 +000010470class AccessCheckInfo: public Struct {
10471 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010472 DECL_ACCESSORS(callback, Object)
Ben Murdoch61f157c2016-09-16 13:49:30 +010010473 DECL_ACCESSORS(named_interceptor, Object)
10474 DECL_ACCESSORS(indexed_interceptor, Object)
Steve Blocka7e24c12009-10-30 11:49:00 +000010475 DECL_ACCESSORS(data, Object)
10476
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010477 DECLARE_CAST(AccessCheckInfo)
Steve Blocka7e24c12009-10-30 11:49:00 +000010478
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010479 // Dispatched behavior.
10480 DECLARE_PRINTER(AccessCheckInfo)
10481 DECLARE_VERIFIER(AccessCheckInfo)
Steve Blocka7e24c12009-10-30 11:49:00 +000010482
Ben Murdoch61f157c2016-09-16 13:49:30 +010010483 static AccessCheckInfo* Get(Isolate* isolate, Handle<JSObject> receiver);
10484
10485 static const int kCallbackOffset = HeapObject::kHeaderSize;
10486 static const int kNamedInterceptorOffset = kCallbackOffset + kPointerSize;
10487 static const int kIndexedInterceptorOffset =
10488 kNamedInterceptorOffset + kPointerSize;
10489 static const int kDataOffset = kIndexedInterceptorOffset + kPointerSize;
Steve Blocka7e24c12009-10-30 11:49:00 +000010490 static const int kSize = kDataOffset + kPointerSize;
10491
10492 private:
10493 DISALLOW_IMPLICIT_CONSTRUCTORS(AccessCheckInfo);
10494};
10495
10496
10497class InterceptorInfo: public Struct {
10498 public:
10499 DECL_ACCESSORS(getter, Object)
10500 DECL_ACCESSORS(setter, Object)
10501 DECL_ACCESSORS(query, Object)
10502 DECL_ACCESSORS(deleter, Object)
10503 DECL_ACCESSORS(enumerator, Object)
10504 DECL_ACCESSORS(data, Object)
Emily Bernierd0a1eb72015-03-24 16:35:39 -040010505 DECL_BOOLEAN_ACCESSORS(can_intercept_symbols)
10506 DECL_BOOLEAN_ACCESSORS(all_can_read)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010507 DECL_BOOLEAN_ACCESSORS(non_masking)
Emily Bernierd0a1eb72015-03-24 16:35:39 -040010508
10509 inline int flags() const;
10510 inline void set_flags(int flags);
Steve Blocka7e24c12009-10-30 11:49:00 +000010511
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010512 DECLARE_CAST(InterceptorInfo)
Steve Blocka7e24c12009-10-30 11:49:00 +000010513
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010514 // Dispatched behavior.
10515 DECLARE_PRINTER(InterceptorInfo)
10516 DECLARE_VERIFIER(InterceptorInfo)
Steve Blocka7e24c12009-10-30 11:49:00 +000010517
10518 static const int kGetterOffset = HeapObject::kHeaderSize;
10519 static const int kSetterOffset = kGetterOffset + kPointerSize;
10520 static const int kQueryOffset = kSetterOffset + kPointerSize;
10521 static const int kDeleterOffset = kQueryOffset + kPointerSize;
10522 static const int kEnumeratorOffset = kDeleterOffset + kPointerSize;
10523 static const int kDataOffset = kEnumeratorOffset + kPointerSize;
Emily Bernierd0a1eb72015-03-24 16:35:39 -040010524 static const int kFlagsOffset = kDataOffset + kPointerSize;
10525 static const int kSize = kFlagsOffset + kPointerSize;
10526
10527 static const int kCanInterceptSymbolsBit = 0;
10528 static const int kAllCanReadBit = 1;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010529 static const int kNonMasking = 2;
Steve Blocka7e24c12009-10-30 11:49:00 +000010530
10531 private:
10532 DISALLOW_IMPLICIT_CONSTRUCTORS(InterceptorInfo);
10533};
10534
10535
10536class CallHandlerInfo: public Struct {
10537 public:
10538 DECL_ACCESSORS(callback, Object)
10539 DECL_ACCESSORS(data, Object)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010540 DECL_ACCESSORS(fast_handler, Object)
Steve Blocka7e24c12009-10-30 11:49:00 +000010541
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010542 DECLARE_CAST(CallHandlerInfo)
Steve Blocka7e24c12009-10-30 11:49:00 +000010543
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010544 // Dispatched behavior.
10545 DECLARE_PRINTER(CallHandlerInfo)
10546 DECLARE_VERIFIER(CallHandlerInfo)
Steve Blocka7e24c12009-10-30 11:49:00 +000010547
10548 static const int kCallbackOffset = HeapObject::kHeaderSize;
10549 static const int kDataOffset = kCallbackOffset + kPointerSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010550 static const int kFastHandlerOffset = kDataOffset + kPointerSize;
10551 static const int kSize = kFastHandlerOffset + kPointerSize;
Steve Blocka7e24c12009-10-30 11:49:00 +000010552
10553 private:
10554 DISALLOW_IMPLICIT_CONSTRUCTORS(CallHandlerInfo);
10555};
10556
10557
10558class TemplateInfo: public Struct {
10559 public:
10560 DECL_ACCESSORS(tag, Object)
Ben Murdoch097c5b22016-05-18 11:27:45 +010010561 DECL_ACCESSORS(serial_number, Object)
10562 DECL_INT_ACCESSORS(number_of_properties)
Steve Blocka7e24c12009-10-30 11:49:00 +000010563 DECL_ACCESSORS(property_list, Object)
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010564 DECL_ACCESSORS(property_accessors, Object)
Steve Blocka7e24c12009-10-30 11:49:00 +000010565
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010566 DECLARE_VERIFIER(TemplateInfo)
Steve Blocka7e24c12009-10-30 11:49:00 +000010567
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010568 static const int kTagOffset = HeapObject::kHeaderSize;
Ben Murdoch097c5b22016-05-18 11:27:45 +010010569 static const int kSerialNumberOffset = kTagOffset + kPointerSize;
10570 static const int kNumberOfProperties = kSerialNumberOffset + kPointerSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010571 static const int kPropertyListOffset = kNumberOfProperties + kPointerSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010572 static const int kPropertyAccessorsOffset =
10573 kPropertyListOffset + kPointerSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010574 static const int kPropertyIntrinsicsOffset =
10575 kPropertyAccessorsOffset + kPointerSize;
10576 static const int kHeaderSize = kPropertyIntrinsicsOffset + kPointerSize;
Ben Murdoch3ef787d2012-04-12 10:51:47 +010010577
10578 private:
Steve Blocka7e24c12009-10-30 11:49:00 +000010579 DISALLOW_IMPLICIT_CONSTRUCTORS(TemplateInfo);
10580};
10581
10582
10583class FunctionTemplateInfo: public TemplateInfo {
10584 public:
Steve Blocka7e24c12009-10-30 11:49:00 +000010585 DECL_ACCESSORS(call_code, Object)
Steve Blocka7e24c12009-10-30 11:49:00 +000010586 DECL_ACCESSORS(prototype_template, Object)
10587 DECL_ACCESSORS(parent_template, Object)
10588 DECL_ACCESSORS(named_property_handler, Object)
10589 DECL_ACCESSORS(indexed_property_handler, Object)
10590 DECL_ACCESSORS(instance_template, Object)
10591 DECL_ACCESSORS(class_name, Object)
10592 DECL_ACCESSORS(signature, Object)
10593 DECL_ACCESSORS(instance_call_handler, Object)
10594 DECL_ACCESSORS(access_check_info, Object)
Ben Murdoch61f157c2016-09-16 13:49:30 +010010595 DECL_ACCESSORS(shared_function_info, Object)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010596 DECL_INT_ACCESSORS(flag)
Steve Blocka7e24c12009-10-30 11:49:00 +000010597
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010598 inline int length() const;
10599 inline void set_length(int value);
10600
Steve Blocka7e24c12009-10-30 11:49:00 +000010601 // Following properties use flag bits.
10602 DECL_BOOLEAN_ACCESSORS(hidden_prototype)
10603 DECL_BOOLEAN_ACCESSORS(undetectable)
10604 // If the bit is set, object instances created by this function
10605 // requires access check.
10606 DECL_BOOLEAN_ACCESSORS(needs_access_check)
Ben Murdoch69a99ed2011-11-30 16:03:39 +000010607 DECL_BOOLEAN_ACCESSORS(read_only_prototype)
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010608 DECL_BOOLEAN_ACCESSORS(remove_prototype)
10609 DECL_BOOLEAN_ACCESSORS(do_not_cache)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010610 DECL_BOOLEAN_ACCESSORS(accept_any_receiver)
Steve Blocka7e24c12009-10-30 11:49:00 +000010611
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010612 DECLARE_CAST(FunctionTemplateInfo)
Steve Blocka7e24c12009-10-30 11:49:00 +000010613
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010614 // Dispatched behavior.
10615 DECLARE_PRINTER(FunctionTemplateInfo)
10616 DECLARE_VERIFIER(FunctionTemplateInfo)
Steve Blocka7e24c12009-10-30 11:49:00 +000010617
Ben Murdoch097c5b22016-05-18 11:27:45 +010010618 static const int kCallCodeOffset = TemplateInfo::kHeaderSize;
Steve Blocka7e24c12009-10-30 11:49:00 +000010619 static const int kPrototypeTemplateOffset =
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010620 kCallCodeOffset + kPointerSize;
Steve Blocka7e24c12009-10-30 11:49:00 +000010621 static const int kParentTemplateOffset =
10622 kPrototypeTemplateOffset + kPointerSize;
10623 static const int kNamedPropertyHandlerOffset =
10624 kParentTemplateOffset + kPointerSize;
10625 static const int kIndexedPropertyHandlerOffset =
10626 kNamedPropertyHandlerOffset + kPointerSize;
10627 static const int kInstanceTemplateOffset =
10628 kIndexedPropertyHandlerOffset + kPointerSize;
10629 static const int kClassNameOffset = kInstanceTemplateOffset + kPointerSize;
10630 static const int kSignatureOffset = kClassNameOffset + kPointerSize;
10631 static const int kInstanceCallHandlerOffset = kSignatureOffset + kPointerSize;
10632 static const int kAccessCheckInfoOffset =
10633 kInstanceCallHandlerOffset + kPointerSize;
Ben Murdoch61f157c2016-09-16 13:49:30 +010010634 static const int kSharedFunctionInfoOffset =
10635 kAccessCheckInfoOffset + kPointerSize;
10636 static const int kFlagOffset = kSharedFunctionInfoOffset + kPointerSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010637 static const int kLengthOffset = kFlagOffset + kPointerSize;
10638 static const int kSize = kLengthOffset + kPointerSize;
10639
Ben Murdoch61f157c2016-09-16 13:49:30 +010010640 static Handle<SharedFunctionInfo> GetOrCreateSharedFunctionInfo(
10641 Isolate* isolate, Handle<FunctionTemplateInfo> info);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010642 // Returns true if |object| is an instance of this function template.
Ben Murdoch61f157c2016-09-16 13:49:30 +010010643 inline bool IsTemplateFor(JSObject* object);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010644 bool IsTemplateFor(Map* map);
Ben Murdoch61f157c2016-09-16 13:49:30 +010010645 inline bool instantiated();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010646
Steve Blocka7e24c12009-10-30 11:49:00 +000010647 private:
10648 // Bit position in the flag, from least significant bit position.
10649 static const int kHiddenPrototypeBit = 0;
10650 static const int kUndetectableBit = 1;
10651 static const int kNeedsAccessCheckBit = 2;
Ben Murdoch69a99ed2011-11-30 16:03:39 +000010652 static const int kReadOnlyPrototypeBit = 3;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010653 static const int kRemovePrototypeBit = 4;
10654 static const int kDoNotCacheBit = 5;
Ben Murdoch61f157c2016-09-16 13:49:30 +010010655 static const int kAcceptAnyReceiver = 6;
Steve Blocka7e24c12009-10-30 11:49:00 +000010656
10657 DISALLOW_IMPLICIT_CONSTRUCTORS(FunctionTemplateInfo);
10658};
10659
10660
10661class ObjectTemplateInfo: public TemplateInfo {
10662 public:
10663 DECL_ACCESSORS(constructor, Object)
10664 DECL_ACCESSORS(internal_field_count, Object)
10665
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010666 DECLARE_CAST(ObjectTemplateInfo)
Steve Blocka7e24c12009-10-30 11:49:00 +000010667
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010668 // Dispatched behavior.
10669 DECLARE_PRINTER(ObjectTemplateInfo)
10670 DECLARE_VERIFIER(ObjectTemplateInfo)
Steve Blocka7e24c12009-10-30 11:49:00 +000010671
10672 static const int kConstructorOffset = TemplateInfo::kHeaderSize;
10673 static const int kInternalFieldCountOffset =
10674 kConstructorOffset + kPointerSize;
10675 static const int kSize = kInternalFieldCountOffset + kPointerSize;
10676};
10677
10678
Steve Blocka7e24c12009-10-30 11:49:00 +000010679// The DebugInfo class holds additional information for a function being
10680// debugged.
10681class DebugInfo: public Struct {
10682 public:
10683 // The shared function info for the source being debugged.
10684 DECL_ACCESSORS(shared, SharedFunctionInfo)
Steve Blocka7e24c12009-10-30 11:49:00 +000010685 // Code object for the patched code. This code object is the code object
10686 // currently active for the function.
Ben Murdoch097c5b22016-05-18 11:27:45 +010010687 DECL_ACCESSORS(abstract_code, AbstractCode)
Steve Blocka7e24c12009-10-30 11:49:00 +000010688 // Fixed array holding status information for each active break point.
10689 DECL_ACCESSORS(break_points, FixedArray)
10690
Ben Murdoch097c5b22016-05-18 11:27:45 +010010691 // Check if there is a break point at a code offset.
10692 bool HasBreakPoint(int code_offset);
10693 // Get the break point info object for a code offset.
10694 Object* GetBreakPointInfo(int code_offset);
Steve Blocka7e24c12009-10-30 11:49:00 +000010695 // Clear a break point.
Ben Murdoch097c5b22016-05-18 11:27:45 +010010696 static void ClearBreakPoint(Handle<DebugInfo> debug_info, int code_offset,
Steve Blocka7e24c12009-10-30 11:49:00 +000010697 Handle<Object> break_point_object);
10698 // Set a break point.
Ben Murdoch097c5b22016-05-18 11:27:45 +010010699 static void SetBreakPoint(Handle<DebugInfo> debug_info, int code_offset,
Steve Blocka7e24c12009-10-30 11:49:00 +000010700 int source_position, int statement_position,
10701 Handle<Object> break_point_object);
Ben Murdoch097c5b22016-05-18 11:27:45 +010010702 // Get the break point objects for a code offset.
10703 Handle<Object> GetBreakPointObjects(int code_offset);
Steve Blocka7e24c12009-10-30 11:49:00 +000010704 // Find the break point info holding this break point object.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010705 static Handle<Object> FindBreakPointInfo(Handle<DebugInfo> debug_info,
10706 Handle<Object> break_point_object);
Steve Blocka7e24c12009-10-30 11:49:00 +000010707 // Get the number of break points for this function.
10708 int GetBreakPointCount();
10709
Ben Murdoch097c5b22016-05-18 11:27:45 +010010710 static Smi* uninitialized() { return Smi::FromInt(0); }
10711
10712 inline BytecodeArray* original_bytecode_array();
10713
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010714 DECLARE_CAST(DebugInfo)
Steve Blocka7e24c12009-10-30 11:49:00 +000010715
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010716 // Dispatched behavior.
10717 DECLARE_PRINTER(DebugInfo)
10718 DECLARE_VERIFIER(DebugInfo)
Steve Blocka7e24c12009-10-30 11:49:00 +000010719
10720 static const int kSharedFunctionInfoIndex = Struct::kHeaderSize;
Ben Murdoch097c5b22016-05-18 11:27:45 +010010721 static const int kAbstractCodeIndex = kSharedFunctionInfoIndex + kPointerSize;
10722 static const int kBreakPointsStateIndex = kAbstractCodeIndex + kPointerSize;
Steve Blocka7e24c12009-10-30 11:49:00 +000010723 static const int kSize = kBreakPointsStateIndex + kPointerSize;
10724
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010725 static const int kEstimatedNofBreakPointsInFunction = 16;
10726
Steve Blocka7e24c12009-10-30 11:49:00 +000010727 private:
10728 static const int kNoBreakPointInfo = -1;
10729
Ben Murdoch097c5b22016-05-18 11:27:45 +010010730 // Lookup the index in the break_points array for a code offset.
10731 int GetBreakPointInfoIndex(int code_offset);
Steve Blocka7e24c12009-10-30 11:49:00 +000010732
10733 DISALLOW_IMPLICIT_CONSTRUCTORS(DebugInfo);
10734};
10735
10736
10737// The BreakPointInfo class holds information for break points set in a
10738// function. The DebugInfo object holds a BreakPointInfo object for each code
10739// position with one or more break points.
10740class BreakPointInfo: public Struct {
10741 public:
Ben Murdoch097c5b22016-05-18 11:27:45 +010010742 // The code offset for the break point.
10743 DECL_INT_ACCESSORS(code_offset)
Steve Blocka7e24c12009-10-30 11:49:00 +000010744 // The position in the source for the break position.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010745 DECL_INT_ACCESSORS(source_position)
Steve Blocka7e24c12009-10-30 11:49:00 +000010746 // The position in the source for the last statement before this break
10747 // position.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010748 DECL_INT_ACCESSORS(statement_position)
Steve Blocka7e24c12009-10-30 11:49:00 +000010749 // List of related JavaScript break points.
10750 DECL_ACCESSORS(break_point_objects, Object)
10751
10752 // Removes a break point.
10753 static void ClearBreakPoint(Handle<BreakPointInfo> info,
10754 Handle<Object> break_point_object);
10755 // Set a break point.
10756 static void SetBreakPoint(Handle<BreakPointInfo> info,
10757 Handle<Object> break_point_object);
10758 // Check if break point info has this break point object.
10759 static bool HasBreakPointObject(Handle<BreakPointInfo> info,
10760 Handle<Object> break_point_object);
Ben Murdoch097c5b22016-05-18 11:27:45 +010010761 // Get the number of break points for this code offset.
Steve Blocka7e24c12009-10-30 11:49:00 +000010762 int GetBreakPointCount();
10763
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010764 DECLARE_CAST(BreakPointInfo)
Steve Blocka7e24c12009-10-30 11:49:00 +000010765
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010766 // Dispatched behavior.
10767 DECLARE_PRINTER(BreakPointInfo)
10768 DECLARE_VERIFIER(BreakPointInfo)
Steve Blocka7e24c12009-10-30 11:49:00 +000010769
Ben Murdoch097c5b22016-05-18 11:27:45 +010010770 static const int kCodeOffsetIndex = Struct::kHeaderSize;
10771 static const int kSourcePositionIndex = kCodeOffsetIndex + kPointerSize;
Steve Blocka7e24c12009-10-30 11:49:00 +000010772 static const int kStatementPositionIndex =
10773 kSourcePositionIndex + kPointerSize;
10774 static const int kBreakPointObjectsIndex =
10775 kStatementPositionIndex + kPointerSize;
10776 static const int kSize = kBreakPointObjectsIndex + kPointerSize;
10777
10778 private:
10779 DISALLOW_IMPLICIT_CONSTRUCTORS(BreakPointInfo);
10780};
Steve Blocka7e24c12009-10-30 11:49:00 +000010781
10782
10783#undef DECL_BOOLEAN_ACCESSORS
10784#undef DECL_ACCESSORS
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010785#undef DECLARE_CAST
10786#undef DECLARE_VERIFIER
Steve Blocka7e24c12009-10-30 11:49:00 +000010787
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010788#define VISITOR_SYNCHRONIZATION_TAGS_LIST(V) \
10789 V(kStringTable, "string_table", "(Internalized strings)") \
Ben Murdoch3ef787d2012-04-12 10:51:47 +010010790 V(kExternalStringsTable, "external_strings_table", "(External strings)") \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010791 V(kStrongRootList, "strong_root_list", "(Strong roots)") \
10792 V(kSmiRootList, "smi_root_list", "(Smi roots)") \
10793 V(kBootstrapper, "bootstrapper", "(Bootstrapper)") \
10794 V(kTop, "top", "(Isolate)") \
10795 V(kRelocatable, "relocatable", "(Relocatable)") \
10796 V(kDebug, "debug", "(Debugger)") \
10797 V(kCompilationCache, "compilationcache", "(Compilation cache)") \
10798 V(kHandleScope, "handlescope", "(Handle scope)") \
Ben Murdoch097c5b22016-05-18 11:27:45 +010010799 V(kDispatchTable, "dispatchtable", "(Dispatch table)") \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010800 V(kBuiltins, "builtins", "(Builtins)") \
10801 V(kGlobalHandles, "globalhandles", "(Global handles)") \
10802 V(kEternalHandles, "eternalhandles", "(Eternal handles)") \
10803 V(kThreadManager, "threadmanager", "(Thread manager)") \
10804 V(kStrongRoots, "strong roots", "(Strong roots)") \
Ben Murdoch3ef787d2012-04-12 10:51:47 +010010805 V(kExtensions, "Extensions", "(Extensions)")
10806
10807class VisitorSynchronization : public AllStatic {
10808 public:
10809#define DECLARE_ENUM(enum_item, ignore1, ignore2) enum_item,
10810 enum SyncTag {
10811 VISITOR_SYNCHRONIZATION_TAGS_LIST(DECLARE_ENUM)
10812 kNumberOfSyncTags
10813 };
10814#undef DECLARE_ENUM
10815
10816 static const char* const kTags[kNumberOfSyncTags];
10817 static const char* const kTagNames[kNumberOfSyncTags];
10818};
Steve Blocka7e24c12009-10-30 11:49:00 +000010819
10820// Abstract base class for visiting, and optionally modifying, the
10821// pointers contained in Objects. Used in GC and serialization/deserialization.
10822class ObjectVisitor BASE_EMBEDDED {
10823 public:
10824 virtual ~ObjectVisitor() {}
10825
10826 // Visits a contiguous arrays of pointers in the half-open range
10827 // [start, end). Any or all of the values may be modified on return.
10828 virtual void VisitPointers(Object** start, Object** end) = 0;
10829
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010830 // Handy shorthand for visiting a single pointer.
10831 virtual void VisitPointer(Object** p) { VisitPointers(p, p + 1); }
10832
10833 // Visit weak next_code_link in Code object.
10834 virtual void VisitNextCodeLink(Object** p) { VisitPointers(p, p + 1); }
10835
Steve Blocka7e24c12009-10-30 11:49:00 +000010836 // To allow lazy clearing of inline caches the visitor has
10837 // a rich interface for iterating over Code objects..
10838
10839 // Visits a code target in the instruction stream.
10840 virtual void VisitCodeTarget(RelocInfo* rinfo);
10841
Steve Block791712a2010-08-27 10:21:07 +010010842 // Visits a code entry in a JS function.
10843 virtual void VisitCodeEntry(Address entry_address);
10844
Ben Murdochb0fe1622011-05-05 13:52:32 +010010845 // Visits a global property cell reference in the instruction stream.
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010846 virtual void VisitCell(RelocInfo* rinfo);
Ben Murdochb0fe1622011-05-05 13:52:32 +010010847
Steve Blocka7e24c12009-10-30 11:49:00 +000010848 // Visits a runtime entry in the instruction stream.
10849 virtual void VisitRuntimeEntry(RelocInfo* rinfo) {}
10850
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010851 // Visits the resource of an one-byte or two-byte string.
10852 virtual void VisitExternalOneByteString(
10853 v8::String::ExternalOneByteStringResource** resource) {}
Steve Blockd0582a62009-12-15 09:54:21 +000010854 virtual void VisitExternalTwoByteString(
10855 v8::String::ExternalStringResource** resource) {}
10856
Steve Blocka7e24c12009-10-30 11:49:00 +000010857 // Visits a debug call target in the instruction stream.
10858 virtual void VisitDebugTarget(RelocInfo* rinfo);
10859
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010860 // Visits the byte sequence in a function's prologue that contains information
10861 // about the code's age.
10862 virtual void VisitCodeAgeSequence(RelocInfo* rinfo);
Steve Blocka7e24c12009-10-30 11:49:00 +000010863
Ben Murdoch3ef787d2012-04-12 10:51:47 +010010864 // Visit pointer embedded into a code object.
10865 virtual void VisitEmbeddedPointer(RelocInfo* rinfo);
10866
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010867 // Visits an external reference embedded into a code object.
Ben Murdoch3ef787d2012-04-12 10:51:47 +010010868 virtual void VisitExternalReference(RelocInfo* rinfo);
10869
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010870 // Visits an external reference.
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010871 virtual void VisitExternalReference(Address* p) {}
Steve Blocka7e24c12009-10-30 11:49:00 +000010872
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010873 // Visits an (encoded) internal reference.
10874 virtual void VisitInternalReference(RelocInfo* rinfo) {}
10875
Steve Block44f0eee2011-05-26 01:26:41 +010010876 // Visits a handle that has an embedder-assigned class ID.
10877 virtual void VisitEmbedderReference(Object** p, uint16_t class_id) {}
10878
Steve Blocka7e24c12009-10-30 11:49:00 +000010879 // Intended for serialization/deserialization checking: insert, or
10880 // check for the presence of, a tag at this position in the stream.
Ben Murdoch3ef787d2012-04-12 10:51:47 +010010881 // Also used for marking up GC roots in heap snapshots.
10882 virtual void Synchronize(VisitorSynchronization::SyncTag tag) {}
Steve Blocka7e24c12009-10-30 11:49:00 +000010883};
10884
10885
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010886// BooleanBit is a helper class for setting and getting a bit in an integer.
Steve Blocka7e24c12009-10-30 11:49:00 +000010887class BooleanBit : public AllStatic {
10888 public:
Steve Blocka7e24c12009-10-30 11:49:00 +000010889 static inline bool get(int value, int bit_position) {
10890 return (value & (1 << bit_position)) != 0;
10891 }
10892
Steve Blocka7e24c12009-10-30 11:49:00 +000010893 static inline int set(int value, int bit_position, bool v) {
10894 if (v) {
10895 value |= (1 << bit_position);
10896 } else {
10897 value &= ~(1 << bit_position);
10898 }
10899 return value;
10900 }
10901};
10902
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010903
10904} // NOLINT, false-positive due to second-order macros.
10905} // NOLINT, false-positive due to second-order macros.
Steve Blocka7e24c12009-10-30 11:49:00 +000010906
10907#endif // V8_OBJECTS_H_