blob: c55c5c978053de25b8ea0b80b89dc60ac3fa02e2 [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/allocation.h"
11#include "src/assert-scope.h"
12#include "src/bailout-reason.h"
13#include "src/base/bits.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000014#include "src/base/flags.h"
15#include "src/base/smart-pointers.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000016#include "src/builtins.h"
17#include "src/checks.h"
18#include "src/elements-kind.h"
19#include "src/field-index.h"
20#include "src/flags.h"
21#include "src/list.h"
22#include "src/property-details.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000023#include "src/unicode.h"
Emily Bernierd0a1eb72015-03-24 16:35:39 -040024#include "src/unicode-decoder.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000025#include "src/zone.h"
26
Steve Block3ce2e202009-11-05 08:53:23 +000027#if V8_TARGET_ARCH_ARM
Ben Murdochb8a8cc12014-11-26 15:28:44 +000028#include "src/arm/constants-arm.h" // NOLINT
29#elif V8_TARGET_ARCH_ARM64
30#include "src/arm64/constants-arm64.h" // NOLINT
Andrei Popescu31002712010-02-23 13:46:05 +000031#elif V8_TARGET_ARCH_MIPS
Ben Murdochb8a8cc12014-11-26 15:28:44 +000032#include "src/mips/constants-mips.h" // NOLINT
33#elif V8_TARGET_ARCH_MIPS64
34#include "src/mips64/constants-mips64.h" // NOLINT
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000035#elif V8_TARGET_ARCH_PPC
36#include "src/ppc/constants-ppc.h" // NOLINT
Steve Block3ce2e202009-11-05 08:53:23 +000037#endif
Ben Murdoch3ef787d2012-04-12 10:51:47 +010038
Steve Blocka7e24c12009-10-30 11:49:00 +000039
40//
Kristian Monsen50ef84f2010-07-29 15:18:00 +010041// Most object types in the V8 JavaScript are described in this file.
Steve Blocka7e24c12009-10-30 11:49:00 +000042//
43// Inheritance hierarchy:
Ben Murdochb8a8cc12014-11-26 15:28:44 +000044// - Object
45// - Smi (immediate small integer)
46// - HeapObject (superclass for everything allocated in the heap)
47// - JSReceiver (suitable for property access)
48// - JSObject
49// - JSArray
50// - JSArrayBuffer
51// - JSArrayBufferView
52// - JSTypedArray
53// - JSDataView
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000054// - JSBoundFunction
Ben Murdochb8a8cc12014-11-26 15:28:44 +000055// - JSCollection
Ben Murdoch3ef787d2012-04-12 10:51:47 +010056// - JSSet
57// - JSMap
Ben Murdochb8a8cc12014-11-26 15:28:44 +000058// - JSSetIterator
59// - JSMapIterator
60// - JSWeakCollection
Ben Murdoch69a99ed2011-11-30 16:03:39 +000061// - JSWeakMap
Ben Murdochb8a8cc12014-11-26 15:28:44 +000062// - JSWeakSet
63// - JSRegExp
64// - JSFunction
65// - JSGeneratorObject
66// - JSModule
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000067// - JSGlobalObject
Ben Murdochb8a8cc12014-11-26 15:28:44 +000068// - JSGlobalProxy
69// - JSValue
70// - JSDate
71// - JSMessageObject
72// - JSProxy
Ben Murdochb8a8cc12014-11-26 15:28:44 +000073// - FixedArrayBase
74// - ByteArray
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000075// - BytecodeArray
Ben Murdochb8a8cc12014-11-26 15:28:44 +000076// - FixedArray
77// - DescriptorArray
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000078// - LiteralsArray
Ben Murdochb8a8cc12014-11-26 15:28:44 +000079// - HashTable
80// - Dictionary
81// - StringTable
82// - CompilationCacheTable
83// - CodeCacheHashTable
84// - MapCache
85// - OrderedHashTable
86// - OrderedHashSet
87// - OrderedHashMap
88// - Context
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000089// - TypeFeedbackMetadata
Ben Murdochb8a8cc12014-11-26 15:28:44 +000090// - TypeFeedbackVector
Ben Murdochb8a8cc12014-11-26 15:28:44 +000091// - ScopeInfo
92// - TransitionArray
Emily Bernierd0a1eb72015-03-24 16:35:39 -040093// - ScriptContextTable
94// - WeakFixedArray
Ben Murdochb8a8cc12014-11-26 15:28:44 +000095// - FixedDoubleArray
Ben Murdochb8a8cc12014-11-26 15:28:44 +000096// - Name
Steve Blocka7e24c12009-10-30 11:49:00 +000097// - String
98// - SeqString
Ben Murdochb8a8cc12014-11-26 15:28:44 +000099// - SeqOneByteString
Steve Blocka7e24c12009-10-30 11:49:00 +0000100// - SeqTwoByteString
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000101// - SlicedString
Steve Blocka7e24c12009-10-30 11:49:00 +0000102// - ConsString
Steve Blocka7e24c12009-10-30 11:49:00 +0000103// - ExternalString
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000104// - ExternalOneByteString
Steve Blocka7e24c12009-10-30 11:49:00 +0000105// - ExternalTwoByteString
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000106// - InternalizedString
107// - SeqInternalizedString
108// - SeqOneByteInternalizedString
109// - SeqTwoByteInternalizedString
110// - ConsInternalizedString
111// - ExternalInternalizedString
112// - ExternalOneByteInternalizedString
113// - ExternalTwoByteInternalizedString
114// - Symbol
115// - HeapNumber
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000116// - Simd128Value
117// - Float32x4
118// - Int32x4
119// - Uint32x4
120// - Bool32x4
121// - Int16x8
122// - Uint16x8
123// - Bool16x8
124// - Int8x16
125// - Uint8x16
126// - Bool8x16
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000127// - Cell
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000128// - PropertyCell
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000129// - Code
130// - Map
131// - Oddball
132// - Foreign
133// - SharedFunctionInfo
134// - Struct
135// - Box
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000136// - AccessorInfo
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000137// - ExecutableAccessorInfo
138// - AccessorPair
139// - AccessCheckInfo
140// - InterceptorInfo
141// - CallHandlerInfo
142// - TemplateInfo
143// - FunctionTemplateInfo
144// - ObjectTemplateInfo
145// - Script
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000146// - DebugInfo
147// - BreakPointInfo
148// - CodeCache
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000149// - PrototypeInfo
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400150// - WeakCell
Steve Blocka7e24c12009-10-30 11:49:00 +0000151//
152// Formats of Object*:
153// Smi: [31 bit signed int] 0
154// HeapObject: [32 bit direct pointer] (4 byte aligned) | 01
Steve Blocka7e24c12009-10-30 11:49:00 +0000155
Steve Blocka7e24c12009-10-30 11:49:00 +0000156namespace v8 {
157namespace internal {
158
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000159enum KeyedAccessStoreMode {
160 STANDARD_STORE,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000161 STORE_TRANSITION_TO_OBJECT,
162 STORE_TRANSITION_TO_DOUBLE,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000163 STORE_AND_GROW_NO_TRANSITION,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000164 STORE_AND_GROW_TRANSITION_TO_OBJECT,
165 STORE_AND_GROW_TRANSITION_TO_DOUBLE,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000166 STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS,
167 STORE_NO_TRANSITION_HANDLE_COW
Ben Murdoch589d6972011-11-30 16:04:58 +0000168};
169
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000170
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000171// Valid hints for the abstract operation ToPrimitive,
172// implemented according to ES6, section 7.1.1.
173enum class ToPrimitiveHint { kDefault, kNumber, kString };
174
175
176// Valid hints for the abstract operation OrdinaryToPrimitive,
177// implemented according to ES6, section 7.1.1.
178enum class OrdinaryToPrimitiveHint { kNumber, kString };
179
180
181enum TypeofMode : int { INSIDE_TYPEOF, NOT_INSIDE_TYPEOF };
Ben Murdochc7cc0282012-03-05 14:35:55 +0000182
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000183
184enum MutableMode {
185 MUTABLE,
186 IMMUTABLE
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100187};
188
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100189
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000190enum ExternalArrayType {
191 kExternalInt8Array = 1,
192 kExternalUint8Array,
193 kExternalInt16Array,
194 kExternalUint16Array,
195 kExternalInt32Array,
196 kExternalUint32Array,
197 kExternalFloat32Array,
198 kExternalFloat64Array,
199 kExternalUint8ClampedArray,
200};
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000201
202
203static inline bool IsTransitionStoreMode(KeyedAccessStoreMode store_mode) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000204 return store_mode == STORE_TRANSITION_TO_OBJECT ||
205 store_mode == STORE_TRANSITION_TO_DOUBLE ||
206 store_mode == STORE_AND_GROW_TRANSITION_TO_OBJECT ||
207 store_mode == STORE_AND_GROW_TRANSITION_TO_DOUBLE;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000208}
209
210
211static inline KeyedAccessStoreMode GetNonTransitioningStoreMode(
212 KeyedAccessStoreMode store_mode) {
213 if (store_mode >= STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) {
214 return store_mode;
215 }
216 if (store_mode >= STORE_AND_GROW_NO_TRANSITION) {
217 return STORE_AND_GROW_NO_TRANSITION;
218 }
219 return STANDARD_STORE;
220}
221
222
223static inline bool IsGrowStoreMode(KeyedAccessStoreMode store_mode) {
224 return store_mode >= STORE_AND_GROW_NO_TRANSITION &&
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000225 store_mode <= STORE_AND_GROW_TRANSITION_TO_DOUBLE;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000226}
227
Steve Blocka7e24c12009-10-30 11:49:00 +0000228
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400229enum IcCheckType { ELEMENT, PROPERTY };
230
231
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000232// SKIP_WRITE_BARRIER skips the write barrier.
233// UPDATE_WEAK_WRITE_BARRIER skips the marking part of the write barrier and
234// only performs the generational part.
235// UPDATE_WRITE_BARRIER is doing the full barrier, marking and generational.
236enum WriteBarrierMode {
237 SKIP_WRITE_BARRIER,
238 UPDATE_WEAK_WRITE_BARRIER,
239 UPDATE_WRITE_BARRIER
240};
Steve Blocka7e24c12009-10-30 11:49:00 +0000241
242
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000243// Indicates whether a value can be loaded as a constant.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000244enum StoreMode { ALLOW_IN_DESCRIPTOR, FORCE_FIELD };
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000245
246
Steve Blocka7e24c12009-10-30 11:49:00 +0000247// PropertyNormalizationMode is used to specify whether to keep
248// inobject properties when normalizing properties of a JSObject.
249enum PropertyNormalizationMode {
250 CLEAR_INOBJECT_PROPERTIES,
251 KEEP_INOBJECT_PROPERTIES
252};
253
254
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000255// Indicates how aggressively the prototype should be optimized. FAST_PROTOTYPE
256// will give the fastest result by tailoring the map to the prototype, but that
257// will cause polymorphism with other objects. REGULAR_PROTOTYPE is to be used
258// (at least for now) when dynamically modifying the prototype chain of an
259// object using __proto__ or Object.setPrototypeOf.
260enum PrototypeOptimizationMode { REGULAR_PROTOTYPE, FAST_PROTOTYPE };
261
262
263// Indicates whether transitions can be added to a source map or not.
264enum TransitionFlag {
265 INSERT_TRANSITION,
266 OMIT_TRANSITION
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100267};
268
269
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000270// Indicates whether the transition is simple: the target map of the transition
271// either extends the current map with a new property, or it modifies the
272// property that was added last to the current map.
273enum SimpleTransitionFlag {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400274 SIMPLE_PROPERTY_TRANSITION,
275 PROPERTY_TRANSITION,
276 SPECIAL_TRANSITION
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000277};
278
279
280// Indicates whether we are only interested in the descriptors of a particular
281// map, or in all descriptors in the descriptor array.
282enum DescriptorFlag {
283 ALL_DESCRIPTORS,
284 OWN_DESCRIPTORS
285};
286
287// The GC maintains a bit of information, the MarkingParity, which toggles
288// from odd to even and back every time marking is completed. Incremental
289// marking can visit an object twice during a marking phase, so algorithms that
290// that piggy-back on marking can use the parity to ensure that they only
291// perform an operation on an object once per marking phase: they record the
292// MarkingParity when they visit an object, and only re-visit the object when it
293// is marked again and the MarkingParity changes.
294enum MarkingParity {
295 NO_MARKING_PARITY,
296 ODD_MARKING_PARITY,
297 EVEN_MARKING_PARITY
298};
299
300// ICs store extra state in a Code object. The default extra state is
301// kNoExtraICState.
302typedef int ExtraICState;
303static const ExtraICState kNoExtraICState = 0;
304
Steve Block791712a2010-08-27 10:21:07 +0100305// Instance size sentinel for objects of variable size.
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100306const int kVariableSizeSentinel = 0;
Steve Block791712a2010-08-27 10:21:07 +0100307
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000308// We may store the unsigned bit field as signed Smi value and do not
309// use the sign bit.
310const int kStubMajorKeyBits = 7;
311const int kStubMinorKeyBits = kSmiValueSize - kStubMajorKeyBits - 1;
Steve Block791712a2010-08-27 10:21:07 +0100312
Steve Blocka7e24c12009-10-30 11:49:00 +0000313// All Maps have a field instance_type containing a InstanceType.
314// It describes the type of the instances.
315//
316// As an example, a JavaScript object is a heap object and its map
317// instance_type is JS_OBJECT_TYPE.
318//
319// The names of the string instance types are intended to systematically
Leon Clarkee46be812010-01-19 14:06:41 +0000320// mirror their encoding in the instance_type field of the map. The default
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000321// encoding is considered TWO_BYTE. It is not mentioned in the name. ONE_BYTE
Leon Clarkee46be812010-01-19 14:06:41 +0000322// encoding is mentioned explicitly in the name. Likewise, the default
323// representation is considered sequential. It is not mentioned in the
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100324// name. The other representations (e.g. CONS, EXTERNAL) are explicitly
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000325// mentioned. Finally, the string is either a STRING_TYPE (if it is a normal
326// string) or a INTERNALIZED_STRING_TYPE (if it is a internalized string).
Steve Blocka7e24c12009-10-30 11:49:00 +0000327//
328// NOTE: The following things are some that depend on the string types having
329// instance_types that are less than those of all other types:
330// HeapObject::Size, HeapObject::IterateBody, the typeof operator, and
331// Object::IsString.
332//
333// NOTE: Everything following JS_VALUE_TYPE is considered a
334// JSObject for GC purposes. The first four entries here have typeof
335// 'object', whereas JS_FUNCTION_TYPE has typeof 'function'.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000336#define INSTANCE_TYPE_LIST(V) \
337 V(STRING_TYPE) \
338 V(ONE_BYTE_STRING_TYPE) \
339 V(CONS_STRING_TYPE) \
340 V(CONS_ONE_BYTE_STRING_TYPE) \
341 V(SLICED_STRING_TYPE) \
342 V(SLICED_ONE_BYTE_STRING_TYPE) \
343 V(EXTERNAL_STRING_TYPE) \
344 V(EXTERNAL_ONE_BYTE_STRING_TYPE) \
345 V(EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE) \
346 V(SHORT_EXTERNAL_STRING_TYPE) \
347 V(SHORT_EXTERNAL_ONE_BYTE_STRING_TYPE) \
348 V(SHORT_EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE) \
349 \
350 V(INTERNALIZED_STRING_TYPE) \
351 V(ONE_BYTE_INTERNALIZED_STRING_TYPE) \
352 V(EXTERNAL_INTERNALIZED_STRING_TYPE) \
353 V(EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE) \
354 V(EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE) \
355 V(SHORT_EXTERNAL_INTERNALIZED_STRING_TYPE) \
356 V(SHORT_EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE) \
357 V(SHORT_EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE) \
358 \
359 V(SYMBOL_TYPE) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000360 V(SIMD128_VALUE_TYPE) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000361 \
362 V(MAP_TYPE) \
363 V(CODE_TYPE) \
364 V(ODDBALL_TYPE) \
365 V(CELL_TYPE) \
366 V(PROPERTY_CELL_TYPE) \
367 \
368 V(HEAP_NUMBER_TYPE) \
369 V(MUTABLE_HEAP_NUMBER_TYPE) \
370 V(FOREIGN_TYPE) \
371 V(BYTE_ARRAY_TYPE) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000372 V(BYTECODE_ARRAY_TYPE) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000373 V(FREE_SPACE_TYPE) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000374 \
375 V(FIXED_INT8_ARRAY_TYPE) \
376 V(FIXED_UINT8_ARRAY_TYPE) \
377 V(FIXED_INT16_ARRAY_TYPE) \
378 V(FIXED_UINT16_ARRAY_TYPE) \
379 V(FIXED_INT32_ARRAY_TYPE) \
380 V(FIXED_UINT32_ARRAY_TYPE) \
381 V(FIXED_FLOAT32_ARRAY_TYPE) \
382 V(FIXED_FLOAT64_ARRAY_TYPE) \
383 V(FIXED_UINT8_CLAMPED_ARRAY_TYPE) \
384 \
385 V(FILLER_TYPE) \
386 \
387 V(DECLARED_ACCESSOR_DESCRIPTOR_TYPE) \
388 V(DECLARED_ACCESSOR_INFO_TYPE) \
389 V(EXECUTABLE_ACCESSOR_INFO_TYPE) \
390 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) \
401 V(CODE_CACHE_TYPE) \
402 V(POLYMORPHIC_CODE_CACHE_TYPE) \
403 V(TYPE_FEEDBACK_INFO_TYPE) \
404 V(ALIASED_ARGUMENTS_ENTRY_TYPE) \
405 V(BOX_TYPE) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000406 V(PROTOTYPE_INFO_TYPE) \
407 V(SLOPPY_BLOCK_WITH_EVAL_CONTEXT_EXTENSION_TYPE) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000408 \
409 V(FIXED_ARRAY_TYPE) \
410 V(FIXED_DOUBLE_ARRAY_TYPE) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000411 V(SHARED_FUNCTION_INFO_TYPE) \
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400412 V(WEAK_CELL_TYPE) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000413 V(TRANSITION_ARRAY_TYPE) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000414 \
415 V(JS_MESSAGE_OBJECT_TYPE) \
416 \
417 V(JS_VALUE_TYPE) \
418 V(JS_DATE_TYPE) \
419 V(JS_OBJECT_TYPE) \
420 V(JS_CONTEXT_EXTENSION_OBJECT_TYPE) \
421 V(JS_GENERATOR_OBJECT_TYPE) \
422 V(JS_MODULE_TYPE) \
423 V(JS_GLOBAL_OBJECT_TYPE) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000424 V(JS_GLOBAL_PROXY_TYPE) \
425 V(JS_ARRAY_TYPE) \
426 V(JS_ARRAY_BUFFER_TYPE) \
427 V(JS_TYPED_ARRAY_TYPE) \
428 V(JS_DATA_VIEW_TYPE) \
429 V(JS_PROXY_TYPE) \
430 V(JS_SET_TYPE) \
431 V(JS_MAP_TYPE) \
432 V(JS_SET_ITERATOR_TYPE) \
433 V(JS_MAP_ITERATOR_TYPE) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000434 V(JS_ITERATOR_RESULT_TYPE) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000435 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) \
439 \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000440 V(JS_BOUND_FUNCTION_TYPE) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000441 V(JS_FUNCTION_TYPE) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000442 V(DEBUG_INFO_TYPE) \
Steve Blocka7e24c12009-10-30 11:49:00 +0000443 V(BREAK_POINT_INFO_TYPE)
Steve Blocka7e24c12009-10-30 11:49:00 +0000444
445
446// 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) \
508 V(EXECUTABLE_ACCESSOR_INFO, ExecutableAccessorInfo, \
509 executable_accessor_info) \
510 V(ACCESSOR_PAIR, AccessorPair, accessor_pair) \
511 V(ACCESS_CHECK_INFO, AccessCheckInfo, access_check_info) \
512 V(INTERCEPTOR_INFO, InterceptorInfo, interceptor_info) \
513 V(CALL_HANDLER_INFO, CallHandlerInfo, call_handler_info) \
514 V(FUNCTION_TEMPLATE_INFO, FunctionTemplateInfo, function_template_info) \
515 V(OBJECT_TEMPLATE_INFO, ObjectTemplateInfo, object_template_info) \
516 V(SCRIPT, Script, script) \
517 V(ALLOCATION_SITE, AllocationSite, allocation_site) \
518 V(ALLOCATION_MEMENTO, AllocationMemento, allocation_memento) \
519 V(CODE_CACHE, CodeCache, code_cache) \
520 V(POLYMORPHIC_CODE_CACHE, PolymorphicCodeCache, polymorphic_code_cache) \
521 V(TYPE_FEEDBACK_INFO, TypeFeedbackInfo, type_feedback_info) \
522 V(ALIASED_ARGUMENTS_ENTRY, AliasedArgumentsEntry, aliased_arguments_entry) \
523 V(DEBUG_INFO, DebugInfo, debug_info) \
524 V(BREAK_POINT_INFO, BreakPointInfo, break_point_info) \
525 V(PROTOTYPE_INFO, PrototypeInfo, prototype_info) \
526 V(SLOPPY_BLOCK_WITH_EVAL_CONTEXT_EXTENSION, \
527 SloppyBlockWithEvalContextExtension, \
528 sloppy_block_with_eval_context_extension)
Steve Blocka7e24c12009-10-30 11:49:00 +0000529
530// We use the full 8 bits of the instance_type field to encode heap object
531// instance types. The high-order bit (bit 7) is set if the object is not a
532// string, and cleared if it is a string.
533const uint32_t kIsNotStringMask = 0x80;
534const uint32_t kStringTag = 0x0;
535const uint32_t kNotStringTag = 0x80;
536
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000537// Bit 6 indicates that the object is an internalized string (if set) or not.
538// Bit 7 has to be clear as well.
539const uint32_t kIsNotInternalizedMask = 0x40;
540const uint32_t kNotInternalizedTag = 0x40;
541const uint32_t kInternalizedTag = 0x0;
Steve Blocka7e24c12009-10-30 11:49:00 +0000542
Steve Blocka7e24c12009-10-30 11:49:00 +0000543// If bit 7 is clear then bit 2 indicates whether the string consists of
544// two-byte characters or one-byte characters.
545const uint32_t kStringEncodingMask = 0x4;
546const uint32_t kTwoByteStringTag = 0x0;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000547const uint32_t kOneByteStringTag = 0x4;
Steve Blocka7e24c12009-10-30 11:49:00 +0000548
549// If bit 7 is clear, the low-order 2 bits indicate the representation
550// of the string.
551const uint32_t kStringRepresentationMask = 0x03;
552enum StringRepresentationTag {
553 kSeqStringTag = 0x0,
554 kConsStringTag = 0x1,
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000555 kExternalStringTag = 0x2,
556 kSlicedStringTag = 0x3
Steve Blocka7e24c12009-10-30 11:49:00 +0000557};
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000558const uint32_t kIsIndirectStringMask = 0x1;
559const uint32_t kIsIndirectStringTag = 0x1;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000560STATIC_ASSERT((kSeqStringTag & kIsIndirectStringMask) == 0); // NOLINT
561STATIC_ASSERT((kExternalStringTag & kIsIndirectStringMask) == 0); // NOLINT
562STATIC_ASSERT((kConsStringTag &
563 kIsIndirectStringMask) == kIsIndirectStringTag); // NOLINT
564STATIC_ASSERT((kSlicedStringTag &
565 kIsIndirectStringMask) == kIsIndirectStringTag); // NOLINT
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000566
567// Use this mask to distinguish between cons and slice only after making
568// sure that the string is one of the two (an indirect string).
569const uint32_t kSlicedNotConsMask = kSlicedStringTag & ~kConsStringTag;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000570STATIC_ASSERT(IS_POWER_OF_TWO(kSlicedNotConsMask));
Steve Blocka7e24c12009-10-30 11:49:00 +0000571
Kristian Monsen9dcf7e22010-06-28 14:14:28 +0100572// If bit 7 is clear, then bit 3 indicates whether this two-byte
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000573// string actually contains one byte data.
574const uint32_t kOneByteDataHintMask = 0x08;
575const uint32_t kOneByteDataHintTag = 0x08;
Kristian Monsen9dcf7e22010-06-28 14:14:28 +0100576
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100577// If bit 7 is clear and string representation indicates an external string,
578// then bit 4 indicates whether the data pointer is cached.
579const uint32_t kShortExternalStringMask = 0x10;
580const uint32_t kShortExternalStringTag = 0x10;
581
Steve Blocka7e24c12009-10-30 11:49:00 +0000582
583// A ConsString with an empty string as the right side is a candidate
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000584// for being shortcut by the garbage collector. We don't allocate any
585// non-flat internalized strings, so we do not shortcut them thereby
586// avoiding turning internalized strings into strings. The bit-masks
587// below contain the internalized bit as additional safety.
588// See heap.cc, mark-compact.cc and objects-visiting.cc.
Steve Blocka7e24c12009-10-30 11:49:00 +0000589const uint32_t kShortcutTypeMask =
590 kIsNotStringMask |
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000591 kIsNotInternalizedMask |
Steve Blocka7e24c12009-10-30 11:49:00 +0000592 kStringRepresentationMask;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000593const uint32_t kShortcutTypeTag = kConsStringTag | kNotInternalizedTag;
594
595static inline bool IsShortcutCandidate(int type) {
596 return ((type & kShortcutTypeMask) == kShortcutTypeTag);
597}
Steve Blocka7e24c12009-10-30 11:49:00 +0000598
599
600enum InstanceType {
Leon Clarkee46be812010-01-19 14:06:41 +0000601 // String types.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000602 INTERNALIZED_STRING_TYPE = kTwoByteStringTag | kSeqStringTag |
603 kInternalizedTag, // FIRST_PRIMITIVE_TYPE
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000604 ONE_BYTE_INTERNALIZED_STRING_TYPE =
605 kOneByteStringTag | kSeqStringTag | kInternalizedTag,
606 EXTERNAL_INTERNALIZED_STRING_TYPE =
607 kTwoByteStringTag | kExternalStringTag | kInternalizedTag,
608 EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE =
609 kOneByteStringTag | kExternalStringTag | kInternalizedTag,
610 EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE =
611 EXTERNAL_INTERNALIZED_STRING_TYPE | kOneByteDataHintTag |
612 kInternalizedTag,
613 SHORT_EXTERNAL_INTERNALIZED_STRING_TYPE = EXTERNAL_INTERNALIZED_STRING_TYPE |
614 kShortExternalStringTag |
615 kInternalizedTag,
616 SHORT_EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE =
617 EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE | kShortExternalStringTag |
618 kInternalizedTag,
619 SHORT_EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE =
620 EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE |
621 kShortExternalStringTag | kInternalizedTag,
622 STRING_TYPE = INTERNALIZED_STRING_TYPE | kNotInternalizedTag,
623 ONE_BYTE_STRING_TYPE =
624 ONE_BYTE_INTERNALIZED_STRING_TYPE | kNotInternalizedTag,
625 CONS_STRING_TYPE = kTwoByteStringTag | kConsStringTag | kNotInternalizedTag,
626 CONS_ONE_BYTE_STRING_TYPE =
627 kOneByteStringTag | kConsStringTag | kNotInternalizedTag,
628 SLICED_STRING_TYPE =
629 kTwoByteStringTag | kSlicedStringTag | kNotInternalizedTag,
630 SLICED_ONE_BYTE_STRING_TYPE =
631 kOneByteStringTag | kSlicedStringTag | kNotInternalizedTag,
632 EXTERNAL_STRING_TYPE =
633 EXTERNAL_INTERNALIZED_STRING_TYPE | kNotInternalizedTag,
634 EXTERNAL_ONE_BYTE_STRING_TYPE =
635 EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE | kNotInternalizedTag,
636 EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE =
637 EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE |
638 kNotInternalizedTag,
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100639 SHORT_EXTERNAL_STRING_TYPE =
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000640 SHORT_EXTERNAL_INTERNALIZED_STRING_TYPE | kNotInternalizedTag,
641 SHORT_EXTERNAL_ONE_BYTE_STRING_TYPE =
642 SHORT_EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE | kNotInternalizedTag,
643 SHORT_EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE =
644 SHORT_EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE |
645 kNotInternalizedTag,
646
647 // Non-string names
648 SYMBOL_TYPE = kNotStringTag, // FIRST_NONSTRING_TYPE, LAST_NAME_TYPE
Steve Blocka7e24c12009-10-30 11:49:00 +0000649
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000650 // Other primitives (cannot contain non-map-word pointers to heap objects).
651 HEAP_NUMBER_TYPE,
652 SIMD128_VALUE_TYPE,
653 ODDBALL_TYPE, // LAST_PRIMITIVE_TYPE
654
Leon Clarkee46be812010-01-19 14:06:41 +0000655 // Objects allocated in their own spaces (never in new space).
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000656 MAP_TYPE,
Steve Blocka7e24c12009-10-30 11:49:00 +0000657 CODE_TYPE,
Leon Clarkee46be812010-01-19 14:06:41 +0000658
659 // "Data", objects that cannot contain non-map-word pointers to heap
660 // objects.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000661 MUTABLE_HEAP_NUMBER_TYPE,
Ben Murdoch257744e2011-11-30 15:57:28 +0000662 FOREIGN_TYPE,
Steve Blocka7e24c12009-10-30 11:49:00 +0000663 BYTE_ARRAY_TYPE,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000664 BYTECODE_ARRAY_TYPE,
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100665 FREE_SPACE_TYPE,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000666 FIXED_INT8_ARRAY_TYPE, // FIRST_FIXED_TYPED_ARRAY_TYPE
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000667 FIXED_UINT8_ARRAY_TYPE,
668 FIXED_INT16_ARRAY_TYPE,
669 FIXED_UINT16_ARRAY_TYPE,
670 FIXED_INT32_ARRAY_TYPE,
671 FIXED_UINT32_ARRAY_TYPE,
672 FIXED_FLOAT32_ARRAY_TYPE,
673 FIXED_FLOAT64_ARRAY_TYPE,
674 FIXED_UINT8_CLAMPED_ARRAY_TYPE, // LAST_FIXED_TYPED_ARRAY_TYPE
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000675 FIXED_DOUBLE_ARRAY_TYPE,
Leon Clarkee46be812010-01-19 14:06:41 +0000676 FILLER_TYPE, // LAST_DATA_TYPE
Steve Blocka7e24c12009-10-30 11:49:00 +0000677
Leon Clarkee46be812010-01-19 14:06:41 +0000678 // Structs.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000679 DECLARED_ACCESSOR_DESCRIPTOR_TYPE,
680 DECLARED_ACCESSOR_INFO_TYPE,
681 EXECUTABLE_ACCESSOR_INFO_TYPE,
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100682 ACCESSOR_PAIR_TYPE,
Steve Blocka7e24c12009-10-30 11:49:00 +0000683 ACCESS_CHECK_INFO_TYPE,
684 INTERCEPTOR_INFO_TYPE,
Steve Blocka7e24c12009-10-30 11:49:00 +0000685 CALL_HANDLER_INFO_TYPE,
686 FUNCTION_TEMPLATE_INFO_TYPE,
687 OBJECT_TEMPLATE_INFO_TYPE,
688 SIGNATURE_INFO_TYPE,
689 TYPE_SWITCH_INFO_TYPE,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000690 ALLOCATION_SITE_TYPE,
691 ALLOCATION_MEMENTO_TYPE,
Leon Clarkee46be812010-01-19 14:06:41 +0000692 SCRIPT_TYPE,
Steve Block6ded16b2010-05-10 14:33:55 +0100693 CODE_CACHE_TYPE,
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000694 POLYMORPHIC_CODE_CACHE_TYPE,
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100695 TYPE_FEEDBACK_INFO_TYPE,
696 ALIASED_ARGUMENTS_ENTRY_TYPE,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000697 BOX_TYPE,
Steve Blocka7e24c12009-10-30 11:49:00 +0000698 DEBUG_INFO_TYPE,
699 BREAK_POINT_INFO_TYPE,
Leon Clarkee46be812010-01-19 14:06:41 +0000700 FIXED_ARRAY_TYPE,
701 SHARED_FUNCTION_INFO_TYPE,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000702 CELL_TYPE,
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400703 WEAK_CELL_TYPE,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000704 TRANSITION_ARRAY_TYPE,
705 PROPERTY_CELL_TYPE,
706 PROTOTYPE_INFO_TYPE,
707 SLOPPY_BLOCK_WITH_EVAL_CONTEXT_EXTENSION_TYPE,
Leon Clarkee46be812010-01-19 14:06:41 +0000708
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100709 // All the following types are subtypes of JSReceiver, which corresponds to
710 // objects in the JS sense. The first and the last type in this range are
711 // the two forms of function. This organization enables using the same
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000712 // compares for checking the JS_RECEIVER and the NONCALLABLE_JS_OBJECT range.
713 JS_PROXY_TYPE, // FIRST_JS_RECEIVER_TYPE
714 JS_VALUE_TYPE, // FIRST_JS_OBJECT_TYPE
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000715 JS_MESSAGE_OBJECT_TYPE,
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100716 JS_DATE_TYPE,
Steve Blocka7e24c12009-10-30 11:49:00 +0000717 JS_OBJECT_TYPE,
718 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_GLOBAL_OBJECT_TYPE,
Steve Blocka7e24c12009-10-30 11:49:00 +0000722 JS_GLOBAL_PROXY_TYPE,
723 JS_ARRAY_TYPE,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000724 JS_ARRAY_BUFFER_TYPE,
725 JS_TYPED_ARRAY_TYPE,
726 JS_DATA_VIEW_TYPE,
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100727 JS_SET_TYPE,
728 JS_MAP_TYPE,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000729 JS_SET_ITERATOR_TYPE,
730 JS_MAP_ITERATOR_TYPE,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000731 JS_ITERATOR_RESULT_TYPE,
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000732 JS_WEAK_MAP_TYPE,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000733 JS_WEAK_SET_TYPE,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000734 JS_PROMISE_TYPE,
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100735 JS_REGEXP_TYPE,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000736 JS_BOUND_FUNCTION_TYPE,
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100737 JS_FUNCTION_TYPE, // LAST_JS_OBJECT_TYPE, LAST_JS_RECEIVER_TYPE
Steve Blocka7e24c12009-10-30 11:49:00 +0000738
739 // Pseudo-types
Steve Blocka7e24c12009-10-30 11:49:00 +0000740 FIRST_TYPE = 0x0,
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100741 LAST_TYPE = JS_FUNCTION_TYPE,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000742 FIRST_NAME_TYPE = FIRST_TYPE,
743 LAST_NAME_TYPE = SYMBOL_TYPE,
744 FIRST_UNIQUE_NAME_TYPE = INTERNALIZED_STRING_TYPE,
745 LAST_UNIQUE_NAME_TYPE = SYMBOL_TYPE,
746 FIRST_NONSTRING_TYPE = SYMBOL_TYPE,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000747 FIRST_PRIMITIVE_TYPE = FIRST_NAME_TYPE,
748 LAST_PRIMITIVE_TYPE = ODDBALL_TYPE,
749 FIRST_FUNCTION_TYPE = JS_BOUND_FUNCTION_TYPE,
750 LAST_FUNCTION_TYPE = JS_FUNCTION_TYPE,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000751 // Boundaries for testing for a fixed typed array.
752 FIRST_FIXED_TYPED_ARRAY_TYPE = FIXED_INT8_ARRAY_TYPE,
753 LAST_FIXED_TYPED_ARRAY_TYPE = FIXED_UINT8_CLAMPED_ARRAY_TYPE,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000754 // Boundary for promotion to old space.
Leon Clarkee46be812010-01-19 14:06:41 +0000755 LAST_DATA_TYPE = FILLER_TYPE,
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000756 // Boundary for objects represented as JSReceiver (i.e. JSObject or JSProxy).
757 // Note that there is no range for JSObject or JSProxy, since their subtypes
758 // are not continuous in this enum! The enum ranges instead reflect the
759 // external class names, where proxies are treated as either ordinary objects,
760 // or functions.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000761 FIRST_JS_RECEIVER_TYPE = JS_PROXY_TYPE,
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000762 LAST_JS_RECEIVER_TYPE = LAST_TYPE,
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100763 // Boundaries for testing the types represented as JSObject
764 FIRST_JS_OBJECT_TYPE = JS_VALUE_TYPE,
765 LAST_JS_OBJECT_TYPE = LAST_TYPE,
Steve Blocka7e24c12009-10-30 11:49:00 +0000766};
767
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000768STATIC_ASSERT(JS_OBJECT_TYPE == Internals::kJSObjectType);
769STATIC_ASSERT(FIRST_NONSTRING_TYPE == Internals::kFirstNonstringType);
770STATIC_ASSERT(ODDBALL_TYPE == Internals::kOddballType);
771STATIC_ASSERT(FOREIGN_TYPE == Internals::kForeignType);
772
773
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000774std::ostream& operator<<(std::ostream& os, InstanceType instance_type);
775
776
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000777#define FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(V) \
778 V(FAST_ELEMENTS_SUB_TYPE) \
779 V(DICTIONARY_ELEMENTS_SUB_TYPE) \
780 V(FAST_PROPERTIES_SUB_TYPE) \
781 V(DICTIONARY_PROPERTIES_SUB_TYPE) \
782 V(MAP_CODE_CACHE_SUB_TYPE) \
783 V(SCOPE_INFO_SUB_TYPE) \
784 V(STRING_TABLE_SUB_TYPE) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000785 V(DESCRIPTOR_ARRAY_SUB_TYPE)
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000786
787enum FixedArraySubInstanceType {
788#define DEFINE_FIXED_ARRAY_SUB_INSTANCE_TYPE(name) name,
789 FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(DEFINE_FIXED_ARRAY_SUB_INSTANCE_TYPE)
790#undef DEFINE_FIXED_ARRAY_SUB_INSTANCE_TYPE
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000791 LAST_FIXED_ARRAY_SUB_TYPE = DESCRIPTOR_ARRAY_SUB_TYPE
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000792};
Kristian Monsen9dcf7e22010-06-28 14:14:28 +0100793
794
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000795// TODO(bmeurer): Remove this in favor of the ComparisonResult below.
Steve Blocka7e24c12009-10-30 11:49:00 +0000796enum CompareResult {
797 LESS = -1,
798 EQUAL = 0,
799 GREATER = 1,
800
801 NOT_EQUAL = GREATER
802};
803
804
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000805// Result of an abstract relational comparison of x and y, implemented according
806// to ES6 section 7.2.11 Abstract Relational Comparison.
807enum class ComparisonResult {
808 kLessThan, // x < y
809 kEqual, // x = y
810 kGreaterThan, // x > y
811 kUndefined // at least one of x or y was undefined or NaN
812};
813
814
815#define DECL_BOOLEAN_ACCESSORS(name) \
816 inline bool name() const; \
817 inline void set_##name(bool value);
818
819#define DECL_INT_ACCESSORS(name) \
820 inline int name() const; \
821 inline void set_##name(int value);
Steve Blocka7e24c12009-10-30 11:49:00 +0000822
823
824#define DECL_ACCESSORS(name, type) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000825 inline type* name() const; \
Steve Blocka7e24c12009-10-30 11:49:00 +0000826 inline void set_##name(type* value, \
827 WriteBarrierMode mode = UPDATE_WRITE_BARRIER); \
828
829
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000830#define DECLARE_CAST(type) \
831 INLINE(static type* cast(Object* object)); \
832 INLINE(static const type* cast(const Object* object));
833
834
835class AccessorPair;
836class AllocationSite;
837class AllocationSiteCreationContext;
838class AllocationSiteUsageContext;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000839class Cell;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400840class ConsString;
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000841class ElementsAccessor;
842class FixedArrayBase;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000843class FunctionLiteral;
844class JSGlobalObject;
845class KeyAccumulator;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400846class LayoutDescriptor;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000847class LiteralsArray;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000848class LookupIterator;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000849class ObjectHashTable;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400850class ObjectVisitor;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000851class PropertyCell;
852class PropertyDescriptor;
853class SafepointEntry;
854class SharedFunctionInfo;
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000855class StringStream;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000856class TypeFeedbackInfo;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000857class TypeFeedbackVector;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400858class WeakCell;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000859class TransitionArray;
860
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000861// We cannot just say "class HeapType;" if it is created from a template... =8-?
862template<class> class TypeImpl;
863struct HeapTypeConfig;
864typedef TypeImpl<HeapTypeConfig> HeapType;
Steve Blocka7e24c12009-10-30 11:49:00 +0000865
866
867// A template-ized version of the IsXXX functions.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000868template <class C> inline bool Is(Object* obj);
Steve Blocka7e24c12009-10-30 11:49:00 +0000869
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000870#ifdef VERIFY_HEAP
871#define DECLARE_VERIFIER(Name) void Name##Verify();
872#else
873#define DECLARE_VERIFIER(Name)
874#endif
Steve Block053d10c2011-06-13 19:13:29 +0100875
Ben Murdochb0fe1622011-05-05 13:52:32 +0100876#ifdef OBJECT_PRINT
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400877#define DECLARE_PRINTER(Name) void Name##Print(std::ostream& os); // NOLINT
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000878#else
879#define DECLARE_PRINTER(Name)
Ben Murdochb0fe1622011-05-05 13:52:32 +0100880#endif
Steve Blocka7e24c12009-10-30 11:49:00 +0000881
Ben Murdochb8e0da22011-05-16 14:20:40 +0100882
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000883#define OBJECT_TYPE_LIST(V) \
884 V(Smi) \
885 V(HeapObject) \
886 V(Number)
Ben Murdochb8e0da22011-05-16 14:20:40 +0100887
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000888#define HEAP_OBJECT_TYPE_LIST(V) \
889 V(HeapNumber) \
890 V(MutableHeapNumber) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000891 V(Simd128Value) \
892 V(Float32x4) \
893 V(Int32x4) \
894 V(Uint32x4) \
895 V(Bool32x4) \
896 V(Int16x8) \
897 V(Uint16x8) \
898 V(Bool16x8) \
899 V(Int8x16) \
900 V(Uint8x16) \
901 V(Bool8x16) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000902 V(Name) \
903 V(UniqueName) \
904 V(String) \
905 V(SeqString) \
906 V(ExternalString) \
907 V(ConsString) \
908 V(SlicedString) \
909 V(ExternalTwoByteString) \
910 V(ExternalOneByteString) \
911 V(SeqTwoByteString) \
912 V(SeqOneByteString) \
913 V(InternalizedString) \
914 V(Symbol) \
915 \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000916 V(FixedTypedArrayBase) \
917 V(FixedUint8Array) \
918 V(FixedInt8Array) \
919 V(FixedUint16Array) \
920 V(FixedInt16Array) \
921 V(FixedUint32Array) \
922 V(FixedInt32Array) \
923 V(FixedFloat32Array) \
924 V(FixedFloat64Array) \
925 V(FixedUint8ClampedArray) \
926 V(ByteArray) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000927 V(BytecodeArray) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000928 V(FreeSpace) \
929 V(JSReceiver) \
930 V(JSObject) \
931 V(JSContextExtensionObject) \
932 V(JSGeneratorObject) \
933 V(JSModule) \
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400934 V(LayoutDescriptor) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000935 V(Map) \
936 V(DescriptorArray) \
937 V(TransitionArray) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000938 V(LiteralsArray) \
939 V(TypeFeedbackMetadata) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000940 V(TypeFeedbackVector) \
941 V(DeoptimizationInputData) \
942 V(DeoptimizationOutputData) \
943 V(DependentCode) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000944 V(HandlerTable) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000945 V(FixedArray) \
946 V(FixedDoubleArray) \
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400947 V(WeakFixedArray) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000948 V(ArrayList) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000949 V(Context) \
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400950 V(ScriptContextTable) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000951 V(NativeContext) \
952 V(ScopeInfo) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000953 V(JSBoundFunction) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000954 V(JSFunction) \
955 V(Code) \
956 V(Oddball) \
957 V(SharedFunctionInfo) \
958 V(JSValue) \
959 V(JSDate) \
960 V(JSMessageObject) \
961 V(StringWrapper) \
962 V(Foreign) \
963 V(Boolean) \
964 V(JSArray) \
965 V(JSArrayBuffer) \
966 V(JSArrayBufferView) \
967 V(JSTypedArray) \
968 V(JSDataView) \
969 V(JSProxy) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000970 V(JSSet) \
971 V(JSMap) \
972 V(JSSetIterator) \
973 V(JSMapIterator) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000974 V(JSIteratorResult) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000975 V(JSWeakCollection) \
976 V(JSWeakMap) \
977 V(JSWeakSet) \
978 V(JSRegExp) \
979 V(HashTable) \
980 V(Dictionary) \
981 V(StringTable) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000982 V(NormalizedMapCache) \
983 V(CompilationCacheTable) \
984 V(CodeCacheHashTable) \
985 V(PolymorphicCodeCacheHashTable) \
986 V(MapCache) \
987 V(Primitive) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000988 V(JSGlobalObject) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000989 V(JSGlobalProxy) \
990 V(UndetectableObject) \
991 V(AccessCheckNeeded) \
992 V(Cell) \
993 V(PropertyCell) \
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400994 V(WeakCell) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000995 V(ObjectHashTable) \
996 V(WeakHashTable) \
997 V(OrderedHashTable)
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100998
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000999// The element types selection for CreateListFromArrayLike.
1000enum class ElementTypes { kAll, kStringAndSymbol };
1001
Steve Blocka7e24c12009-10-30 11:49:00 +00001002// Object is the abstract superclass for all classes in the
1003// object hierarchy.
1004// Object does not use any virtual functions to avoid the
1005// allocation of the C++ vtable.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001006// Since both Smi and HeapObject are subclasses of Object no
Steve Blocka7e24c12009-10-30 11:49:00 +00001007// data members can be present in Object.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001008class Object {
Steve Blocka7e24c12009-10-30 11:49:00 +00001009 public:
1010 // Type testing.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001011 bool IsObject() const { return true; }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001012
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001013#define IS_TYPE_FUNCTION_DECL(type_) INLINE(bool Is##type_() const);
Ben Murdochb8e0da22011-05-16 14:20:40 +01001014 OBJECT_TYPE_LIST(IS_TYPE_FUNCTION_DECL)
1015 HEAP_OBJECT_TYPE_LIST(IS_TYPE_FUNCTION_DECL)
1016#undef IS_TYPE_FUNCTION_DECL
Steve Blocka7e24c12009-10-30 11:49:00 +00001017
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001018 // A non-keyed store is of the form a.x = foo or a["x"] = foo whereas
1019 // a keyed store is of the form a[expression] = foo.
1020 enum StoreFromKeyed {
1021 MAY_BE_STORE_FROM_KEYED,
1022 CERTAINLY_NOT_STORE_FROM_KEYED
1023 };
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001024
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001025 enum ShouldThrow { THROW_ON_ERROR, DONT_THROW };
1026
1027#define RETURN_FAILURE(isolate, should_throw, call) \
1028 do { \
1029 if ((should_throw) == DONT_THROW) { \
1030 return Just(false); \
1031 } else { \
1032 isolate->Throw(*isolate->factory()->call); \
1033 return Nothing<bool>(); \
1034 } \
1035 } while (false)
1036
1037#define MAYBE_RETURN(call, value) \
1038 do { \
1039 if ((call).IsNothing()) return value; \
1040 } while (false)
1041
1042#define MAYBE_RETURN_NULL(call) MAYBE_RETURN(call, MaybeHandle<Object>())
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001043
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001044 INLINE(bool IsFixedArrayBase() const);
1045 INLINE(bool IsExternal() const);
1046 INLINE(bool IsAccessorInfo() const);
Steve Blocka7e24c12009-10-30 11:49:00 +00001047
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001048 INLINE(bool IsStruct() const);
1049#define DECLARE_STRUCT_PREDICATE(NAME, Name, name) \
1050 INLINE(bool Is##Name() const);
Steve Blocka7e24c12009-10-30 11:49:00 +00001051 STRUCT_LIST(DECLARE_STRUCT_PREDICATE)
1052#undef DECLARE_STRUCT_PREDICATE
1053
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001054 // ES6, section 7.2.2 IsArray. NOT to be confused with %_IsArray.
1055 MUST_USE_RESULT static Maybe<bool> IsArray(Handle<Object> object);
1056
1057 // Test for JSBoundFunction or JSFunction.
1058 INLINE(bool IsFunction() const);
1059
1060 // ES6, section 7.2.3 IsCallable.
1061 INLINE(bool IsCallable() const);
1062
1063 // ES6, section 7.2.4 IsConstructor.
1064 INLINE(bool IsConstructor() const);
1065
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001066 INLINE(bool IsTemplateInfo()) const;
1067 INLINE(bool IsNameDictionary() const);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001068 INLINE(bool IsGlobalDictionary() const);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001069 INLINE(bool IsSeededNumberDictionary() const);
1070 INLINE(bool IsUnseededNumberDictionary() const);
1071 INLINE(bool IsOrderedHashSet() const);
1072 INLINE(bool IsOrderedHashMap() const);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001073 static bool IsPromise(Handle<Object> object);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001074
Steve Blocka7e24c12009-10-30 11:49:00 +00001075 // Oddball testing.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001076 INLINE(bool IsUndefined() const);
1077 INLINE(bool IsNull() const);
1078 INLINE(bool IsTheHole() const);
1079 INLINE(bool IsException() const);
1080 INLINE(bool IsUninitialized() const);
1081 INLINE(bool IsTrue() const);
1082 INLINE(bool IsFalse() const);
1083 INLINE(bool IsArgumentsMarker() const);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001084
1085 // Filler objects (fillers and free space objects).
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001086 INLINE(bool IsFiller() const);
Steve Blocka7e24c12009-10-30 11:49:00 +00001087
1088 // Extract the number.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001089 inline double Number() const;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001090 INLINE(bool IsNaN() const);
1091 INLINE(bool IsMinusZero() const);
1092 bool ToInt32(int32_t* value);
1093 bool ToUint32(uint32_t* value);
1094
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001095 inline Representation OptimalRepresentation();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001096
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001097 inline ElementsKind OptimalElementsKind();
1098
1099 inline bool FitsRepresentation(Representation representation);
1100
1101 // Checks whether two valid primitive encodings of a property name resolve to
1102 // the same logical property. E.g., the smi 1, the string "1" and the double
1103 // 1 all refer to the same property, so this helper will return true.
1104 inline bool KeyEquals(Object* other);
1105
1106 inline bool FilterKey(PropertyFilter filter);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001107
1108 Handle<HeapType> OptimalType(Isolate* isolate, Representation representation);
1109
1110 inline static Handle<Object> NewStorageFor(Isolate* isolate,
1111 Handle<Object> object,
1112 Representation representation);
1113
1114 inline static Handle<Object> WrapForRead(Isolate* isolate,
1115 Handle<Object> object,
1116 Representation representation);
Steve Blocka7e24c12009-10-30 11:49:00 +00001117
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001118 // Returns true if the object is of the correct type to be used as a
1119 // implementation of a JSObject's elements.
1120 inline bool HasValidElements();
1121
Steve Blocka7e24c12009-10-30 11:49:00 +00001122 inline bool HasSpecificClassOf(String* name);
1123
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001124 bool BooleanValue(); // ECMA-262 9.2.
Steve Blocka7e24c12009-10-30 11:49:00 +00001125
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001126 // ES6 section 7.2.11 Abstract Relational Comparison
1127 MUST_USE_RESULT static Maybe<ComparisonResult> Compare(
1128 Handle<Object> x, Handle<Object> y, Strength strength = Strength::WEAK);
1129
1130 // ES6 section 7.2.12 Abstract Equality Comparison
1131 MUST_USE_RESULT static Maybe<bool> Equals(Handle<Object> x, Handle<Object> y);
1132
1133 // ES6 section 7.2.13 Strict Equality Comparison
1134 bool StrictEquals(Object* that);
1135
Steve Blocka7e24c12009-10-30 11:49:00 +00001136 // Convert to a JSObject if needed.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001137 // native_context is used when creating wrapper object.
1138 static inline MaybeHandle<JSReceiver> ToObject(Isolate* isolate,
1139 Handle<Object> object);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001140 MUST_USE_RESULT static MaybeHandle<JSReceiver> ToObject(
1141 Isolate* isolate, Handle<Object> object, Handle<Context> context);
Steve Blocka7e24c12009-10-30 11:49:00 +00001142
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001143 // ES6 section 7.1.14 ToPropertyKey
1144 MUST_USE_RESULT static MaybeHandle<Name> ToName(Isolate* isolate,
1145 Handle<Object> input);
Steve Blocka7e24c12009-10-30 11:49:00 +00001146
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001147 // ES6 section 7.1.1 ToPrimitive
1148 MUST_USE_RESULT static inline MaybeHandle<Object> ToPrimitive(
1149 Handle<Object> input, ToPrimitiveHint hint = ToPrimitiveHint::kDefault);
Steve Blocka7e24c12009-10-30 11:49:00 +00001150
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001151 // ES6 section 7.1.3 ToNumber
1152 MUST_USE_RESULT static MaybeHandle<Object> ToNumber(Handle<Object> input);
1153
1154 // ES6 section 7.1.4 ToInteger
1155 MUST_USE_RESULT static MaybeHandle<Object> ToInteger(Isolate* isolate,
1156 Handle<Object> input);
1157
1158 // ES6 section 7.1.5 ToInt32
1159 MUST_USE_RESULT static MaybeHandle<Object> ToInt32(Isolate* isolate,
1160 Handle<Object> input);
1161
1162 // ES6 section 7.1.6 ToUint32
1163 MUST_USE_RESULT static MaybeHandle<Object> ToUint32(Isolate* isolate,
1164 Handle<Object> input);
1165
1166 // ES6 section 7.1.12 ToString
1167 MUST_USE_RESULT static MaybeHandle<String> ToString(Isolate* isolate,
1168 Handle<Object> input);
1169
1170 // ES6 section 7.1.15 ToLength
1171 MUST_USE_RESULT static MaybeHandle<Object> ToLength(Isolate* isolate,
1172 Handle<Object> input);
1173
1174 // ES6 section 7.3.9 GetMethod
1175 MUST_USE_RESULT static MaybeHandle<Object> GetMethod(
1176 Handle<JSReceiver> receiver, Handle<Name> name);
1177
1178 // ES6 section 7.3.17 CreateListFromArrayLike
1179 MUST_USE_RESULT static MaybeHandle<FixedArray> CreateListFromArrayLike(
1180 Isolate* isolate, Handle<Object> object, ElementTypes element_types);
1181
1182 // Check whether |object| is an instance of Error or NativeError.
1183 static bool IsErrorObject(Isolate* isolate, Handle<Object> object);
1184
1185 // ES6 section 12.5.6 The typeof Operator
1186 static Handle<String> TypeOf(Isolate* isolate, Handle<Object> object);
1187
1188 // ES6 section 12.6 Multiplicative Operators
1189 MUST_USE_RESULT static MaybeHandle<Object> Multiply(
1190 Isolate* isolate, Handle<Object> lhs, Handle<Object> rhs,
1191 Strength strength = Strength::WEAK);
1192 MUST_USE_RESULT static MaybeHandle<Object> Divide(
1193 Isolate* isolate, Handle<Object> lhs, Handle<Object> rhs,
1194 Strength strength = Strength::WEAK);
1195 MUST_USE_RESULT static MaybeHandle<Object> Modulus(
1196 Isolate* isolate, Handle<Object> lhs, Handle<Object> rhs,
1197 Strength strength = Strength::WEAK);
1198
1199 // ES6 section 12.7 Additive Operators
1200 MUST_USE_RESULT static MaybeHandle<Object> Add(
1201 Isolate* isolate, Handle<Object> lhs, Handle<Object> rhs,
1202 Strength strength = Strength::WEAK);
1203 MUST_USE_RESULT static MaybeHandle<Object> Subtract(
1204 Isolate* isolate, Handle<Object> lhs, Handle<Object> rhs,
1205 Strength strength = Strength::WEAK);
1206
1207 // ES6 section 12.8 Bitwise Shift Operators
1208 MUST_USE_RESULT static MaybeHandle<Object> ShiftLeft(
1209 Isolate* isolate, Handle<Object> lhs, Handle<Object> rhs,
1210 Strength strength = Strength::WEAK);
1211 MUST_USE_RESULT static MaybeHandle<Object> ShiftRight(
1212 Isolate* isolate, Handle<Object> lhs, Handle<Object> rhs,
1213 Strength strength = Strength::WEAK);
1214 MUST_USE_RESULT static MaybeHandle<Object> ShiftRightLogical(
1215 Isolate* isolate, Handle<Object> lhs, Handle<Object> rhs,
1216 Strength strength = Strength::WEAK);
1217
1218 // ES6 section 12.9 Relational Operators
1219 MUST_USE_RESULT static inline Maybe<bool> GreaterThan(
1220 Handle<Object> x, Handle<Object> y, Strength strength = Strength::WEAK);
1221 MUST_USE_RESULT static inline Maybe<bool> GreaterThanOrEqual(
1222 Handle<Object> x, Handle<Object> y, Strength strength = Strength::WEAK);
1223 MUST_USE_RESULT static inline Maybe<bool> LessThan(
1224 Handle<Object> x, Handle<Object> y, Strength strength = Strength::WEAK);
1225 MUST_USE_RESULT static inline Maybe<bool> LessThanOrEqual(
1226 Handle<Object> x, Handle<Object> y, Strength strength = Strength::WEAK);
1227
1228 // ES6 section 12.11 Binary Bitwise Operators
1229 MUST_USE_RESULT static MaybeHandle<Object> BitwiseAnd(
1230 Isolate* isolate, Handle<Object> lhs, Handle<Object> rhs,
1231 Strength strength = Strength::WEAK);
1232 MUST_USE_RESULT static MaybeHandle<Object> BitwiseOr(
1233 Isolate* isolate, Handle<Object> lhs, Handle<Object> rhs,
1234 Strength strength = Strength::WEAK);
1235 MUST_USE_RESULT static MaybeHandle<Object> BitwiseXor(
1236 Isolate* isolate, Handle<Object> lhs, Handle<Object> rhs,
1237 Strength strength = Strength::WEAK);
1238
1239 MUST_USE_RESULT static MaybeHandle<Object> GetProperty(
1240 LookupIterator* it, LanguageMode language_mode = SLOPPY);
1241
1242 // ES6 [[Set]] (when passed DONT_THROW)
1243 // Invariants for this and related functions (unless stated otherwise):
1244 // 1) When the result is Nothing, an exception is pending.
1245 // 2) When passed THROW_ON_ERROR, the result is never Just(false).
1246 // In some cases, an exception is thrown regardless of the ShouldThrow
1247 // argument. These cases are either in accordance with the spec or not
1248 // covered by it (eg., concerning API callbacks).
1249 MUST_USE_RESULT static Maybe<bool> SetProperty(LookupIterator* it,
1250 Handle<Object> value,
1251 LanguageMode language_mode,
1252 StoreFromKeyed store_mode);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001253 MUST_USE_RESULT static MaybeHandle<Object> SetProperty(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001254 Handle<Object> object, Handle<Name> name, Handle<Object> value,
1255 LanguageMode language_mode,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001256 StoreFromKeyed store_mode = MAY_BE_STORE_FROM_KEYED);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001257
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001258 MUST_USE_RESULT static Maybe<bool> SetSuperProperty(
1259 LookupIterator* it, Handle<Object> value, LanguageMode language_mode,
1260 StoreFromKeyed store_mode);
1261
1262 MUST_USE_RESULT static MaybeHandle<Object> ReadAbsentProperty(
1263 LookupIterator* it, LanguageMode language_mode);
1264 MUST_USE_RESULT static MaybeHandle<Object> ReadAbsentProperty(
1265 Isolate* isolate, Handle<Object> receiver, Handle<Object> name,
1266 LanguageMode language_mode);
1267 MUST_USE_RESULT static Maybe<bool> CannotCreateProperty(
1268 Isolate* isolate, Handle<Object> receiver, Handle<Object> name,
1269 Handle<Object> value, ShouldThrow should_throw);
1270 MUST_USE_RESULT static Maybe<bool> WriteToReadOnlyProperty(
1271 LookupIterator* it, Handle<Object> value, ShouldThrow should_throw);
1272 MUST_USE_RESULT static Maybe<bool> WriteToReadOnlyProperty(
1273 Isolate* isolate, Handle<Object> receiver, Handle<Object> name,
1274 Handle<Object> value, ShouldThrow should_throw);
1275 MUST_USE_RESULT static Maybe<bool> RedefineIncompatibleProperty(
1276 Isolate* isolate, Handle<Object> name, Handle<Object> value,
1277 ShouldThrow should_throw);
1278 MUST_USE_RESULT static Maybe<bool> SetDataProperty(LookupIterator* it,
1279 Handle<Object> value);
1280 MUST_USE_RESULT static Maybe<bool> AddDataProperty(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001281 LookupIterator* it, Handle<Object> value, PropertyAttributes attributes,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001282 ShouldThrow should_throw, StoreFromKeyed store_mode);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001283 MUST_USE_RESULT static inline MaybeHandle<Object> GetPropertyOrElement(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001284 Handle<Object> object, Handle<Name> name,
1285 LanguageMode language_mode = SLOPPY);
1286 MUST_USE_RESULT static inline MaybeHandle<Object> GetPropertyOrElement(
1287 Handle<JSReceiver> holder, Handle<Name> name, Handle<Object> receiver,
1288 LanguageMode language_mode = SLOPPY);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001289 MUST_USE_RESULT static inline MaybeHandle<Object> GetProperty(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001290 Isolate* isolate, Handle<Object> object, const char* key,
1291 LanguageMode language_mode = SLOPPY);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001292 MUST_USE_RESULT static inline MaybeHandle<Object> GetProperty(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001293 Handle<Object> object, Handle<Name> name,
1294 LanguageMode language_mode = SLOPPY);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001295
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001296 MUST_USE_RESULT static MaybeHandle<Object> GetPropertyWithAccessor(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001297 LookupIterator* it, LanguageMode language_mode);
1298 MUST_USE_RESULT static Maybe<bool> SetPropertyWithAccessor(
1299 LookupIterator* it, Handle<Object> value, ShouldThrow should_throw);
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001300
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001301 MUST_USE_RESULT static MaybeHandle<Object> GetPropertyWithDefinedGetter(
1302 Handle<Object> receiver,
1303 Handle<JSReceiver> getter);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001304 MUST_USE_RESULT static Maybe<bool> SetPropertyWithDefinedSetter(
1305 Handle<Object> receiver, Handle<JSReceiver> setter, Handle<Object> value,
1306 ShouldThrow should_throw);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001307
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001308 MUST_USE_RESULT static inline MaybeHandle<Object> GetElement(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001309 Isolate* isolate, Handle<Object> object, uint32_t index,
1310 LanguageMode language_mode = SLOPPY);
Steve Blocka7e24c12009-10-30 11:49:00 +00001311
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001312 MUST_USE_RESULT static inline MaybeHandle<Object> SetElement(
1313 Isolate* isolate, Handle<Object> object, uint32_t index,
1314 Handle<Object> value, LanguageMode language_mode);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001315
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001316 // Get the first non-hidden prototype.
1317 static inline MaybeHandle<Object> GetPrototype(Isolate* isolate,
1318 Handle<Object> receiver);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001319
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001320 MUST_USE_RESULT static Maybe<bool> HasInPrototypeChain(Isolate* isolate,
1321 Handle<Object> object,
1322 Handle<Object> proto);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001323
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001324 // Returns the permanent hash code associated with this object. May return
1325 // undefined if not yet created.
1326 Object* GetHash();
Steve Blocka7e24c12009-10-30 11:49:00 +00001327
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001328 // Returns undefined for JSObjects, but returns the hash code for simple
1329 // objects. This avoids a double lookup in the cases where we know we will
1330 // add the hash to the JSObject if it does not already exist.
1331 Object* GetSimpleHash();
1332
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001333 // Returns the permanent hash code associated with this object depending on
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001334 // the actual object type. May create and store a hash code if needed and none
1335 // exists.
1336 static Handle<Smi> GetOrCreateHash(Isolate* isolate, Handle<Object> object);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001337
1338 // Checks whether this object has the same value as the given one. This
1339 // function is implemented according to ES5, section 9.12 and can be used
1340 // to implement the Harmony "egal" function.
1341 bool SameValue(Object* other);
1342
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001343 // Checks whether this object has the same value as the given one.
1344 // +0 and -0 are treated equal. Everything else is the same as SameValue.
1345 // This function is implemented according to ES6, section 7.2.4 and is used
1346 // by ES6 Map and Set.
1347 bool SameValueZero(Object* other);
1348
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001349 // ES6 section 9.4.2.3 ArraySpeciesCreate (part of it)
1350 MUST_USE_RESULT static MaybeHandle<Object> ArraySpeciesConstructor(
1351 Isolate* isolate, Handle<Object> original_array);
1352
1353 // Tries to convert an object to an array length. Returns true and sets the
1354 // output parameter if it succeeds.
1355 inline bool ToArrayLength(uint32_t* index);
1356
1357 // Tries to convert an object to an array index. Returns true and sets the
1358 // output parameter if it succeeds. Equivalent to ToArrayLength, but does not
1359 // allow kMaxUInt32.
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01001360 inline bool ToArrayIndex(uint32_t* index);
1361
Steve Blocka7e24c12009-10-30 11:49:00 +00001362 // Returns true if this is a JSValue containing a string and the index is
1363 // < the length of the string. Used to implement [] on strings.
1364 inline bool IsStringObjectWithCharacterAt(uint32_t index);
1365
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001366 DECLARE_VERIFIER(Object)
1367#ifdef VERIFY_HEAP
Steve Blocka7e24c12009-10-30 11:49:00 +00001368 // Verify a pointer is a valid object pointer.
1369 static void VerifyPointer(Object* p);
1370#endif
1371
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001372 inline void VerifyApiCallResultType();
1373
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001374 // ES6 19.1.3.6 Object.prototype.toString
1375 MUST_USE_RESULT static MaybeHandle<String> ObjectProtoToString(
1376 Isolate* isolate, Handle<Object> object);
1377
Steve Blocka7e24c12009-10-30 11:49:00 +00001378 // Prints this object without details.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001379 void ShortPrint(FILE* out = stdout);
Steve Blocka7e24c12009-10-30 11:49:00 +00001380
1381 // Prints this object without details to a message accumulator.
1382 void ShortPrint(StringStream* accumulator);
1383
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001384 void ShortPrint(std::ostream& os); // NOLINT
1385
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001386 DECLARE_CAST(Object)
Steve Blocka7e24c12009-10-30 11:49:00 +00001387
1388 // Layout description.
1389 static const int kHeaderSize = 0; // Object does not take up any space.
1390
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001391#ifdef OBJECT_PRINT
1392 // For our gdb macros, we should perhaps change these in the future.
1393 void Print();
1394
1395 // Prints this object with details.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001396 void Print(std::ostream& os); // NOLINT
1397#else
1398 void Print() { ShortPrint(); }
1399 void Print(std::ostream& os) { ShortPrint(os); } // NOLINT
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001400#endif
1401
Steve Blocka7e24c12009-10-30 11:49:00 +00001402 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001403 friend class LookupIterator;
1404 friend class PrototypeIterator;
1405
1406 // Return the map of the root of object's prototype chain.
1407 Map* GetRootMap(Isolate* isolate);
1408
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001409 // Helper for SetProperty and SetSuperProperty.
1410 // Return value is only meaningful if [found] is set to true on return.
1411 MUST_USE_RESULT static Maybe<bool> SetPropertyInternal(
1412 LookupIterator* it, Handle<Object> value, LanguageMode language_mode,
1413 StoreFromKeyed store_mode, bool* found);
1414
Steve Blocka7e24c12009-10-30 11:49:00 +00001415 DISALLOW_IMPLICIT_CONSTRUCTORS(Object);
1416};
1417
1418
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001419// In objects.h to be usable without objects-inl.h inclusion.
1420bool Object::IsSmi() const { return HAS_SMI_TAG(this); }
1421bool Object::IsHeapObject() const { return Internals::HasHeapObjectTag(this); }
1422
1423
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001424struct Brief {
1425 explicit Brief(const Object* const v) : value(v) {}
1426 const Object* value;
1427};
1428
1429
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001430std::ostream& operator<<(std::ostream& os, const Brief& v);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001431
1432
Steve Blocka7e24c12009-10-30 11:49:00 +00001433// Smi represents integer Numbers that can be stored in 31 bits.
1434// Smis are immediate which means they are NOT allocated in the heap.
Steve Blocka7e24c12009-10-30 11:49:00 +00001435// The this pointer has the following format: [31 bit signed int] 0
Steve Block3ce2e202009-11-05 08:53:23 +00001436// For long smis it has the following format:
1437// [32 bit signed int] [31 bits zero padding] 0
1438// Smi stands for small integer.
Steve Blocka7e24c12009-10-30 11:49:00 +00001439class Smi: public Object {
1440 public:
1441 // Returns the integer value.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001442 inline int value() const { return Internals::SmiValue(this); }
Steve Blocka7e24c12009-10-30 11:49:00 +00001443
1444 // Convert a value to a Smi object.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001445 static inline Smi* FromInt(int value) {
1446 DCHECK(Smi::IsValid(value));
1447 return reinterpret_cast<Smi*>(Internals::IntToSmi(value));
1448 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001449
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001450 static inline Smi* FromIntptr(intptr_t value) {
1451 DCHECK(Smi::IsValid(value));
1452 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
1453 return reinterpret_cast<Smi*>((value << smi_shift_bits) | kSmiTag);
1454 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001455
1456 // Returns whether value can be represented in a Smi.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001457 static inline bool IsValid(intptr_t value) {
1458 bool result = Internals::IsValidSmi(value);
1459 DCHECK_EQ(result, value >= kMinValue && value <= kMaxValue);
1460 return result;
1461 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001462
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001463 DECLARE_CAST(Smi)
Steve Blocka7e24c12009-10-30 11:49:00 +00001464
1465 // Dispatched behavior.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001466 void SmiPrint(std::ostream& os) const; // NOLINT
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001467 DECLARE_VERIFIER(Smi)
Steve Blocka7e24c12009-10-30 11:49:00 +00001468
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001469 static const int kMinValue =
1470 (static_cast<unsigned int>(-1)) << (kSmiValueSize - 1);
Steve Block3ce2e202009-11-05 08:53:23 +00001471 static const int kMaxValue = -(kMinValue + 1);
Steve Blocka7e24c12009-10-30 11:49:00 +00001472
1473 private:
1474 DISALLOW_IMPLICIT_CONSTRUCTORS(Smi);
1475};
1476
1477
Steve Blocka7e24c12009-10-30 11:49:00 +00001478// Heap objects typically have a map pointer in their first word. However,
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001479// during GC other data (e.g. mark bits, forwarding addresses) is sometimes
Steve Blocka7e24c12009-10-30 11:49:00 +00001480// encoded in the first word. The class MapWord is an abstraction of the
1481// value in a heap object's first word.
1482class MapWord BASE_EMBEDDED {
1483 public:
1484 // Normal state: the map word contains a map pointer.
1485
1486 // Create a map word from a map pointer.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001487 static inline MapWord FromMap(const Map* map);
Steve Blocka7e24c12009-10-30 11:49:00 +00001488
1489 // View this map word as a map pointer.
1490 inline Map* ToMap();
1491
1492
1493 // Scavenge collection: the map word of live objects in the from space
1494 // contains a forwarding address (a heap object pointer in the to space).
1495
1496 // True if this map word is a forwarding address for a scavenge
1497 // collection. Only valid during a scavenge collection (specifically,
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001498 // when all map words are heap object pointers, i.e. not during a full GC).
Steve Blocka7e24c12009-10-30 11:49:00 +00001499 inline bool IsForwardingAddress();
1500
1501 // Create a map word from a forwarding address.
1502 static inline MapWord FromForwardingAddress(HeapObject* object);
1503
1504 // View this map word as a forwarding address.
1505 inline HeapObject* ToForwardingAddress();
1506
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001507 static inline MapWord FromRawValue(uintptr_t value) {
1508 return MapWord(value);
1509 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001510
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001511 inline uintptr_t ToRawValue() {
1512 return value_;
1513 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001514
1515 private:
1516 // HeapObject calls the private constructor and directly reads the value.
1517 friend class HeapObject;
1518
1519 explicit MapWord(uintptr_t value) : value_(value) {}
1520
1521 uintptr_t value_;
1522};
1523
1524
1525// HeapObject is the superclass for all classes describing heap allocated
1526// objects.
1527class HeapObject: public Object {
1528 public:
1529 // [map]: Contains a map which contains the object's reflective
1530 // information.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001531 inline Map* map() const;
Steve Blocka7e24c12009-10-30 11:49:00 +00001532 inline void set_map(Map* value);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001533 // The no-write-barrier version. This is OK if the object is white and in
1534 // new space, or if the value is an immortal immutable object, like the maps
1535 // of primitive (non-JS) objects like strings, heap numbers etc.
1536 inline void set_map_no_write_barrier(Map* value);
Steve Blocka7e24c12009-10-30 11:49:00 +00001537
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001538 // Get the map using acquire load.
1539 inline Map* synchronized_map();
1540 inline MapWord synchronized_map_word() const;
1541
1542 // Set the map using release store
1543 inline void synchronized_set_map(Map* value);
1544 inline void synchronized_set_map_no_write_barrier(Map* value);
1545 inline void synchronized_set_map_word(MapWord map_word);
1546
Steve Blocka7e24c12009-10-30 11:49:00 +00001547 // During garbage collection, the map word of a heap object does not
1548 // necessarily contain a map pointer.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001549 inline MapWord map_word() const;
Steve Blocka7e24c12009-10-30 11:49:00 +00001550 inline void set_map_word(MapWord map_word);
1551
Steve Block44f0eee2011-05-26 01:26:41 +01001552 // The Heap the object was allocated in. Used also to access Isolate.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001553 inline Heap* GetHeap() const;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001554
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001555 // Convenience method to get current isolate.
1556 inline Isolate* GetIsolate() const;
Steve Block44f0eee2011-05-26 01:26:41 +01001557
Steve Blocka7e24c12009-10-30 11:49:00 +00001558 // Converts an address to a HeapObject pointer.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001559 static inline HeapObject* FromAddress(Address address) {
1560 DCHECK_TAG_ALIGNED(address);
1561 return reinterpret_cast<HeapObject*>(address + kHeapObjectTag);
1562 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001563
1564 // Returns the address of this HeapObject.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001565 inline Address address() {
1566 return reinterpret_cast<Address>(this) - kHeapObjectTag;
1567 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001568
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001569 // Iterates over pointers contained in the object (including the Map).
1570 // If it's not performance critical iteration use the non-templatized
1571 // version.
Steve Blocka7e24c12009-10-30 11:49:00 +00001572 void Iterate(ObjectVisitor* v);
1573
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001574 template <typename ObjectVisitor>
1575 inline void IterateFast(ObjectVisitor* v);
1576
Steve Blocka7e24c12009-10-30 11:49:00 +00001577 // Iterates over all pointers contained in the object except the
1578 // first map pointer. The object type is given in the first
1579 // parameter. This function does not access the map pointer in the
1580 // object, and so is safe to call while the map pointer is modified.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001581 // If it's not performance critical iteration use the non-templatized
1582 // version.
1583 void IterateBody(ObjectVisitor* v);
Steve Blocka7e24c12009-10-30 11:49:00 +00001584 void IterateBody(InstanceType type, int object_size, ObjectVisitor* v);
1585
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001586 template <typename ObjectVisitor>
1587 inline void IterateBodyFast(ObjectVisitor* v);
1588
1589 template <typename ObjectVisitor>
1590 inline void IterateBodyFast(InstanceType type, int object_size,
1591 ObjectVisitor* v);
1592
1593 // Returns true if the object contains a tagged value at given offset.
1594 // It is used for invalid slots filtering. If the offset points outside
1595 // of the object or to the map word, the result is UNDEFINED (!!!).
1596 bool IsValidSlot(int offset);
1597
Steve Blocka7e24c12009-10-30 11:49:00 +00001598 // Returns the heap object's size in bytes
1599 inline int Size();
1600
1601 // Given a heap object's map pointer, returns the heap size in bytes
1602 // Useful when the map pointer field is used for other purposes.
1603 // GC internal.
1604 inline int SizeFromMap(Map* map);
1605
Steve Blocka7e24c12009-10-30 11:49:00 +00001606 // Returns the field at offset in obj, as a read/write Object* reference.
1607 // Does no checking, and is safe to use during GC, while maps are invalid.
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01001608 // Does not invoke write barrier, so should only be assigned to
Steve Blocka7e24c12009-10-30 11:49:00 +00001609 // during marking GC.
1610 static inline Object** RawField(HeapObject* obj, int offset);
1611
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001612 // Adds the |code| object related to |name| to the code cache of this map. If
1613 // this map is a dictionary map that is shared, the map copied and installed
1614 // onto the object.
1615 static void UpdateMapCodeCache(Handle<HeapObject> object,
1616 Handle<Name> name,
1617 Handle<Code> code);
1618
1619 DECLARE_CAST(HeapObject)
Steve Blocka7e24c12009-10-30 11:49:00 +00001620
Leon Clarke4515c472010-02-03 11:58:03 +00001621 // Return the write barrier mode for this. Callers of this function
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001622 // must be able to present a reference to an DisallowHeapAllocation
Leon Clarke4515c472010-02-03 11:58:03 +00001623 // object as a sign that they are not going to use this function
1624 // from code that allocates and thus invalidates the returned write
1625 // barrier mode.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001626 inline WriteBarrierMode GetWriteBarrierMode(
1627 const DisallowHeapAllocation& promise);
Steve Blocka7e24c12009-10-30 11:49:00 +00001628
1629 // Dispatched behavior.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001630 void HeapObjectShortPrint(std::ostream& os); // NOLINT
Ben Murdochb0fe1622011-05-05 13:52:32 +01001631#ifdef OBJECT_PRINT
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001632 void PrintHeader(std::ostream& os, const char* id); // NOLINT
Ben Murdoch85b71792012-04-11 18:30:58 +01001633#endif
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001634 DECLARE_PRINTER(HeapObject)
1635 DECLARE_VERIFIER(HeapObject)
1636#ifdef VERIFY_HEAP
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001637 inline void VerifyObjectField(int offset);
1638 inline void VerifySmiField(int offset);
1639
Steve Blocka7e24c12009-10-30 11:49:00 +00001640 // Verify a pointer is a valid HeapObject pointer that points to object
1641 // areas in the heap.
1642 static void VerifyHeapPointer(Object* p);
1643#endif
1644
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001645 inline AllocationAlignment RequiredAlignment();
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001646
Steve Blocka7e24c12009-10-30 11:49:00 +00001647 // Layout description.
1648 // First field in a heap object is map.
1649 static const int kMapOffset = Object::kHeaderSize;
1650 static const int kHeaderSize = kMapOffset + kPointerSize;
1651
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001652 STATIC_ASSERT(kMapOffset == Internals::kHeapObjectMapOffset);
Steve Blocka7e24c12009-10-30 11:49:00 +00001653
Steve Blocka7e24c12009-10-30 11:49:00 +00001654 private:
1655 DISALLOW_IMPLICIT_CONSTRUCTORS(HeapObject);
1656};
1657
1658
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001659template <int start_offset, int end_offset, int size>
1660class FixedBodyDescriptor;
Iain Merrick75681382010-08-19 15:07:18 +01001661
1662
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001663template <int start_offset>
1664class FlexibleBodyDescriptor;
Iain Merrick75681382010-08-19 15:07:18 +01001665
Iain Merrick75681382010-08-19 15:07:18 +01001666
Steve Blocka7e24c12009-10-30 11:49:00 +00001667// The HeapNumber class describes heap allocated numbers that cannot be
1668// represented in a Smi (small integer)
1669class HeapNumber: public HeapObject {
1670 public:
1671 // [value]: number value.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001672 inline double value() const;
Steve Blocka7e24c12009-10-30 11:49:00 +00001673 inline void set_value(double value);
1674
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001675 DECLARE_CAST(HeapNumber)
Steve Blocka7e24c12009-10-30 11:49:00 +00001676
1677 // Dispatched behavior.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001678 bool HeapNumberBooleanValue();
1679
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001680 void HeapNumberPrint(std::ostream& os); // NOLINT
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001681 DECLARE_VERIFIER(HeapNumber)
Steve Blocka7e24c12009-10-30 11:49:00 +00001682
Steve Block6ded16b2010-05-10 14:33:55 +01001683 inline int get_exponent();
1684 inline int get_sign();
1685
Steve Blocka7e24c12009-10-30 11:49:00 +00001686 // Layout description.
1687 static const int kValueOffset = HeapObject::kHeaderSize;
1688 // IEEE doubles are two 32 bit words. The first is just mantissa, the second
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001689 // is a mixture of sign, exponent and mantissa. The offsets of two 32 bit
1690 // words within double numbers are endian dependent and they are set
1691 // accordingly.
1692#if defined(V8_TARGET_LITTLE_ENDIAN)
Steve Blocka7e24c12009-10-30 11:49:00 +00001693 static const int kMantissaOffset = kValueOffset;
1694 static const int kExponentOffset = kValueOffset + 4;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001695#elif defined(V8_TARGET_BIG_ENDIAN)
1696 static const int kMantissaOffset = kValueOffset + 4;
1697 static const int kExponentOffset = kValueOffset;
1698#else
1699#error Unknown byte ordering
1700#endif
Ben Murdoch8b112d22011-06-08 16:22:53 +01001701
Steve Blocka7e24c12009-10-30 11:49:00 +00001702 static const int kSize = kValueOffset + kDoubleSize;
Steve Blocka7e24c12009-10-30 11:49:00 +00001703 static const uint32_t kSignMask = 0x80000000u;
1704 static const uint32_t kExponentMask = 0x7ff00000u;
1705 static const uint32_t kMantissaMask = 0xfffffu;
Steve Block6ded16b2010-05-10 14:33:55 +01001706 static const int kMantissaBits = 52;
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01001707 static const int kExponentBits = 11;
Steve Blocka7e24c12009-10-30 11:49:00 +00001708 static const int kExponentBias = 1023;
1709 static const int kExponentShift = 20;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001710 static const int kInfinityOrNanExponent =
1711 (kExponentMask >> kExponentShift) - kExponentBias;
Steve Blocka7e24c12009-10-30 11:49:00 +00001712 static const int kMantissaBitsInTopWord = 20;
1713 static const int kNonMantissaBitsInTopWord = 12;
1714
1715 private:
1716 DISALLOW_IMPLICIT_CONSTRUCTORS(HeapNumber);
1717};
1718
1719
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001720// The Simd128Value class describes heap allocated 128 bit SIMD values.
1721class Simd128Value : public HeapObject {
1722 public:
1723 DECLARE_CAST(Simd128Value)
1724
1725 DECLARE_PRINTER(Simd128Value)
1726 DECLARE_VERIFIER(Simd128Value)
1727
1728 static Handle<String> ToString(Handle<Simd128Value> input);
1729
1730 // Equality operations.
1731 inline bool Equals(Simd128Value* that);
1732 static inline bool Equals(Handle<Simd128Value> one, Handle<Simd128Value> two);
1733
1734 // Checks that another instance is bit-wise equal.
1735 bool BitwiseEquals(const Simd128Value* other) const;
1736 // Computes a hash from the 128 bit value, viewed as 4 32-bit integers.
1737 uint32_t Hash() const;
1738 // Copies the 16 bytes of SIMD data to the destination address.
1739 void CopyBits(void* destination) const;
1740
1741 // Layout description.
1742 static const int kValueOffset = HeapObject::kHeaderSize;
1743 static const int kSize = kValueOffset + kSimd128Size;
1744
1745 private:
1746 DISALLOW_IMPLICIT_CONSTRUCTORS(Simd128Value);
1747};
1748
1749
1750// V has parameters (TYPE, Type, type, lane count, lane type)
1751#define SIMD128_TYPES(V) \
1752 V(FLOAT32X4, Float32x4, float32x4, 4, float) \
1753 V(INT32X4, Int32x4, int32x4, 4, int32_t) \
1754 V(UINT32X4, Uint32x4, uint32x4, 4, uint32_t) \
1755 V(BOOL32X4, Bool32x4, bool32x4, 4, bool) \
1756 V(INT16X8, Int16x8, int16x8, 8, int16_t) \
1757 V(UINT16X8, Uint16x8, uint16x8, 8, uint16_t) \
1758 V(BOOL16X8, Bool16x8, bool16x8, 8, bool) \
1759 V(INT8X16, Int8x16, int8x16, 16, int8_t) \
1760 V(UINT8X16, Uint8x16, uint8x16, 16, uint8_t) \
1761 V(BOOL8X16, Bool8x16, bool8x16, 16, bool)
1762
1763#define SIMD128_VALUE_CLASS(TYPE, Type, type, lane_count, lane_type) \
1764 class Type final : public Simd128Value { \
1765 public: \
1766 inline lane_type get_lane(int lane) const; \
1767 inline void set_lane(int lane, lane_type value); \
1768 \
1769 DECLARE_CAST(Type) \
1770 \
1771 DECLARE_PRINTER(Type) \
1772 \
1773 static Handle<String> ToString(Handle<Type> input); \
1774 \
1775 inline bool Equals(Type* that); \
1776 \
1777 private: \
1778 DISALLOW_IMPLICIT_CONSTRUCTORS(Type); \
1779 };
1780SIMD128_TYPES(SIMD128_VALUE_CLASS)
1781#undef SIMD128_VALUE_CLASS
1782
1783
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001784enum EnsureElementsMode {
1785 DONT_ALLOW_DOUBLE_ELEMENTS,
1786 ALLOW_COPIED_DOUBLE_ELEMENTS,
1787 ALLOW_CONVERTED_DOUBLE_ELEMENTS
1788};
1789
1790
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001791// Indicator for one component of an AccessorPair.
1792enum AccessorComponent {
1793 ACCESSOR_GETTER,
1794 ACCESSOR_SETTER
1795};
1796
1797
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001798enum GetKeysConversion { KEEP_NUMBERS, CONVERT_TO_STRING };
1799
1800
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001801// JSReceiver includes types on which properties can be defined, i.e.,
1802// JSObject and JSProxy.
1803class JSReceiver: public HeapObject {
Steve Blocka7e24c12009-10-30 11:49:00 +00001804 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001805 // [properties]: Backing storage for properties.
1806 // properties is a FixedArray in the fast case and a Dictionary in the
1807 // slow case.
1808 DECL_ACCESSORS(properties, FixedArray) // Get and set fast properties.
1809 inline void initialize_properties();
1810 inline bool HasFastProperties();
1811 // Gets slow properties for non-global objects.
1812 inline NameDictionary* property_dictionary();
1813
1814 // Deletes an existing named property in a normalized object.
1815 static void DeleteNormalizedProperty(Handle<JSReceiver> object,
1816 Handle<Name> name, int entry);
Ben Murdoche0cee9b2011-05-25 10:26:03 +01001817
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001818 DECLARE_CAST(JSReceiver)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001819
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001820 // ES6 section 7.1.1 ToPrimitive
1821 MUST_USE_RESULT static MaybeHandle<Object> ToPrimitive(
1822 Handle<JSReceiver> receiver,
1823 ToPrimitiveHint hint = ToPrimitiveHint::kDefault);
1824 MUST_USE_RESULT static MaybeHandle<Object> OrdinaryToPrimitive(
1825 Handle<JSReceiver> receiver, OrdinaryToPrimitiveHint hint);
1826
1827 static MaybeHandle<Context> GetFunctionRealm(Handle<JSReceiver> receiver);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001828
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001829 // Implementation of [[HasProperty]], ECMA-262 5th edition, section 8.12.6.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001830 MUST_USE_RESULT static Maybe<bool> HasProperty(LookupIterator* it);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001831 MUST_USE_RESULT static inline Maybe<bool> HasProperty(
1832 Handle<JSReceiver> object, Handle<Name> name);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001833 MUST_USE_RESULT static inline Maybe<bool> HasElement(
1834 Handle<JSReceiver> object, uint32_t index);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001835
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001836 MUST_USE_RESULT static inline Maybe<bool> HasOwnProperty(
1837 Handle<JSReceiver> object, Handle<Name> name);
1838
1839 // Implementation of ES6 [[Delete]]
1840 MUST_USE_RESULT static Maybe<bool> DeletePropertyOrElement(
1841 Handle<JSReceiver> object, Handle<Name> name,
1842 LanguageMode language_mode = SLOPPY);
1843 MUST_USE_RESULT static Maybe<bool> DeleteProperty(
1844 Handle<JSReceiver> object, Handle<Name> name,
1845 LanguageMode language_mode = SLOPPY);
1846 MUST_USE_RESULT static Maybe<bool> DeleteProperty(LookupIterator* it,
1847 LanguageMode language_mode);
1848 MUST_USE_RESULT static Maybe<bool> DeleteElement(
1849 Handle<JSReceiver> object, uint32_t index,
1850 LanguageMode language_mode = SLOPPY);
1851
1852 MUST_USE_RESULT static Object* DefineProperty(Isolate* isolate,
1853 Handle<Object> object,
1854 Handle<Object> name,
1855 Handle<Object> attributes);
1856 MUST_USE_RESULT static MaybeHandle<Object> DefineProperties(
1857 Isolate* isolate, Handle<Object> object, Handle<Object> properties);
1858
1859 // "virtual" dispatcher to the correct [[DefineOwnProperty]] implementation.
1860 MUST_USE_RESULT static Maybe<bool> DefineOwnProperty(
1861 Isolate* isolate, Handle<JSReceiver> object, Handle<Object> key,
1862 PropertyDescriptor* desc, ShouldThrow should_throw);
1863
1864 // ES6 7.3.4 (when passed DONT_THROW)
1865 MUST_USE_RESULT static Maybe<bool> CreateDataProperty(
1866 LookupIterator* it, Handle<Object> value, ShouldThrow should_throw);
1867
1868 // ES6 9.1.6.1
1869 MUST_USE_RESULT static Maybe<bool> OrdinaryDefineOwnProperty(
1870 Isolate* isolate, Handle<JSObject> object, Handle<Object> key,
1871 PropertyDescriptor* desc, ShouldThrow should_throw);
1872 MUST_USE_RESULT static Maybe<bool> OrdinaryDefineOwnProperty(
1873 LookupIterator* it, PropertyDescriptor* desc, ShouldThrow should_throw);
1874 // ES6 9.1.6.2
1875 MUST_USE_RESULT static Maybe<bool> IsCompatiblePropertyDescriptor(
1876 Isolate* isolate, bool extensible, PropertyDescriptor* desc,
1877 PropertyDescriptor* current, Handle<Name> property_name,
1878 ShouldThrow should_throw);
1879 // ES6 9.1.6.3
1880 // |it| can be NULL in cases where the ES spec passes |undefined| as the
1881 // receiver. Exactly one of |it| and |property_name| must be provided.
1882 MUST_USE_RESULT static Maybe<bool> ValidateAndApplyPropertyDescriptor(
1883 Isolate* isolate, LookupIterator* it, bool extensible,
1884 PropertyDescriptor* desc, PropertyDescriptor* current,
1885 ShouldThrow should_throw, Handle<Name> property_name = Handle<Name>());
1886
1887 MUST_USE_RESULT static Maybe<bool> GetOwnPropertyDescriptor(
1888 Isolate* isolate, Handle<JSReceiver> object, Handle<Object> key,
1889 PropertyDescriptor* desc);
1890 MUST_USE_RESULT static Maybe<bool> GetOwnPropertyDescriptor(
1891 LookupIterator* it, PropertyDescriptor* desc);
1892
1893 typedef PropertyAttributes IntegrityLevel;
1894
1895 // ES6 7.3.14 (when passed DONT_THROW)
1896 // 'level' must be SEALED or FROZEN.
1897 MUST_USE_RESULT static Maybe<bool> SetIntegrityLevel(
1898 Handle<JSReceiver> object, IntegrityLevel lvl, ShouldThrow should_throw);
1899
1900 // ES6 7.3.15
1901 // 'level' must be SEALED or FROZEN.
1902 MUST_USE_RESULT static Maybe<bool> TestIntegrityLevel(
1903 Handle<JSReceiver> object, IntegrityLevel lvl);
1904
1905 // ES6 [[PreventExtensions]] (when passed DONT_THROW)
1906 MUST_USE_RESULT static Maybe<bool> PreventExtensions(
1907 Handle<JSReceiver> object, ShouldThrow should_throw);
1908
1909 MUST_USE_RESULT static Maybe<bool> IsExtensible(Handle<JSReceiver> object);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001910
1911 // Tests for the fast common case for property enumeration.
1912 bool IsSimpleEnum();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001913
1914 // Returns the class name ([[Class]] property in the specification).
1915 String* class_name();
1916
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001917 // Returns the builtin string tag used in Object.prototype.toString.
1918 MUST_USE_RESULT static MaybeHandle<String> BuiltinStringTag(
1919 Handle<JSReceiver> object);
1920
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001921 // Returns the constructor name (the name (possibly, inferred name) of the
1922 // function that was used to instantiate the object).
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001923 static Handle<String> GetConstructorName(Handle<JSReceiver> receiver);
1924
1925 Context* GetCreationContext();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001926
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001927 MUST_USE_RESULT static inline Maybe<PropertyAttributes> GetPropertyAttributes(
1928 Handle<JSReceiver> object, Handle<Name> name);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001929 MUST_USE_RESULT static inline Maybe<PropertyAttributes>
1930 GetOwnPropertyAttributes(Handle<JSReceiver> object, Handle<Name> name);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001931
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001932 MUST_USE_RESULT static inline Maybe<PropertyAttributes> GetElementAttributes(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001933 Handle<JSReceiver> object, uint32_t index);
1934 MUST_USE_RESULT static inline Maybe<PropertyAttributes>
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001935 GetOwnElementAttributes(Handle<JSReceiver> object, uint32_t index);
1936
1937 MUST_USE_RESULT static Maybe<PropertyAttributes> GetPropertyAttributes(
1938 LookupIterator* it);
1939
1940 // Set the object's prototype (only JSReceiver and null are allowed values).
1941 MUST_USE_RESULT static Maybe<bool> SetPrototype(Handle<JSReceiver> object,
1942 Handle<Object> value,
1943 bool from_javascript,
1944 ShouldThrow should_throw);
1945
1946
1947 static Handle<Object> GetDataProperty(Handle<JSReceiver> object,
1948 Handle<Name> name);
1949 static Handle<Object> GetDataProperty(LookupIterator* it);
1950
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001951
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001952 // Retrieves a permanent object identity hash code. The undefined value might
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001953 // be returned in case no hash was created yet.
1954 inline Object* GetIdentityHash();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001955
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001956 // Retrieves a permanent object identity hash code. May create and store a
1957 // hash code if needed and none exists.
1958 inline static Handle<Smi> GetOrCreateIdentityHash(
1959 Handle<JSReceiver> object);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001960
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001961 enum KeyCollectionType { OWN_ONLY, INCLUDE_PROTOS };
1962
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001963 // ES6 [[OwnPropertyKeys]] (modulo return type)
1964 MUST_USE_RESULT static MaybeHandle<FixedArray> OwnPropertyKeys(
1965 Handle<JSReceiver> object) {
1966 return GetKeys(object, JSReceiver::OWN_ONLY, ALL_PROPERTIES,
1967 CONVERT_TO_STRING);
1968 }
1969
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001970 // Computes the enumerable keys for a JSObject. Used for implementing
1971 // "for (n in object) { }".
1972 MUST_USE_RESULT static MaybeHandle<FixedArray> GetKeys(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001973 Handle<JSReceiver> object, KeyCollectionType type, PropertyFilter filter,
1974 GetKeysConversion keys_conversion = KEEP_NUMBERS);
1975
1976 // Layout description.
1977 static const int kPropertiesOffset = HeapObject::kHeaderSize;
1978 static const int kHeaderSize = HeapObject::kHeaderSize + kPointerSize;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001979
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001980 private:
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001981 DISALLOW_IMPLICIT_CONSTRUCTORS(JSReceiver);
1982};
1983
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001984
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001985// The JSObject describes real heap allocated JavaScript objects with
1986// properties.
1987// Note that the map of JSObject changes during execution to enable inline
1988// caching.
1989class JSObject: public JSReceiver {
1990 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001991 static MUST_USE_RESULT MaybeHandle<JSObject> New(
1992 Handle<JSFunction> constructor, Handle<JSReceiver> new_target,
1993 Handle<AllocationSite> site = Handle<AllocationSite>::null());
1994
1995 // Gets global object properties.
1996 inline GlobalDictionary* global_dictionary();
1997
1998 static MaybeHandle<Context> GetFunctionRealm(Handle<JSObject> object);
Steve Blocka7e24c12009-10-30 11:49:00 +00001999
2000 // [elements]: The elements (properties with names that are integers).
Iain Merrick75681382010-08-19 15:07:18 +01002001 //
2002 // Elements can be in two general modes: fast and slow. Each mode
2003 // corrensponds to a set of object representations of elements that
2004 // have something in common.
2005 //
2006 // In the fast mode elements is a FixedArray and so each element can
2007 // be quickly accessed. This fact is used in the generated code. The
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002008 // elements array can have one of three maps in this mode:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002009 // fixed_array_map, sloppy_arguments_elements_map or
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002010 // fixed_cow_array_map (for copy-on-write arrays). In the latter case
2011 // the elements array may be shared by a few objects and so before
2012 // writing to any element the array must be copied. Use
2013 // EnsureWritableFastElements in this case.
Iain Merrick75681382010-08-19 15:07:18 +01002014 //
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002015 // In the slow mode the elements is either a NumberDictionary, a
2016 // FixedArray parameter map for a (sloppy) arguments object.
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002017 DECL_ACCESSORS(elements, FixedArrayBase)
Steve Blocka7e24c12009-10-30 11:49:00 +00002018 inline void initialize_elements();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002019 static void ResetElements(Handle<JSObject> object);
2020 static inline void SetMapAndElements(Handle<JSObject> object,
2021 Handle<Map> map,
2022 Handle<FixedArrayBase> elements);
Steve Blocka7e24c12009-10-30 11:49:00 +00002023 inline ElementsKind GetElementsKind();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002024 ElementsAccessor* GetElementsAccessor();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002025 // Returns true if an object has elements of FAST_SMI_ELEMENTS ElementsKind.
2026 inline bool HasFastSmiElements();
2027 // Returns true if an object has elements of FAST_ELEMENTS ElementsKind.
2028 inline bool HasFastObjectElements();
2029 // Returns true if an object has elements of FAST_ELEMENTS or
2030 // FAST_SMI_ONLY_ELEMENTS.
2031 inline bool HasFastSmiOrObjectElements();
2032 // Returns true if an object has any of the fast elements kinds.
Steve Blocka7e24c12009-10-30 11:49:00 +00002033 inline bool HasFastElements();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002034 // Returns true if an object has elements of FAST_DOUBLE_ELEMENTS
2035 // ElementsKind.
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002036 inline bool HasFastDoubleElements();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002037 // Returns true if an object has elements of FAST_HOLEY_*_ELEMENTS
2038 // ElementsKind.
2039 inline bool HasFastHoleyElements();
2040 inline bool HasSloppyArgumentsElements();
Steve Blocka7e24c12009-10-30 11:49:00 +00002041 inline bool HasDictionaryElements();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002042
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002043 inline bool HasFixedTypedArrayElements();
2044
2045 inline bool HasFixedUint8ClampedElements();
2046 inline bool HasFixedArrayElements();
2047 inline bool HasFixedInt8Elements();
2048 inline bool HasFixedUint8Elements();
2049 inline bool HasFixedInt16Elements();
2050 inline bool HasFixedUint16Elements();
2051 inline bool HasFixedInt32Elements();
2052 inline bool HasFixedUint32Elements();
2053 inline bool HasFixedFloat32Elements();
2054 inline bool HasFixedFloat64Elements();
2055
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002056 inline bool HasFastArgumentsElements();
2057 inline bool HasSlowArgumentsElements();
Ben Murdochc7cc0282012-03-05 14:35:55 +00002058 inline SeededNumberDictionary* element_dictionary(); // Gets slow elements.
2059
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002060 // Requires: HasFastElements().
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002061 static Handle<FixedArray> EnsureWritableFastElements(
2062 Handle<JSObject> object);
Steve Blocka7e24c12009-10-30 11:49:00 +00002063
2064 // Collects elements starting at index 0.
2065 // Undefined values are placed after non-undefined values.
2066 // Returns the number of non-undefined values.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002067 static Handle<Object> PrepareElementsForSort(Handle<JSObject> object,
2068 uint32_t limit);
Steve Blocka7e24c12009-10-30 11:49:00 +00002069 // As PrepareElementsForSort, but only on objects where elements is
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002070 // a dictionary, and it will stay a dictionary. Collates undefined and
2071 // unexisting elements below limit from position zero of the elements.
2072 static Handle<Object> PrepareSlowElementsForSort(Handle<JSObject> object,
2073 uint32_t limit);
Steve Blocka7e24c12009-10-30 11:49:00 +00002074
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002075 MUST_USE_RESULT static Maybe<bool> SetPropertyWithInterceptor(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002076 LookupIterator* it, Handle<Object> value);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002077
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002078 // SetLocalPropertyIgnoreAttributes converts callbacks to fields. We need to
2079 // grant an exemption to ExecutableAccessor callbacks in some cases.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002080 enum ExecutableAccessorInfoHandling { DEFAULT_HANDLING, DONT_FORCE_FIELD };
2081
2082 MUST_USE_RESULT static MaybeHandle<Object> DefineOwnPropertyIgnoreAttributes(
2083 LookupIterator* it, Handle<Object> value, PropertyAttributes attributes,
2084 ExecutableAccessorInfoHandling handling = DEFAULT_HANDLING);
2085
2086 MUST_USE_RESULT static Maybe<bool> DefineOwnPropertyIgnoreAttributes(
2087 LookupIterator* it, Handle<Object> value, PropertyAttributes attributes,
2088 ShouldThrow should_throw,
2089 ExecutableAccessorInfoHandling handling = DEFAULT_HANDLING);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002090
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002091 MUST_USE_RESULT static MaybeHandle<Object> SetOwnPropertyIgnoreAttributes(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002092 Handle<JSObject> object, Handle<Name> name, Handle<Object> value,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002093 PropertyAttributes attributes,
2094 ExecutableAccessorInfoHandling handling = DEFAULT_HANDLING);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002095
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002096 MUST_USE_RESULT static MaybeHandle<Object> SetOwnElementIgnoreAttributes(
2097 Handle<JSObject> object, uint32_t index, Handle<Object> value,
2098 PropertyAttributes attributes,
2099 ExecutableAccessorInfoHandling handling = DEFAULT_HANDLING);
2100
2101 // Equivalent to one of the above depending on whether |name| can be converted
2102 // to an array index.
2103 MUST_USE_RESULT static MaybeHandle<Object>
2104 DefinePropertyOrElementIgnoreAttributes(
2105 Handle<JSObject> object, Handle<Name> name, Handle<Object> value,
2106 PropertyAttributes attributes = NONE,
2107 ExecutableAccessorInfoHandling handling = DEFAULT_HANDLING);
2108
2109 // Adds or reconfigures a property to attributes NONE. It will fail when it
2110 // cannot.
2111 MUST_USE_RESULT static Maybe<bool> CreateDataProperty(LookupIterator* it,
2112 Handle<Object> value);
2113
2114 static void AddProperty(Handle<JSObject> object, Handle<Name> name,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002115 Handle<Object> value, PropertyAttributes attributes);
Steve Blocka7e24c12009-10-30 11:49:00 +00002116
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002117 MUST_USE_RESULT static Maybe<bool> AddDataElement(
2118 Handle<JSObject> receiver, uint32_t index, Handle<Object> value,
2119 PropertyAttributes attributes, ShouldThrow should_throw);
2120 MUST_USE_RESULT static MaybeHandle<Object> AddDataElement(
2121 Handle<JSObject> receiver, uint32_t index, Handle<Object> value,
2122 PropertyAttributes attributes);
2123
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002124 // Extend the receiver with a single fast property appeared first in the
2125 // passed map. This also extends the property backing store if necessary.
2126 static void AllocateStorageForMap(Handle<JSObject> object, Handle<Map> map);
Steve Blocka7e24c12009-10-30 11:49:00 +00002127
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002128 // Migrates the given object to a map whose field representations are the
2129 // lowest upper bound of all known representations for that field.
2130 static void MigrateInstance(Handle<JSObject> instance);
2131
2132 // Migrates the given object only if the target map is already available,
2133 // or returns false if such a map is not yet available.
2134 static bool TryMigrateInstance(Handle<JSObject> instance);
Steve Blocka7e24c12009-10-30 11:49:00 +00002135
2136 // Sets the property value in a normalized object given (key, value, details).
2137 // Handles the special representation of JS global objects.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002138 static void SetNormalizedProperty(Handle<JSObject> object, Handle<Name> name,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002139 Handle<Object> value,
2140 PropertyDetails details);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002141 static void SetDictionaryElement(Handle<JSObject> object, uint32_t index,
2142 Handle<Object> value,
2143 PropertyAttributes attributes);
2144 static void SetDictionaryArgumentsElement(Handle<JSObject> object,
2145 uint32_t index,
2146 Handle<Object> value,
2147 PropertyAttributes attributes);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002148
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002149 static void OptimizeAsPrototype(Handle<JSObject> object,
2150 PrototypeOptimizationMode mode);
2151 static void ReoptimizeIfPrototype(Handle<JSObject> object);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002152 static void LazyRegisterPrototypeUser(Handle<Map> user, Isolate* isolate);
2153 static void UpdatePrototypeUserRegistration(Handle<Map> old_map,
2154 Handle<Map> new_map,
2155 Isolate* isolate);
2156 static bool UnregisterPrototypeUser(Handle<Map> user, Isolate* isolate);
2157 static void InvalidatePrototypeChains(Map* map);
2158
2159 // Alternative implementation of WeakFixedArray::NullCallback.
2160 class PrototypeRegistryCompactionCallback {
2161 public:
2162 static void Callback(Object* value, int old_index, int new_index);
2163 };
Steve Blocka7e24c12009-10-30 11:49:00 +00002164
Steve Blocka7e24c12009-10-30 11:49:00 +00002165 // Retrieve interceptors.
2166 InterceptorInfo* GetNamedInterceptor();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002167 inline InterceptorInfo* GetIndexedInterceptor();
Steve Blocka7e24c12009-10-30 11:49:00 +00002168
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002169 // Used from JSReceiver.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002170 MUST_USE_RESULT static Maybe<PropertyAttributes>
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002171 GetPropertyAttributesWithInterceptor(LookupIterator* it);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002172 MUST_USE_RESULT static Maybe<PropertyAttributes>
2173 GetPropertyAttributesWithFailedAccessCheck(LookupIterator* it);
Steve Blocka7e24c12009-10-30 11:49:00 +00002174
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002175 // Retrieves an AccessorPair property from the given object. Might return
2176 // undefined if the property doesn't exist or is of a different kind.
2177 MUST_USE_RESULT static MaybeHandle<Object> GetAccessor(
2178 Handle<JSObject> object,
2179 Handle<Name> name,
2180 AccessorComponent component);
Steve Blocka7e24c12009-10-30 11:49:00 +00002181
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002182 // Defines an AccessorPair property on the given object.
2183 // TODO(mstarzinger): Rename to SetAccessor().
2184 static MaybeHandle<Object> DefineAccessor(Handle<JSObject> object,
2185 Handle<Name> name,
2186 Handle<Object> getter,
2187 Handle<Object> setter,
2188 PropertyAttributes attributes);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002189 static MaybeHandle<Object> DefineAccessor(LookupIterator* it,
2190 Handle<Object> getter,
2191 Handle<Object> setter,
2192 PropertyAttributes attributes);
Leon Clarkef7060e22010-06-03 12:02:55 +01002193
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002194 // Defines an AccessorInfo property on the given object.
2195 MUST_USE_RESULT static MaybeHandle<Object> SetAccessor(
2196 Handle<JSObject> object,
2197 Handle<AccessorInfo> info);
2198
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002199 // The result must be checked first for exceptions. If there's no exception,
2200 // the output parameter |done| indicates whether the interceptor has a result
2201 // or not.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002202 MUST_USE_RESULT static MaybeHandle<Object> GetPropertyWithInterceptor(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002203 LookupIterator* it, bool* done);
Steve Blocka7e24c12009-10-30 11:49:00 +00002204
Steve Blockd0582a62009-12-15 09:54:21 +00002205 // Accessors for hidden properties object.
2206 //
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002207 // Hidden properties are not own properties of the object itself.
2208 // Instead they are stored in an auxiliary structure kept as an own
2209 // property with a special name Heap::hidden_string(). But if the
Steve Blockd0582a62009-12-15 09:54:21 +00002210 // receiver is a JSGlobalProxy then the auxiliary object is a property
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002211 // of its prototype, and if it's a detached proxy, then you can't have
2212 // hidden properties.
Steve Blockd0582a62009-12-15 09:54:21 +00002213
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002214 // Sets a hidden property on this object. Returns this object if successful,
2215 // undefined if called on a detached proxy.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002216 static Handle<Object> SetHiddenProperty(Handle<JSObject> object,
2217 Handle<Name> key,
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002218 Handle<Object> value);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002219 // Gets the value of a hidden property with the given key. Returns the hole
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002220 // if the property doesn't exist (or if called on a detached proxy),
2221 // otherwise returns the value set for the key.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002222 Object* GetHiddenProperty(Handle<Name> key);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002223 // Deletes a hidden property. Deleting a non-existing property is
2224 // considered successful.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002225 static void DeleteHiddenProperty(Handle<JSObject> object,
2226 Handle<Name> key);
2227 // Returns true if the object has a property with the hidden string as name.
2228 static bool HasHiddenProperties(Handle<JSObject> object);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002229
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002230 static void SetIdentityHash(Handle<JSObject> object, Handle<Smi> hash);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002231
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002232 static void ValidateElements(Handle<JSObject> object);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002233
2234 // Makes sure that this object can contain HeapObject as elements.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002235 static inline void EnsureCanContainHeapObjectElements(Handle<JSObject> obj);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002236
2237 // Makes sure that this object can contain the specified elements.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002238 static inline void EnsureCanContainElements(
2239 Handle<JSObject> object,
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002240 Object** elements,
2241 uint32_t count,
2242 EnsureElementsMode mode);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002243 static inline void EnsureCanContainElements(
2244 Handle<JSObject> object,
2245 Handle<FixedArrayBase> elements,
2246 uint32_t length,
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002247 EnsureElementsMode mode);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002248 static void EnsureCanContainElements(
2249 Handle<JSObject> object,
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002250 Arguments* arguments,
2251 uint32_t first_arg,
2252 uint32_t arg_count,
2253 EnsureElementsMode mode);
Steve Blocka7e24c12009-10-30 11:49:00 +00002254
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002255 // Would we convert a fast elements array to dictionary mode given
2256 // an access at key?
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002257 bool WouldConvertToSlowElements(uint32_t index);
Andrei Popescu402d9372010-02-26 13:31:12 +00002258
Ben Murdoche0cee9b2011-05-25 10:26:03 +01002259 // Computes the new capacity when expanding the elements of a JSObject.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002260 static uint32_t NewElementsCapacity(uint32_t old_capacity) {
Ben Murdoche0cee9b2011-05-25 10:26:03 +01002261 // (old_capacity + 50%) + 16
2262 return old_capacity + (old_capacity >> 1) + 16;
2263 }
2264
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002265 // These methods do not perform access checks!
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002266 static void UpdateAllocationSite(Handle<JSObject> object,
2267 ElementsKind to_kind);
Steve Blocka7e24c12009-10-30 11:49:00 +00002268
2269 // Lookup interceptors are used for handling properties controlled by host
2270 // objects.
2271 inline bool HasNamedInterceptor();
2272 inline bool HasIndexedInterceptor();
2273
2274 // Support functions for v8 api (needed for correct interceptor behavior).
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002275 MUST_USE_RESULT static Maybe<bool> HasRealNamedProperty(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002276 Handle<JSObject> object, Handle<Name> name);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002277 MUST_USE_RESULT static Maybe<bool> HasRealElementProperty(
2278 Handle<JSObject> object, uint32_t index);
2279 MUST_USE_RESULT static Maybe<bool> HasRealNamedCallbackProperty(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002280 Handle<JSObject> object, Handle<Name> name);
Steve Blocka7e24c12009-10-30 11:49:00 +00002281
Steve Blocka7e24c12009-10-30 11:49:00 +00002282 // Get the header size for a JSObject. Used to compute the index of
2283 // internal fields as well as the number of internal fields.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002284 static inline int GetHeaderSize(InstanceType instance_type);
Steve Blocka7e24c12009-10-30 11:49:00 +00002285 inline int GetHeaderSize();
2286
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002287 static inline int GetInternalFieldCount(Map* map);
Steve Blocka7e24c12009-10-30 11:49:00 +00002288 inline int GetInternalFieldCount();
Steve Block44f0eee2011-05-26 01:26:41 +01002289 inline int GetInternalFieldOffset(int index);
Steve Blocka7e24c12009-10-30 11:49:00 +00002290 inline Object* GetInternalField(int index);
2291 inline void SetInternalField(int index, Object* value);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002292 inline void SetInternalField(int index, Smi* value);
Steve Blocka7e24c12009-10-30 11:49:00 +00002293
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002294 void CollectOwnPropertyNames(KeyAccumulator* keys,
2295 PropertyFilter filter = ALL_PROPERTIES);
Steve Blocka7e24c12009-10-30 11:49:00 +00002296
2297 // Returns the number of properties on this object filtering out properties
2298 // with the specified attributes (ignoring interceptors).
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002299 // TODO(jkummerow): Deprecated, only used by Object.observe.
2300 int NumberOfOwnElements(PropertyFilter filter);
Steve Blocka7e24c12009-10-30 11:49:00 +00002301 // Returns the number of elements on this object filtering out elements
2302 // with the specified attributes (ignoring interceptors).
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002303 // TODO(jkummerow): Deprecated, only used by Object.observe.
2304 int GetOwnElementKeys(FixedArray* storage, PropertyFilter filter);
2305
2306 static void CollectOwnElementKeys(Handle<JSObject> object,
2307 KeyAccumulator* keys,
2308 PropertyFilter filter);
2309
2310 static Handle<FixedArray> GetEnumPropertyKeys(Handle<JSObject> object,
2311 bool cache_result);
Steve Blocka7e24c12009-10-30 11:49:00 +00002312
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002313 // Returns a new map with all transitions dropped from the object's current
2314 // map and the ElementsKind set.
2315 static Handle<Map> GetElementsTransitionMap(Handle<JSObject> object,
2316 ElementsKind to_kind);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002317 static void TransitionElementsKind(Handle<JSObject> object,
2318 ElementsKind to_kind);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002319
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002320 // Always use this to migrate an object to a new map.
2321 // |expected_additional_properties| is only used for fast-to-slow transitions
2322 // and ignored otherwise.
2323 static void MigrateToMap(Handle<JSObject> object, Handle<Map> new_map,
2324 int expected_additional_properties = 0);
Steve Blocka7e24c12009-10-30 11:49:00 +00002325
2326 // Convert the object to use the canonical dictionary
2327 // representation. If the object is expected to have additional properties
2328 // added this number can be indicated to have the backing store allocated to
2329 // an initial capacity for holding these properties.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002330 static void NormalizeProperties(Handle<JSObject> object,
2331 PropertyNormalizationMode mode,
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002332 int expected_additional_properties,
2333 const char* reason);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002334
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002335 // Convert and update the elements backing store to be a
2336 // SeededNumberDictionary dictionary. Returns the backing after conversion.
2337 static Handle<SeededNumberDictionary> NormalizeElements(
2338 Handle<JSObject> object);
2339
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002340 void RequireSlowElements(SeededNumberDictionary* dictionary);
2341
Steve Blocka7e24c12009-10-30 11:49:00 +00002342 // Transform slow named properties to fast variants.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002343 static void MigrateSlowToFast(Handle<JSObject> object,
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002344 int unused_property_fields, const char* reason);
2345
2346 inline bool IsUnboxedDoubleField(FieldIndex index);
Steve Blocka7e24c12009-10-30 11:49:00 +00002347
2348 // Access fast-case object properties at index.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002349 static Handle<Object> FastPropertyAt(Handle<JSObject> object,
2350 Representation representation,
2351 FieldIndex index);
2352 inline Object* RawFastPropertyAt(FieldIndex index);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002353 inline double RawFastDoublePropertyAt(FieldIndex index);
2354
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002355 inline void FastPropertyAtPut(FieldIndex index, Object* value);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002356 inline void RawFastPropertyAtPut(FieldIndex index, Object* value);
2357 inline void RawFastDoublePropertyAtPut(FieldIndex index, double value);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002358 inline void WriteToField(int descriptor, Object* value);
Steve Blocka7e24c12009-10-30 11:49:00 +00002359
2360 // Access to in object properties.
Steve Block44f0eee2011-05-26 01:26:41 +01002361 inline int GetInObjectPropertyOffset(int index);
Steve Blocka7e24c12009-10-30 11:49:00 +00002362 inline Object* InObjectPropertyAt(int index);
2363 inline Object* InObjectPropertyAtPut(int index,
2364 Object* value,
2365 WriteBarrierMode mode
2366 = UPDATE_WRITE_BARRIER);
2367
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002368 // Set the object's prototype (only JSReceiver and null are allowed values).
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002369 MUST_USE_RESULT static Maybe<bool> SetPrototype(Handle<JSObject> object,
2370 Handle<Object> value,
2371 bool from_javascript,
2372 ShouldThrow should_throw);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002373
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002374 // Initializes the body starting at |start_offset|. It is responsibility of
2375 // the caller to initialize object header. Fill the pre-allocated fields with
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002376 // pre_allocated_value and the rest with filler_value.
2377 // Note: this call does not update write barrier, the caller is responsible
2378 // to ensure that |filler_value| can be collected without WB here.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002379 inline void InitializeBody(Map* map, int start_offset,
2380 Object* pre_allocated_value, Object* filler_value);
Steve Blocka7e24c12009-10-30 11:49:00 +00002381
2382 // Check whether this object references another object
2383 bool ReferencesObject(Object* obj);
2384
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002385 MUST_USE_RESULT static Maybe<bool> PreventExtensions(
2386 Handle<JSObject> object, ShouldThrow should_throw);
Steve Block8defd9f2010-07-08 12:39:36 +01002387
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002388 static bool IsExtensible(Handle<JSObject> object);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002389
2390 // Called the first time an object is observed with ES7 Object.observe.
2391 static void SetObserved(Handle<JSObject> object);
2392
2393 // Copy object.
2394 enum DeepCopyHints { kNoHints = 0, kObjectIsShallow = 1 };
2395
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002396 MUST_USE_RESULT static MaybeHandle<JSObject> DeepCopy(
2397 Handle<JSObject> object,
2398 AllocationSiteUsageContext* site_context,
2399 DeepCopyHints hints = kNoHints);
2400 MUST_USE_RESULT static MaybeHandle<JSObject> DeepWalk(
2401 Handle<JSObject> object,
2402 AllocationSiteCreationContext* site_context);
2403
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002404 DECLARE_CAST(JSObject)
Steve Block8defd9f2010-07-08 12:39:36 +01002405
Steve Blocka7e24c12009-10-30 11:49:00 +00002406 // Dispatched behavior.
Steve Blocka7e24c12009-10-30 11:49:00 +00002407 void JSObjectShortPrint(StringStream* accumulator);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002408 DECLARE_PRINTER(JSObject)
2409 DECLARE_VERIFIER(JSObject)
Ben Murdochb0fe1622011-05-05 13:52:32 +01002410#ifdef OBJECT_PRINT
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002411 void PrintProperties(std::ostream& os); // NOLINT
2412 void PrintElements(std::ostream& os); // NOLINT
2413#endif
2414#if defined(DEBUG) || defined(OBJECT_PRINT)
2415 void PrintTransitions(std::ostream& os); // NOLINT
Ben Murdochb0fe1622011-05-05 13:52:32 +01002416#endif
2417
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002418 static void PrintElementsTransition(
2419 FILE* file, Handle<JSObject> object,
2420 ElementsKind from_kind, Handle<FixedArrayBase> from_elements,
2421 ElementsKind to_kind, Handle<FixedArrayBase> to_elements);
2422
2423 void PrintInstanceMigration(FILE* file, Map* original_map, Map* new_map);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002424
Ben Murdochb0fe1622011-05-05 13:52:32 +01002425#ifdef DEBUG
Steve Blocka7e24c12009-10-30 11:49:00 +00002426 // Structure for collecting spill information about JSObjects.
2427 class SpillInformation {
2428 public:
2429 void Clear();
2430 void Print();
2431 int number_of_objects_;
2432 int number_of_objects_with_fast_properties_;
2433 int number_of_objects_with_fast_elements_;
2434 int number_of_fast_used_fields_;
2435 int number_of_fast_unused_fields_;
2436 int number_of_slow_used_properties_;
2437 int number_of_slow_unused_properties_;
2438 int number_of_fast_used_elements_;
2439 int number_of_fast_unused_elements_;
2440 int number_of_slow_used_elements_;
2441 int number_of_slow_unused_elements_;
2442 };
2443
2444 void IncrementSpillStatistics(SpillInformation* info);
2445#endif
Steve Blocka7e24c12009-10-30 11:49:00 +00002446
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002447#ifdef VERIFY_HEAP
2448 // If a GC was caused while constructing this object, the elements pointer
2449 // may point to a one pointer filler map. The object won't be rooted, but
2450 // our heap verification code could stumble across it.
2451 bool ElementsAreSafeToExamine();
2452#endif
2453
2454 Object* SlowReverseLookup(Object* value);
Steve Block8defd9f2010-07-08 12:39:36 +01002455
Leon Clarkee46be812010-01-19 14:06:41 +00002456 // Maximal number of elements (numbered 0 .. kMaxElementCount - 1).
2457 // Also maximal value of JSArray's length property.
2458 static const uint32_t kMaxElementCount = 0xffffffffu;
2459
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002460 // Constants for heuristics controlling conversion of fast elements
2461 // to slow elements.
2462
2463 // Maximal gap that can be introduced by adding an element beyond
2464 // the current elements length.
Steve Blocka7e24c12009-10-30 11:49:00 +00002465 static const uint32_t kMaxGap = 1024;
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002466
2467 // Maximal length of fast elements array that won't be checked for
2468 // being dense enough on expansion.
2469 static const int kMaxUncheckedFastElementsLength = 5000;
2470
2471 // Same as above but for old arrays. This limit is more strict. We
2472 // don't want to be wasteful with long lived objects.
2473 static const int kMaxUncheckedOldFastElementsLength = 500;
2474
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002475 // This constant applies only to the initial map of "global.Object" and
2476 // not to arbitrary other JSObject maps.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002477 static const int kInitialGlobalObjectUnusedPropertiesCount = 4;
2478
Steve Blocka7e24c12009-10-30 11:49:00 +00002479 static const int kMaxInstanceSize = 255 * kPointerSize;
2480 // When extending the backing storage for property values, we increase
2481 // its size by more than the 1 entry necessary, so sequentially adding fields
2482 // to the same object requires fewer allocations and copies.
2483 static const int kFieldsAdded = 3;
2484
2485 // Layout description.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002486 static const int kElementsOffset = JSReceiver::kHeaderSize;
Steve Blocka7e24c12009-10-30 11:49:00 +00002487 static const int kHeaderSize = kElementsOffset + kPointerSize;
2488
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002489 STATIC_ASSERT(kHeaderSize == Internals::kJSObjectHeaderSize);
Steve Blocka7e24c12009-10-30 11:49:00 +00002490
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002491 typedef FlexibleBodyDescriptor<JSReceiver::kPropertiesOffset> BodyDescriptor;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002492
2493 // Enqueue change record for Object.observe. May cause GC.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002494 MUST_USE_RESULT static MaybeHandle<Object> EnqueueChangeRecord(
2495 Handle<JSObject> object, const char* type, Handle<Name> name,
2496 Handle<Object> old_value);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002497
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002498 // Gets the number of currently used elements.
2499 int GetFastElementsUsage();
2500
2501 static bool AllCanRead(LookupIterator* it);
2502 static bool AllCanWrite(LookupIterator* it);
2503
Steve Blocka7e24c12009-10-30 11:49:00 +00002504 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002505 friend class JSReceiver;
2506 friend class Object;
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002507
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002508 static void MigrateFastToFast(Handle<JSObject> object, Handle<Map> new_map);
2509 static void MigrateFastToSlow(Handle<JSObject> object,
2510 Handle<Map> new_map,
2511 int expected_additional_properties);
2512
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002513 // Used from Object::GetProperty().
2514 MUST_USE_RESULT static MaybeHandle<Object> GetPropertyWithFailedAccessCheck(
2515 LookupIterator* it);
2516
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002517 MUST_USE_RESULT static Maybe<bool> SetPropertyWithFailedAccessCheck(
2518 LookupIterator* it, Handle<Object> value, ShouldThrow should_throw);
Steve Blocka7e24c12009-10-30 11:49:00 +00002519
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002520 // Add a property to a slow-case object.
2521 static void AddSlowProperty(Handle<JSObject> object,
2522 Handle<Name> name,
2523 Handle<Object> value,
2524 PropertyAttributes attributes);
Steve Blocka7e24c12009-10-30 11:49:00 +00002525
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002526 MUST_USE_RESULT static Maybe<bool> DeletePropertyWithInterceptor(
2527 LookupIterator* it);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002528
2529 bool ReferencesObjectFromElements(FixedArray* elements,
2530 ElementsKind kind,
2531 Object* object);
Steve Blocka7e24c12009-10-30 11:49:00 +00002532
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002533 // Return the hash table backing store or the inline stored identity hash,
2534 // whatever is found.
2535 MUST_USE_RESULT Object* GetHiddenPropertiesHashTable();
2536
2537 // Return the hash table backing store for hidden properties. If there is no
2538 // backing store, allocate one.
2539 static Handle<ObjectHashTable> GetOrCreateHiddenPropertiesHashtable(
2540 Handle<JSObject> object);
2541
2542 // Set the hidden property backing store to either a hash table or
2543 // the inline-stored identity hash.
2544 static Handle<Object> SetHiddenPropertiesHashTable(
2545 Handle<JSObject> object,
2546 Handle<Object> value);
2547
2548 MUST_USE_RESULT Object* GetIdentityHash();
2549
2550 static Handle<Smi> GetOrCreateIdentityHash(Handle<JSObject> object);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002551
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002552 static Handle<SeededNumberDictionary> GetNormalizedElementDictionary(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002553 Handle<JSObject> object, Handle<FixedArrayBase> elements);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002554
2555 // Helper for fast versions of preventExtensions, seal, and freeze.
2556 // attrs is one of NONE, SEALED, or FROZEN (depending on the operation).
2557 template <PropertyAttributes attrs>
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002558 MUST_USE_RESULT static Maybe<bool> PreventExtensionsWithTransition(
2559 Handle<JSObject> object, ShouldThrow should_throw);
2560
2561 MUST_USE_RESULT static Maybe<bool> SetPrototypeUnobserved(
2562 Handle<JSObject> object, Handle<Object> value, bool from_javascript,
2563 ShouldThrow should_throw);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002564
Steve Blocka7e24c12009-10-30 11:49:00 +00002565 DISALLOW_IMPLICIT_CONSTRUCTORS(JSObject);
2566};
2567
2568
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002569// Common superclass for FixedArrays that allow implementations to share
2570// common accessors and some code paths.
2571class FixedArrayBase: public HeapObject {
Steve Blocka7e24c12009-10-30 11:49:00 +00002572 public:
2573 // [length]: length of the array.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002574 inline int length() const;
Steve Blocka7e24c12009-10-30 11:49:00 +00002575 inline void set_length(int value);
2576
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002577 // Get and set the length using acquire loads and release stores.
2578 inline int synchronized_length() const;
2579 inline void synchronized_set_length(int value);
2580
2581 DECLARE_CAST(FixedArrayBase)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002582
2583 // Layout description.
2584 // Length is smi tagged when it is stored.
2585 static const int kLengthOffset = HeapObject::kHeaderSize;
2586 static const int kHeaderSize = kLengthOffset + kPointerSize;
2587};
2588
2589
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002590class FixedDoubleArray;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002591class IncrementalMarking;
2592
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002593
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002594// FixedArray describes fixed-sized arrays with element type Object*.
2595class FixedArray: public FixedArrayBase {
2596 public:
Steve Blocka7e24c12009-10-30 11:49:00 +00002597 // Setter and getter for elements.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002598 inline Object* get(int index) const;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002599 static inline Handle<Object> get(Handle<FixedArray> array, int index);
Steve Blocka7e24c12009-10-30 11:49:00 +00002600 // Setter that uses write barrier.
2601 inline void set(int index, Object* value);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002602 inline bool is_the_hole(int index);
Steve Blocka7e24c12009-10-30 11:49:00 +00002603
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002604 // Setter that doesn't need write barrier.
Steve Blocka7e24c12009-10-30 11:49:00 +00002605 inline void set(int index, Smi* value);
2606 // Setter with explicit barrier mode.
2607 inline void set(int index, Object* value, WriteBarrierMode mode);
2608
2609 // Setters for frequently used oddballs located in old space.
2610 inline void set_undefined(int index);
2611 inline void set_null(int index);
2612 inline void set_the_hole(int index);
2613
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002614 inline Object** GetFirstElementAddress();
2615 inline bool ContainsOnlySmisOrHoles();
2616
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002617 // Gives access to raw memory which stores the array's data.
2618 inline Object** data_start();
2619
2620 inline void FillWithHoles(int from, int to);
2621
2622 // Shrink length and insert filler objects.
2623 void Shrink(int length);
2624
Steve Blocka7e24c12009-10-30 11:49:00 +00002625 // Copy a sub array from the receiver to dest.
2626 void CopyTo(int pos, FixedArray* dest, int dest_pos, int len);
2627
2628 // Garbage collection support.
2629 static int SizeFor(int length) { return kHeaderSize + length * kPointerSize; }
2630
2631 // Code Generation support.
2632 static int OffsetOfElementAt(int index) { return SizeFor(index); }
2633
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002634 // Garbage collection support.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002635 inline Object** RawFieldOfElementAt(int index);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002636
2637 DECLARE_CAST(FixedArray)
Steve Blocka7e24c12009-10-30 11:49:00 +00002638
Leon Clarkee46be812010-01-19 14:06:41 +00002639 // Maximal allowed size, in bytes, of a single FixedArray.
2640 // Prevents overflowing size computations, as well as extreme memory
2641 // consumption.
Ben Murdoch692be652012-01-10 18:47:50 +00002642 static const int kMaxSize = 128 * MB * kPointerSize;
Leon Clarkee46be812010-01-19 14:06:41 +00002643 // Maximally allowed length of a FixedArray.
2644 static const int kMaxLength = (kMaxSize - kHeaderSize) / kPointerSize;
Steve Blocka7e24c12009-10-30 11:49:00 +00002645
2646 // Dispatched behavior.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002647 DECLARE_PRINTER(FixedArray)
2648 DECLARE_VERIFIER(FixedArray)
Steve Blocka7e24c12009-10-30 11:49:00 +00002649#ifdef DEBUG
Steve Blocka7e24c12009-10-30 11:49:00 +00002650 // Checks if two FixedArrays have identical contents.
2651 bool IsEqualTo(FixedArray* other);
2652#endif
2653
2654 // Swap two elements in a pair of arrays. If this array and the
2655 // numbers array are the same object, the elements are only swapped
2656 // once.
2657 void SwapPairs(FixedArray* numbers, int i, int j);
2658
2659 // Sort prefix of this array and the numbers array as pairs wrt. the
2660 // numbers. If the numbers array and the this array are the same
2661 // object, the prefix of this array is sorted.
2662 void SortPairs(FixedArray* numbers, uint32_t len);
2663
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002664 typedef FlexibleBodyDescriptor<kHeaderSize> BodyDescriptor;
Iain Merrick75681382010-08-19 15:07:18 +01002665
Steve Blocka7e24c12009-10-30 11:49:00 +00002666 protected:
Leon Clarke4515c472010-02-03 11:58:03 +00002667 // Set operation on FixedArray without using write barriers. Can
2668 // only be used for storing old space objects or smis.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002669 static inline void NoWriteBarrierSet(FixedArray* array,
2670 int index,
2671 Object* value);
2672
Steve Blocka7e24c12009-10-30 11:49:00 +00002673 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002674 STATIC_ASSERT(kHeaderSize == Internals::kFixedArrayHeaderSize);
2675
Steve Blocka7e24c12009-10-30 11:49:00 +00002676 DISALLOW_IMPLICIT_CONSTRUCTORS(FixedArray);
2677};
2678
2679
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002680// FixedDoubleArray describes fixed-sized arrays with element type double.
2681class FixedDoubleArray: public FixedArrayBase {
2682 public:
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002683 // Setter and getter for elements.
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002684 inline double get_scalar(int index);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002685 inline uint64_t get_representation(int index);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002686 static inline Handle<Object> get(Handle<FixedDoubleArray> array, int index);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002687 inline void set(int index, double value);
2688 inline void set_the_hole(int index);
2689
2690 // Checking for the hole.
2691 inline bool is_the_hole(int index);
2692
2693 // Garbage collection support.
2694 inline static int SizeFor(int length) {
2695 return kHeaderSize + length * kDoubleSize;
2696 }
2697
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002698 // Gives access to raw memory which stores the array's data.
2699 inline double* data_start();
2700
2701 inline void FillWithHoles(int from, int to);
2702
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002703 // Code Generation support.
2704 static int OffsetOfElementAt(int index) { return SizeFor(index); }
2705
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002706 DECLARE_CAST(FixedDoubleArray)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002707
2708 // Maximal allowed size, in bytes, of a single FixedDoubleArray.
2709 // Prevents overflowing size computations, as well as extreme memory
2710 // consumption.
2711 static const int kMaxSize = 512 * MB;
2712 // Maximally allowed length of a FixedArray.
2713 static const int kMaxLength = (kMaxSize - kHeaderSize) / kDoubleSize;
2714
2715 // Dispatched behavior.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002716 DECLARE_PRINTER(FixedDoubleArray)
2717 DECLARE_VERIFIER(FixedDoubleArray)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002718
2719 private:
2720 DISALLOW_IMPLICIT_CONSTRUCTORS(FixedDoubleArray);
2721};
2722
2723
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002724class WeakFixedArray : public FixedArray {
2725 public:
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002726 // If |maybe_array| is not a WeakFixedArray, a fresh one will be allocated.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002727 // This function does not check if the value exists already, callers must
2728 // ensure this themselves if necessary.
2729 static Handle<WeakFixedArray> Add(Handle<Object> maybe_array,
2730 Handle<HeapObject> value,
2731 int* assigned_index = NULL);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002732
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002733 // Returns true if an entry was found and removed.
2734 bool Remove(Handle<HeapObject> value);
2735
2736 class NullCallback {
2737 public:
2738 static void Callback(Object* value, int old_index, int new_index) {}
2739 };
2740
2741 template <class CompactionCallback>
2742 void Compact();
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002743
2744 inline Object* Get(int index) const;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002745 inline void Clear(int index);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002746 inline int Length() const;
2747
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002748 inline bool IsEmptySlot(int index) const;
2749 static Object* Empty() { return Smi::FromInt(0); }
2750
2751 class Iterator {
2752 public:
2753 explicit Iterator(Object* maybe_array) : list_(NULL) { Reset(maybe_array); }
2754 void Reset(Object* maybe_array);
2755
2756 template <class T>
2757 inline T* Next();
2758
2759 private:
2760 int index_;
2761 WeakFixedArray* list_;
2762#ifdef DEBUG
2763 int last_used_index_;
2764 DisallowHeapAllocation no_gc_;
2765#endif // DEBUG
2766 DISALLOW_COPY_AND_ASSIGN(Iterator);
2767 };
2768
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002769 DECLARE_CAST(WeakFixedArray)
2770
2771 private:
2772 static const int kLastUsedIndexIndex = 0;
2773 static const int kFirstIndex = 1;
2774
2775 static Handle<WeakFixedArray> Allocate(
2776 Isolate* isolate, int size, Handle<WeakFixedArray> initialize_from);
2777
2778 static void Set(Handle<WeakFixedArray> array, int index,
2779 Handle<HeapObject> value);
2780 inline void clear(int index);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002781
2782 inline int last_used_index() const;
2783 inline void set_last_used_index(int index);
2784
2785 // Disallow inherited setters.
2786 void set(int index, Smi* value);
2787 void set(int index, Object* value);
2788 void set(int index, Object* value, WriteBarrierMode mode);
2789 DISALLOW_IMPLICIT_CONSTRUCTORS(WeakFixedArray);
2790};
2791
2792
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002793// Generic array grows dynamically with O(1) amortized insertion.
2794class ArrayList : public FixedArray {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002795 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002796 enum AddMode {
2797 kNone,
2798 // Use this if GC can delete elements from the array.
2799 kReloadLengthAfterAllocation,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002800 };
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002801 static Handle<ArrayList> Add(Handle<ArrayList> array, Handle<Object> obj,
2802 AddMode mode = kNone);
2803 static Handle<ArrayList> Add(Handle<ArrayList> array, Handle<Object> obj1,
2804 Handle<Object> obj2, AddMode = kNone);
2805 inline int Length();
2806 inline void SetLength(int length);
2807 inline Object* Get(int index);
2808 inline Object** Slot(int index);
2809 inline void Set(int index, Object* obj);
2810 inline void Clear(int index, Object* undefined);
2811 bool IsFull();
2812 DECLARE_CAST(ArrayList)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002813
2814 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002815 static Handle<ArrayList> EnsureSpace(Handle<ArrayList> array, int length);
2816 static const int kLengthIndex = 0;
2817 static const int kFirstIndex = 1;
2818 DISALLOW_IMPLICIT_CONSTRUCTORS(ArrayList);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002819};
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002820
2821
Steve Blocka7e24c12009-10-30 11:49:00 +00002822// DescriptorArrays are fixed arrays used to hold instance descriptors.
2823// The format of the these objects is:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002824// [0]: Number of descriptors
2825// [1]: Either Smi(0) if uninitialized, or a pointer to small fixed array:
2826// [0]: pointer to fixed array with enum cache
2827// [1]: either Smi(0) or pointer to fixed array with indices
2828// [2]: first key
2829// [2 + number of descriptors * kDescriptorSize]: start of slack
Steve Blocka7e24c12009-10-30 11:49:00 +00002830class DescriptorArray: public FixedArray {
2831 public:
Ben Murdoch257744e2011-11-30 15:57:28 +00002832 // Returns true for both shared empty_descriptor_array and for smis, which the
2833 // map uses to encode additional bit fields when the descriptor array is not
2834 // yet used.
Steve Blocka7e24c12009-10-30 11:49:00 +00002835 inline bool IsEmpty();
Leon Clarkee46be812010-01-19 14:06:41 +00002836
Steve Blocka7e24c12009-10-30 11:49:00 +00002837 // Returns the number of descriptors in the array.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002838 inline int number_of_descriptors();
Steve Blocka7e24c12009-10-30 11:49:00 +00002839
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002840 inline int number_of_descriptors_storage();
Steve Blocka7e24c12009-10-30 11:49:00 +00002841
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002842 inline int NumberOfSlackDescriptors();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002843
2844 inline void SetNumberOfDescriptors(int number_of_descriptors);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002845 inline int number_of_entries();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002846
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002847 inline bool HasEnumCache();
Steve Blocka7e24c12009-10-30 11:49:00 +00002848
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002849 inline void CopyEnumCacheFrom(DescriptorArray* array);
Steve Blocka7e24c12009-10-30 11:49:00 +00002850
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002851 inline FixedArray* GetEnumCache();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002852
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002853 inline bool HasEnumIndicesCache();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002854
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002855 inline FixedArray* GetEnumIndicesCache();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002856
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002857 inline Object** GetEnumCacheSlot();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002858
2859 void ClearEnumCache();
Ben Murdoch257744e2011-11-30 15:57:28 +00002860
Steve Blocka7e24c12009-10-30 11:49:00 +00002861 // Initialize or change the enum cache,
2862 // using the supplied storage for the small "bridge".
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002863 static void SetEnumCache(Handle<DescriptorArray> descriptors,
2864 Isolate* isolate, Handle<FixedArray> new_cache,
2865 Handle<FixedArray> new_index_cache);
Steve Blocka7e24c12009-10-30 11:49:00 +00002866
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002867 bool CanHoldValue(int descriptor, Object* value);
2868
Steve Blocka7e24c12009-10-30 11:49:00 +00002869 // Accessors for fetching instance descriptor at descriptor number.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002870 inline Name* GetKey(int descriptor_number);
2871 inline Object** GetKeySlot(int descriptor_number);
Steve Blocka7e24c12009-10-30 11:49:00 +00002872 inline Object* GetValue(int descriptor_number);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002873 inline void SetValue(int descriptor_number, Object* value);
2874 inline Object** GetValueSlot(int descriptor_number);
2875 static inline int GetValueOffset(int descriptor_number);
2876 inline Object** GetDescriptorStartSlot(int descriptor_number);
2877 inline Object** GetDescriptorEndSlot(int descriptor_number);
2878 inline PropertyDetails GetDetails(int descriptor_number);
Steve Blocka7e24c12009-10-30 11:49:00 +00002879 inline PropertyType GetType(int descriptor_number);
2880 inline int GetFieldIndex(int descriptor_number);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002881 inline HeapType* GetFieldType(int descriptor_number);
2882 inline Object* GetConstant(int descriptor_number);
Steve Blocka7e24c12009-10-30 11:49:00 +00002883 inline Object* GetCallbacksObject(int descriptor_number);
2884 inline AccessorDescriptor* GetCallbacks(int descriptor_number);
Steve Blocka7e24c12009-10-30 11:49:00 +00002885
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002886 inline Name* GetSortedKey(int descriptor_number);
2887 inline int GetSortedKeyIndex(int descriptor_number);
2888 inline void SetSortedKey(int pointer, int descriptor_number);
2889 inline void SetRepresentation(int descriptor_number,
2890 Representation representation);
2891
2892 // Accessor for complete descriptor.
2893 inline void Get(int descriptor_number, Descriptor* desc);
2894 inline void Set(int descriptor_number, Descriptor* desc);
2895 void Replace(int descriptor_number, Descriptor* descriptor);
2896
2897 // Append automatically sets the enumeration index. This should only be used
2898 // to add descriptors in bulk at the end, followed by sorting the descriptor
2899 // array.
2900 inline void Append(Descriptor* desc);
2901
2902 static Handle<DescriptorArray> CopyUpTo(Handle<DescriptorArray> desc,
2903 int enumeration_index,
2904 int slack = 0);
2905
2906 static Handle<DescriptorArray> CopyUpToAddAttributes(
2907 Handle<DescriptorArray> desc,
2908 int enumeration_index,
2909 PropertyAttributes attributes,
2910 int slack = 0);
2911
2912 // Sort the instance descriptors by the hash codes of their keys.
2913 void Sort();
2914
2915 // Search the instance descriptors for given name.
2916 INLINE(int Search(Name* name, int number_of_own_descriptors));
2917
2918 // As the above, but uses DescriptorLookupCache and updates it when
2919 // necessary.
2920 INLINE(int SearchWithCache(Name* name, Map* map));
2921
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002922 bool IsEqualUpTo(DescriptorArray* desc, int nof_descriptors);
2923
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002924 // Allocates a DescriptorArray, but returns the singleton
2925 // empty descriptor array object if number_of_descriptors is 0.
2926 static Handle<DescriptorArray> Allocate(Isolate* isolate,
2927 int number_of_descriptors,
2928 int slack = 0);
2929
2930 DECLARE_CAST(DescriptorArray)
2931
2932 // Constant for denoting key was not found.
2933 static const int kNotFound = -1;
2934
2935 static const int kDescriptorLengthIndex = 0;
2936 static const int kEnumCacheIndex = 1;
2937 static const int kFirstIndex = 2;
2938
2939 // The length of the "bridge" to the enum cache.
2940 static const int kEnumCacheBridgeLength = 2;
2941 static const int kEnumCacheBridgeCacheIndex = 0;
2942 static const int kEnumCacheBridgeIndicesCacheIndex = 1;
2943
2944 // Layout description.
2945 static const int kDescriptorLengthOffset = FixedArray::kHeaderSize;
2946 static const int kEnumCacheOffset = kDescriptorLengthOffset + kPointerSize;
2947 static const int kFirstOffset = kEnumCacheOffset + kPointerSize;
2948
2949 // Layout description for the bridge array.
2950 static const int kEnumCacheBridgeCacheOffset = FixedArray::kHeaderSize;
2951
2952 // Layout of descriptor.
2953 static const int kDescriptorKey = 0;
2954 static const int kDescriptorDetails = 1;
2955 static const int kDescriptorValue = 2;
2956 static const int kDescriptorSize = 3;
2957
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002958#if defined(DEBUG) || defined(OBJECT_PRINT)
2959 // For our gdb macros, we should perhaps change these in the future.
2960 void Print();
2961
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002962 // Print all the descriptors.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002963 void PrintDescriptors(std::ostream& os); // NOLINT
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002964#endif
2965
2966#ifdef DEBUG
2967 // Is the descriptor array sorted and without duplicates?
2968 bool IsSortedNoDuplicates(int valid_descriptors = -1);
2969
2970 // Is the descriptor array consistent with the back pointers in targets?
2971 bool IsConsistentWithBackPointers(Map* current_map);
2972
2973 // Are two DescriptorArrays equal?
2974 bool IsEqualTo(DescriptorArray* other);
2975#endif
2976
2977 // Returns the fixed array length required to hold number_of_descriptors
2978 // descriptors.
2979 static int LengthFor(int number_of_descriptors) {
2980 return ToKeyIndex(number_of_descriptors);
2981 }
2982
2983 private:
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002984 // An entry in a DescriptorArray, represented as an (array, index) pair.
2985 class Entry {
2986 public:
2987 inline explicit Entry(DescriptorArray* descs, int index) :
2988 descs_(descs), index_(index) { }
2989
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002990 inline PropertyType type();
2991 inline Object* GetCallbackObject();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002992
2993 private:
2994 DescriptorArray* descs_;
2995 int index_;
2996 };
2997
Steve Blocka7e24c12009-10-30 11:49:00 +00002998 // Conversion from descriptor number to array indices.
2999 static int ToKeyIndex(int descriptor_number) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003000 return kFirstIndex +
3001 (descriptor_number * kDescriptorSize) +
3002 kDescriptorKey;
Steve Blocka7e24c12009-10-30 11:49:00 +00003003 }
Leon Clarkee46be812010-01-19 14:06:41 +00003004
3005 static int ToDetailsIndex(int descriptor_number) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003006 return kFirstIndex +
3007 (descriptor_number * kDescriptorSize) +
3008 kDescriptorDetails;
Leon Clarkee46be812010-01-19 14:06:41 +00003009 }
3010
Steve Blocka7e24c12009-10-30 11:49:00 +00003011 static int ToValueIndex(int descriptor_number) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003012 return kFirstIndex +
3013 (descriptor_number * kDescriptorSize) +
3014 kDescriptorValue;
Steve Blocka7e24c12009-10-30 11:49:00 +00003015 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003016
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003017 // Transfer a complete descriptor from the src descriptor array to this
3018 // descriptor array.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003019 void CopyFrom(int index, DescriptorArray* src);
Steve Blocka7e24c12009-10-30 11:49:00 +00003020
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003021 inline void SetDescriptor(int descriptor_number, Descriptor* desc);
Steve Blocka7e24c12009-10-30 11:49:00 +00003022
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003023 // Swap first and second descriptor.
3024 inline void SwapSortedKeys(int first, int second);
3025
Steve Blocka7e24c12009-10-30 11:49:00 +00003026 DISALLOW_IMPLICIT_CONSTRUCTORS(DescriptorArray);
3027};
3028
3029
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003030enum SearchMode { ALL_ENTRIES, VALID_ENTRIES };
3031
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003032template <SearchMode search_mode, typename T>
3033inline int Search(T* array, Name* name, int valid_entries = 0,
3034 int* out_insertion_index = NULL);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003035
3036
Steve Blocka7e24c12009-10-30 11:49:00 +00003037// HashTable is a subclass of FixedArray that implements a hash table
3038// that uses open addressing and quadratic probing.
3039//
3040// In order for the quadratic probing to work, elements that have not
3041// yet been used and elements that have been deleted are
3042// distinguished. Probing continues when deleted elements are
3043// encountered and stops when unused elements are encountered.
3044//
3045// - Elements with key == undefined have not been used yet.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003046// - Elements with key == the_hole have been deleted.
Steve Blocka7e24c12009-10-30 11:49:00 +00003047//
3048// The hash table class is parameterized with a Shape and a Key.
3049// Shape must be a class with the following interface:
3050// class ExampleShape {
3051// public:
3052// // Tells whether key matches other.
3053// static bool IsMatch(Key key, Object* other);
3054// // Returns the hash value for key.
3055// static uint32_t Hash(Key key);
3056// // Returns the hash value for object.
3057// static uint32_t HashForObject(Key key, Object* object);
3058// // Convert key to an object.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003059// static inline Handle<Object> AsHandle(Isolate* isolate, Key key);
Steve Blocka7e24c12009-10-30 11:49:00 +00003060// // The prefix size indicates number of elements in the beginning
3061// // of the backing storage.
3062// static const int kPrefixSize = ..;
3063// // The Element size indicates number of elements per entry.
3064// static const int kEntrySize = ..;
3065// };
Steve Block3ce2e202009-11-05 08:53:23 +00003066// The prefix size indicates an amount of memory in the
Steve Blocka7e24c12009-10-30 11:49:00 +00003067// beginning of the backing storage that can be used for non-element
3068// information by subclasses.
3069
Ben Murdochc7cc0282012-03-05 14:35:55 +00003070template<typename Key>
3071class BaseShape {
3072 public:
3073 static const bool UsesSeed = false;
3074 static uint32_t Hash(Key key) { return 0; }
3075 static uint32_t SeededHash(Key key, uint32_t seed) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003076 DCHECK(UsesSeed);
Ben Murdochc7cc0282012-03-05 14:35:55 +00003077 return Hash(key);
3078 }
3079 static uint32_t HashForObject(Key key, Object* object) { return 0; }
3080 static uint32_t SeededHashForObject(Key key, uint32_t seed, Object* object) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003081 DCHECK(UsesSeed);
Ben Murdochc7cc0282012-03-05 14:35:55 +00003082 return HashForObject(key, object);
3083 }
3084};
3085
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003086
3087class HashTableBase : public FixedArray {
3088 public:
3089 // Returns the number of elements in the hash table.
3090 inline int NumberOfElements();
3091
3092 // Returns the number of deleted elements in the hash table.
3093 inline int NumberOfDeletedElements();
3094
3095 // Returns the capacity of the hash table.
3096 inline int Capacity();
3097
3098 // ElementAdded should be called whenever an element is added to a
3099 // hash table.
3100 inline void ElementAdded();
3101
3102 // ElementRemoved should be called whenever an element is removed from
3103 // a hash table.
3104 inline void ElementRemoved();
3105 inline void ElementsRemoved(int n);
3106
3107 // Computes the required capacity for a table holding the given
3108 // number of elements. May be more than HashTable::kMaxCapacity.
3109 static inline int ComputeCapacity(int at_least_space_for);
3110
3111 // Tells whether k is a real key. The hole and undefined are not allowed
3112 // as keys and can be used to indicate missing or deleted elements.
3113 inline bool IsKey(Object* k);
3114
3115 // Compute the probe offset (quadratic probing).
3116 INLINE(static uint32_t GetProbeOffset(uint32_t n)) {
3117 return (n + n * n) >> 1;
3118 }
3119
3120 static const int kNumberOfElementsIndex = 0;
3121 static const int kNumberOfDeletedElementsIndex = 1;
3122 static const int kCapacityIndex = 2;
3123 static const int kPrefixStartIndex = 3;
3124
3125 // Constant used for denoting a absent entry.
3126 static const int kNotFound = -1;
3127
3128 protected:
3129 // Update the number of elements in the hash table.
3130 inline void SetNumberOfElements(int nof);
3131
3132 // Update the number of deleted elements in the hash table.
3133 inline void SetNumberOfDeletedElements(int nod);
3134
3135 // Returns probe entry.
3136 static uint32_t GetProbe(uint32_t hash, uint32_t number, uint32_t size) {
3137 DCHECK(base::bits::IsPowerOfTwo32(size));
3138 return (hash + GetProbeOffset(number)) & (size - 1);
3139 }
3140
3141 inline static uint32_t FirstProbe(uint32_t hash, uint32_t size) {
3142 return hash & (size - 1);
3143 }
3144
3145 inline static uint32_t NextProbe(
3146 uint32_t last, uint32_t number, uint32_t size) {
3147 return (last + number) & (size - 1);
3148 }
3149};
3150
3151
3152template <typename Derived, typename Shape, typename Key>
3153class HashTable : public HashTableBase {
Steve Blocka7e24c12009-10-30 11:49:00 +00003154 public:
Ben Murdochc7cc0282012-03-05 14:35:55 +00003155 // Wrapper methods
3156 inline uint32_t Hash(Key key) {
3157 if (Shape::UsesSeed) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003158 return Shape::SeededHash(key, GetHeap()->HashSeed());
Ben Murdochc7cc0282012-03-05 14:35:55 +00003159 } else {
3160 return Shape::Hash(key);
3161 }
3162 }
3163
3164 inline uint32_t HashForObject(Key key, Object* object) {
3165 if (Shape::UsesSeed) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003166 return Shape::SeededHashForObject(key, GetHeap()->HashSeed(), object);
Ben Murdochc7cc0282012-03-05 14:35:55 +00003167 } else {
3168 return Shape::HashForObject(key, object);
3169 }
3170 }
3171
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003172 // Returns a new HashTable object.
3173 MUST_USE_RESULT static Handle<Derived> New(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003174 Isolate* isolate, int at_least_space_for,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003175 MinimumCapacity capacity_option = USE_DEFAULT_MINIMUM_CAPACITY,
Kristian Monsen80d68ea2010-09-08 11:05:35 +01003176 PretenureFlag pretenure = NOT_TENURED);
Steve Blocka7e24c12009-10-30 11:49:00 +00003177
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003178 DECLARE_CAST(HashTable)
Steve Blocka7e24c12009-10-30 11:49:00 +00003179
3180 // Garbage collection support.
3181 void IteratePrefix(ObjectVisitor* visitor);
3182 void IterateElements(ObjectVisitor* visitor);
3183
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003184 // Find entry for key otherwise return kNotFound.
3185 inline int FindEntry(Key key);
3186 inline int FindEntry(Isolate* isolate, Key key, int32_t hash);
3187 int FindEntry(Isolate* isolate, Key key);
Steve Blocka7e24c12009-10-30 11:49:00 +00003188
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003189 // Rehashes the table in-place.
3190 void Rehash(Key key);
Steve Blocka7e24c12009-10-30 11:49:00 +00003191
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003192 // Returns the key at entry.
3193 Object* KeyAt(int entry) { return get(EntryToIndex(entry)); }
3194
3195 static const int kElementsStartIndex = kPrefixStartIndex + Shape::kPrefixSize;
Leon Clarkee46be812010-01-19 14:06:41 +00003196 static const int kEntrySize = Shape::kEntrySize;
3197 static const int kElementsStartOffset =
Steve Blocka7e24c12009-10-30 11:49:00 +00003198 kHeaderSize + kElementsStartIndex * kPointerSize;
Steve Block6ded16b2010-05-10 14:33:55 +01003199 static const int kCapacityOffset =
3200 kHeaderSize + kCapacityIndex * kPointerSize;
Steve Blocka7e24c12009-10-30 11:49:00 +00003201
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003202 // Returns the index for an entry (of the key)
3203 static inline int EntryToIndex(int entry) {
3204 return (entry * kEntrySize) + kElementsStartIndex;
3205 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003206
Steve Blocka7e24c12009-10-30 11:49:00 +00003207 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003208 friend class ObjectHashTable;
3209
Steve Blocka7e24c12009-10-30 11:49:00 +00003210 // Find the entry at which to insert element with the given key that
3211 // has the given hash value.
3212 uint32_t FindInsertionEntry(uint32_t hash);
3213
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003214 // Attempt to shrink hash table after removal of key.
3215 MUST_USE_RESULT static Handle<Derived> Shrink(Handle<Derived> table, Key key);
Steve Blocka7e24c12009-10-30 11:49:00 +00003216
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003217 // Ensure enough space for n additional elements.
3218 MUST_USE_RESULT static Handle<Derived> EnsureCapacity(
3219 Handle<Derived> table,
3220 int n,
3221 Key key,
3222 PretenureFlag pretenure = NOT_TENURED);
Steve Blocka7e24c12009-10-30 11:49:00 +00003223
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003224 // Returns true if this table has sufficient capacity for adding n elements.
3225 bool HasSufficientCapacity(int n);
Leon Clarkee46be812010-01-19 14:06:41 +00003226
Steve Blocka7e24c12009-10-30 11:49:00 +00003227 // Sets the capacity of the hash table.
3228 void SetCapacity(int capacity) {
3229 // To scale a computed hash code to fit within the hash table, we
3230 // use bit-wise AND with a mask, so the capacity must be positive
3231 // and non-zero.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003232 DCHECK(capacity > 0);
3233 DCHECK(capacity <= kMaxCapacity);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003234 set(kCapacityIndex, Smi::FromInt(capacity));
Steve Blocka7e24c12009-10-30 11:49:00 +00003235 }
3236
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003237 // Maximal capacity of HashTable. Based on maximal length of underlying
3238 // FixedArray. Staying below kMaxCapacity also ensures that EntryToIndex
3239 // cannot overflow.
3240 static const int kMaxCapacity =
3241 (FixedArray::kMaxLength - kElementsStartOffset) / kEntrySize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003242
3243 private:
3244 // Returns _expected_ if one of entries given by the first _probe_ probes is
3245 // equal to _expected_. Otherwise, returns the entry given by the probe
3246 // number _probe_.
3247 uint32_t EntryForProbe(Key key, Object* k, int probe, uint32_t expected);
3248
3249 void Swap(uint32_t entry1, uint32_t entry2, WriteBarrierMode mode);
3250
3251 // Rehashes this hash-table into the new table.
3252 void Rehash(Handle<Derived> new_table, Key key);
Steve Blocka7e24c12009-10-30 11:49:00 +00003253};
3254
3255
Steve Blocka7e24c12009-10-30 11:49:00 +00003256// HashTableKey is an abstract superclass for virtual key behavior.
3257class HashTableKey {
3258 public:
3259 // Returns whether the other object matches this key.
3260 virtual bool IsMatch(Object* other) = 0;
3261 // Returns the hash value for this key.
3262 virtual uint32_t Hash() = 0;
3263 // Returns the hash value for object.
3264 virtual uint32_t HashForObject(Object* key) = 0;
Steve Block3ce2e202009-11-05 08:53:23 +00003265 // Returns the key object for storing into the hash table.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003266 MUST_USE_RESULT virtual Handle<Object> AsHandle(Isolate* isolate) = 0;
Steve Blocka7e24c12009-10-30 11:49:00 +00003267 // Required.
3268 virtual ~HashTableKey() {}
3269};
3270
Ben Murdochc7cc0282012-03-05 14:35:55 +00003271
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003272class StringTableShape : public BaseShape<HashTableKey*> {
Steve Blocka7e24c12009-10-30 11:49:00 +00003273 public:
Steve Block44f0eee2011-05-26 01:26:41 +01003274 static inline bool IsMatch(HashTableKey* key, Object* value) {
Steve Blocka7e24c12009-10-30 11:49:00 +00003275 return key->IsMatch(value);
3276 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003277
Steve Block44f0eee2011-05-26 01:26:41 +01003278 static inline uint32_t Hash(HashTableKey* key) {
Steve Blocka7e24c12009-10-30 11:49:00 +00003279 return key->Hash();
3280 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003281
Steve Block44f0eee2011-05-26 01:26:41 +01003282 static inline uint32_t HashForObject(HashTableKey* key, Object* object) {
Steve Blocka7e24c12009-10-30 11:49:00 +00003283 return key->HashForObject(object);
3284 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003285
3286 static inline Handle<Object> AsHandle(Isolate* isolate, HashTableKey* key);
Steve Blocka7e24c12009-10-30 11:49:00 +00003287
3288 static const int kPrefixSize = 0;
3289 static const int kEntrySize = 1;
3290};
3291
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003292class SeqOneByteString;
Ben Murdoch257744e2011-11-30 15:57:28 +00003293
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003294// StringTable.
Steve Blocka7e24c12009-10-30 11:49:00 +00003295//
3296// No special elements in the prefix and the element size is 1
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003297// because only the string itself (the key) needs to be stored.
3298class StringTable: public HashTable<StringTable,
3299 StringTableShape,
3300 HashTableKey*> {
Steve Blocka7e24c12009-10-30 11:49:00 +00003301 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003302 // Find string in the string table. If it is not there yet, it is
3303 // added. The return value is the string found.
3304 static Handle<String> LookupString(Isolate* isolate, Handle<String> key);
3305 static Handle<String> LookupKey(Isolate* isolate, HashTableKey* key);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003306 static String* LookupKeyIfExists(Isolate* isolate, HashTableKey* key);
Steve Blocka7e24c12009-10-30 11:49:00 +00003307
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003308 // Tries to internalize given string and returns string handle on success
3309 // or an empty handle otherwise.
3310 MUST_USE_RESULT static MaybeHandle<String> InternalizeStringIfExists(
3311 Isolate* isolate,
3312 Handle<String> string);
Steve Blocka7e24c12009-10-30 11:49:00 +00003313
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003314 // Looks up a string that is equal to the given string and returns
3315 // string handle if it is found, or an empty handle otherwise.
3316 MUST_USE_RESULT static MaybeHandle<String> LookupStringIfExists(
3317 Isolate* isolate,
3318 Handle<String> str);
3319 MUST_USE_RESULT static MaybeHandle<String> LookupTwoCharsStringIfExists(
3320 Isolate* isolate,
3321 uint16_t c1,
3322 uint16_t c2);
3323
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003324 static void EnsureCapacityForDeserialization(Isolate* isolate, int expected);
3325
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003326 DECLARE_CAST(StringTable)
Steve Blocka7e24c12009-10-30 11:49:00 +00003327
3328 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003329 template <bool seq_one_byte>
3330 friend class JsonParser;
Steve Blocka7e24c12009-10-30 11:49:00 +00003331
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003332 DISALLOW_IMPLICIT_CONSTRUCTORS(StringTable);
Steve Blocka7e24c12009-10-30 11:49:00 +00003333};
3334
3335
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003336template <typename Derived, typename Shape, typename Key>
3337class Dictionary: public HashTable<Derived, Shape, Key> {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003338 typedef HashTable<Derived, Shape, Key> DerivedHashTable;
Steve Blocka7e24c12009-10-30 11:49:00 +00003339
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003340 public:
Steve Blocka7e24c12009-10-30 11:49:00 +00003341 // Returns the value at entry.
3342 Object* ValueAt(int entry) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003343 return this->get(Derived::EntryToIndex(entry) + 1);
Steve Blocka7e24c12009-10-30 11:49:00 +00003344 }
3345
3346 // Set the value for entry.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003347 void ValueAtPut(int entry, Object* value) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003348 this->set(Derived::EntryToIndex(entry) + 1, value);
Steve Blocka7e24c12009-10-30 11:49:00 +00003349 }
3350
3351 // Returns the property details for the property at entry.
3352 PropertyDetails DetailsAt(int entry) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003353 return Shape::DetailsAt(static_cast<Derived*>(this), entry);
Steve Blocka7e24c12009-10-30 11:49:00 +00003354 }
3355
3356 // Set the details for entry.
3357 void DetailsAtPut(int entry, PropertyDetails value) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003358 Shape::DetailsAtPut(static_cast<Derived*>(this), entry, value);
Steve Blocka7e24c12009-10-30 11:49:00 +00003359 }
3360
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003361 // Returns true if property at given entry is deleted.
3362 bool IsDeleted(int entry) {
3363 return Shape::IsDeleted(static_cast<Derived*>(this), entry);
3364 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003365
3366 // Delete a property from the dictionary.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003367 static Handle<Object> DeleteProperty(Handle<Derived> dictionary, int entry);
Steve Blocka7e24c12009-10-30 11:49:00 +00003368
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003369 // Attempt to shrink the dictionary after deletion of key.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003370 MUST_USE_RESULT static inline Handle<Derived> Shrink(
3371 Handle<Derived> dictionary,
3372 Key key) {
3373 return DerivedHashTable::Shrink(dictionary, key);
3374 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003375
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003376 // Sorting support
3377 // TODO(dcarney): templatize or move to SeededNumberDictionary
3378 void CopyValuesTo(FixedArray* elements);
3379
Steve Blocka7e24c12009-10-30 11:49:00 +00003380 // Returns the number of elements in the dictionary filtering out properties
3381 // with the specified attributes.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003382 // TODO(jkummerow): Deprecated, only used by Object.observe.
3383 int NumberOfElementsFilterAttributes(PropertyFilter filter);
Steve Blocka7e24c12009-10-30 11:49:00 +00003384
3385 // Returns the number of enumerable elements in the dictionary.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003386 // TODO(jkummerow): Deprecated, only used by Object.observe.
3387 int NumberOfEnumElements() {
3388 return NumberOfElementsFilterAttributes(ENUMERABLE_STRINGS);
3389 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003390
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003391 // Returns true if the dictionary contains any elements that are non-writable,
3392 // non-configurable, non-enumerable, or have getters/setters.
3393 bool HasComplexElements();
3394
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003395 enum SortMode { UNSORTED, SORTED };
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003396
Steve Blocka7e24c12009-10-30 11:49:00 +00003397 // Fill in details for properties into storage.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003398 // Returns the number of properties added.
3399 // TODO(jkummerow): Deprecated, only used by Object.observe.
3400 int CopyKeysTo(FixedArray* storage, int index, PropertyFilter filter,
3401 SortMode sort_mode);
3402 // Collect the keys into the given KeyAccumulator, in ascending chronological
3403 // order of property creation.
3404 static void CollectKeysTo(Handle<Dictionary<Derived, Shape, Key> > dictionary,
3405 KeyAccumulator* keys, PropertyFilter filter);
3406
3407 // Copies enumerable keys to preallocated fixed array.
3408 void CopyEnumKeysTo(FixedArray* storage);
Steve Blocka7e24c12009-10-30 11:49:00 +00003409
3410 // Accessors for next enumeration index.
3411 void SetNextEnumerationIndex(int index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003412 DCHECK(index != 0);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003413 this->set(kNextEnumerationIndexIndex, Smi::FromInt(index));
Steve Blocka7e24c12009-10-30 11:49:00 +00003414 }
3415
3416 int NextEnumerationIndex() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003417 return Smi::cast(this->get(kNextEnumerationIndexIndex))->value();
Steve Blocka7e24c12009-10-30 11:49:00 +00003418 }
3419
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003420 // Creates a new dictionary.
3421 MUST_USE_RESULT static Handle<Derived> New(
3422 Isolate* isolate,
3423 int at_least_space_for,
3424 PretenureFlag pretenure = NOT_TENURED);
Steve Blocka7e24c12009-10-30 11:49:00 +00003425
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003426 // Ensures that a new dictionary is created when the capacity is checked.
3427 void SetRequiresCopyOnCapacityChange();
3428
Steve Blocka7e24c12009-10-30 11:49:00 +00003429 // Ensure enough space for n additional elements.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003430 static Handle<Derived> EnsureCapacity(Handle<Derived> obj, int n, Key key);
Steve Blocka7e24c12009-10-30 11:49:00 +00003431
Ben Murdochb0fe1622011-05-05 13:52:32 +01003432#ifdef OBJECT_PRINT
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003433 void Print(std::ostream& os); // NOLINT
Steve Blocka7e24c12009-10-30 11:49:00 +00003434#endif
3435 // Returns the key (slow).
3436 Object* SlowReverseLookup(Object* value);
3437
3438 // Sets the entry to (key, value) pair.
3439 inline void SetEntry(int entry,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003440 Handle<Object> key,
3441 Handle<Object> value);
Ben Murdoch8b112d22011-06-08 16:22:53 +01003442 inline void SetEntry(int entry,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003443 Handle<Object> key,
3444 Handle<Object> value,
Steve Blocka7e24c12009-10-30 11:49:00 +00003445 PropertyDetails details);
3446
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003447 MUST_USE_RESULT static Handle<Derived> Add(
3448 Handle<Derived> dictionary,
3449 Key key,
3450 Handle<Object> value,
3451 PropertyDetails details);
Steve Blocka7e24c12009-10-30 11:49:00 +00003452
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003453 // Returns iteration indices array for the |dictionary|.
3454 // Values are direct indices in the |HashTable| array.
3455 static Handle<FixedArray> BuildIterationIndicesArray(
3456 Handle<Derived> dictionary);
3457
Steve Blocka7e24c12009-10-30 11:49:00 +00003458 protected:
3459 // Generic at put operation.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003460 MUST_USE_RESULT static Handle<Derived> AtPut(
3461 Handle<Derived> dictionary,
3462 Key key,
3463 Handle<Object> value);
Steve Blocka7e24c12009-10-30 11:49:00 +00003464
3465 // Add entry to dictionary.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003466 static void AddEntry(
3467 Handle<Derived> dictionary,
3468 Key key,
3469 Handle<Object> value,
3470 PropertyDetails details,
3471 uint32_t hash);
Steve Blocka7e24c12009-10-30 11:49:00 +00003472
3473 // Generate new enumeration indices to avoid enumeration index overflow.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003474 // Returns iteration indices array for the |dictionary|.
3475 static Handle<FixedArray> GenerateNewEnumerationIndices(
3476 Handle<Derived> dictionary);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003477 static const int kMaxNumberKeyIndex = DerivedHashTable::kPrefixStartIndex;
Steve Blocka7e24c12009-10-30 11:49:00 +00003478 static const int kNextEnumerationIndexIndex = kMaxNumberKeyIndex + 1;
3479};
3480
3481
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003482template <typename Derived, typename Shape>
3483class NameDictionaryBase : public Dictionary<Derived, Shape, Handle<Name> > {
3484 typedef Dictionary<Derived, Shape, Handle<Name> > DerivedDictionary;
3485
3486 public:
3487 // Find entry for key, otherwise return kNotFound. Optimized version of
3488 // HashTable::FindEntry.
3489 int FindEntry(Handle<Name> key);
3490};
3491
3492
3493template <typename Key>
3494class BaseDictionaryShape : public BaseShape<Key> {
3495 public:
3496 template <typename Dictionary>
3497 static inline PropertyDetails DetailsAt(Dictionary* dict, int entry) {
3498 STATIC_ASSERT(Dictionary::kEntrySize == 3);
3499 DCHECK(entry >= 0); // Not found is -1, which is not caught by get().
3500 return PropertyDetails(
3501 Smi::cast(dict->get(Dictionary::EntryToIndex(entry) + 2)));
3502 }
3503
3504 template <typename Dictionary>
3505 static inline void DetailsAtPut(Dictionary* dict, int entry,
3506 PropertyDetails value) {
3507 STATIC_ASSERT(Dictionary::kEntrySize == 3);
3508 dict->set(Dictionary::EntryToIndex(entry) + 2, value.AsSmi());
3509 }
3510
3511 template <typename Dictionary>
3512 static bool IsDeleted(Dictionary* dict, int entry) {
3513 return false;
3514 }
3515
3516 template <typename Dictionary>
3517 static inline void SetEntry(Dictionary* dict, int entry, Handle<Object> key,
3518 Handle<Object> value, PropertyDetails details);
3519};
3520
3521
3522class NameDictionaryShape : public BaseDictionaryShape<Handle<Name> > {
Steve Blocka7e24c12009-10-30 11:49:00 +00003523 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003524 static inline bool IsMatch(Handle<Name> key, Object* other);
3525 static inline uint32_t Hash(Handle<Name> key);
3526 static inline uint32_t HashForObject(Handle<Name> key, Object* object);
3527 static inline Handle<Object> AsHandle(Isolate* isolate, Handle<Name> key);
Steve Blocka7e24c12009-10-30 11:49:00 +00003528 static const int kPrefixSize = 2;
3529 static const int kEntrySize = 3;
3530 static const bool kIsEnumerable = true;
3531};
3532
3533
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003534class NameDictionary
3535 : public NameDictionaryBase<NameDictionary, NameDictionaryShape> {
3536 typedef NameDictionaryBase<NameDictionary, NameDictionaryShape>
3537 DerivedDictionary;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003538
Steve Blocka7e24c12009-10-30 11:49:00 +00003539 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003540 DECLARE_CAST(NameDictionary)
Steve Blocka7e24c12009-10-30 11:49:00 +00003541
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003542 inline static Handle<FixedArray> DoGenerateNewEnumerationIndices(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003543 Handle<NameDictionary> dictionary);
Steve Blocka7e24c12009-10-30 11:49:00 +00003544};
3545
3546
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003547class GlobalDictionaryShape : public NameDictionaryShape {
3548 public:
3549 static const int kEntrySize = 2; // Overrides NameDictionaryShape::kEntrySize
3550
3551 template <typename Dictionary>
3552 static inline PropertyDetails DetailsAt(Dictionary* dict, int entry);
3553
3554 template <typename Dictionary>
3555 static inline void DetailsAtPut(Dictionary* dict, int entry,
3556 PropertyDetails value);
3557
3558 template <typename Dictionary>
3559 static bool IsDeleted(Dictionary* dict, int entry);
3560
3561 template <typename Dictionary>
3562 static inline void SetEntry(Dictionary* dict, int entry, Handle<Object> key,
3563 Handle<Object> value, PropertyDetails details);
3564};
3565
3566
3567class GlobalDictionary
3568 : public NameDictionaryBase<GlobalDictionary, GlobalDictionaryShape> {
3569 public:
3570 DECLARE_CAST(GlobalDictionary)
3571};
3572
3573
3574class NumberDictionaryShape : public BaseDictionaryShape<uint32_t> {
Steve Blocka7e24c12009-10-30 11:49:00 +00003575 public:
3576 static inline bool IsMatch(uint32_t key, Object* other);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003577 static inline Handle<Object> AsHandle(Isolate* isolate, uint32_t key);
Steve Blocka7e24c12009-10-30 11:49:00 +00003578 static const int kEntrySize = 3;
3579 static const bool kIsEnumerable = false;
3580};
3581
3582
Ben Murdochc7cc0282012-03-05 14:35:55 +00003583class SeededNumberDictionaryShape : public NumberDictionaryShape {
Steve Blocka7e24c12009-10-30 11:49:00 +00003584 public:
Ben Murdochc7cc0282012-03-05 14:35:55 +00003585 static const bool UsesSeed = true;
3586 static const int kPrefixSize = 2;
3587
3588 static inline uint32_t SeededHash(uint32_t key, uint32_t seed);
3589 static inline uint32_t SeededHashForObject(uint32_t key,
3590 uint32_t seed,
3591 Object* object);
3592};
3593
3594
3595class UnseededNumberDictionaryShape : public NumberDictionaryShape {
3596 public:
3597 static const int kPrefixSize = 0;
3598
3599 static inline uint32_t Hash(uint32_t key);
3600 static inline uint32_t HashForObject(uint32_t key, Object* object);
3601};
3602
3603
3604class SeededNumberDictionary
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003605 : public Dictionary<SeededNumberDictionary,
3606 SeededNumberDictionaryShape,
3607 uint32_t> {
Ben Murdochc7cc0282012-03-05 14:35:55 +00003608 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003609 DECLARE_CAST(SeededNumberDictionary)
Steve Blocka7e24c12009-10-30 11:49:00 +00003610
3611 // Type specific at put (default NONE attributes is used when adding).
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003612 MUST_USE_RESULT static Handle<SeededNumberDictionary> AtNumberPut(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003613 Handle<SeededNumberDictionary> dictionary, uint32_t key,
3614 Handle<Object> value, bool used_as_prototype);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003615 MUST_USE_RESULT static Handle<SeededNumberDictionary> AddNumberEntry(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003616 Handle<SeededNumberDictionary> dictionary, uint32_t key,
3617 Handle<Object> value, PropertyDetails details, bool used_as_prototype);
Steve Blocka7e24c12009-10-30 11:49:00 +00003618
3619 // Set an existing entry or add a new one if needed.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003620 // Return the updated dictionary.
3621 MUST_USE_RESULT static Handle<SeededNumberDictionary> Set(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003622 Handle<SeededNumberDictionary> dictionary, uint32_t key,
3623 Handle<Object> value, PropertyDetails details, bool used_as_prototype);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003624
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003625 void UpdateMaxNumberKey(uint32_t key, bool used_as_prototype);
Steve Blocka7e24c12009-10-30 11:49:00 +00003626
3627 // If slow elements are required we will never go back to fast-case
3628 // for the elements kept in this dictionary. We require slow
3629 // elements if an element has been added at an index larger than
3630 // kRequiresSlowElementsLimit or set_requires_slow_elements() has been called
3631 // when defining a getter or setter with a number key.
3632 inline bool requires_slow_elements();
3633 inline void set_requires_slow_elements();
3634
3635 // Get the value of the max number key that has been added to this
3636 // dictionary. max_number_key can only be called if
3637 // requires_slow_elements returns false.
3638 inline uint32_t max_number_key();
3639
Steve Blocka7e24c12009-10-30 11:49:00 +00003640 // Bit masks.
3641 static const int kRequiresSlowElementsMask = 1;
3642 static const int kRequiresSlowElementsTagSize = 1;
3643 static const uint32_t kRequiresSlowElementsLimit = (1 << 29) - 1;
3644};
3645
3646
Ben Murdochc7cc0282012-03-05 14:35:55 +00003647class UnseededNumberDictionary
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003648 : public Dictionary<UnseededNumberDictionary,
3649 UnseededNumberDictionaryShape,
3650 uint32_t> {
Ben Murdochc7cc0282012-03-05 14:35:55 +00003651 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003652 DECLARE_CAST(UnseededNumberDictionary)
Ben Murdochc7cc0282012-03-05 14:35:55 +00003653
3654 // Type specific at put (default NONE attributes is used when adding).
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003655 MUST_USE_RESULT static Handle<UnseededNumberDictionary> AtNumberPut(
3656 Handle<UnseededNumberDictionary> dictionary,
3657 uint32_t key,
3658 Handle<Object> value);
3659 MUST_USE_RESULT static Handle<UnseededNumberDictionary> AddNumberEntry(
3660 Handle<UnseededNumberDictionary> dictionary,
3661 uint32_t key,
3662 Handle<Object> value);
Ben Murdochc7cc0282012-03-05 14:35:55 +00003663
3664 // Set an existing entry or add a new one if needed.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003665 // Return the updated dictionary.
3666 MUST_USE_RESULT static Handle<UnseededNumberDictionary> Set(
3667 Handle<UnseededNumberDictionary> dictionary,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003668 uint32_t key,
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003669 Handle<Object> value);
Ben Murdochc7cc0282012-03-05 14:35:55 +00003670};
3671
3672
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003673class ObjectHashTableShape : public BaseShape<Handle<Object> > {
Ben Murdoch2b4ba112012-01-20 14:57:15 +00003674 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003675 static inline bool IsMatch(Handle<Object> key, Object* other);
3676 static inline uint32_t Hash(Handle<Object> key);
3677 static inline uint32_t HashForObject(Handle<Object> key, Object* object);
3678 static inline Handle<Object> AsHandle(Isolate* isolate, Handle<Object> key);
Ben Murdoch592a9fc2012-03-05 11:04:45 +00003679 static const int kPrefixSize = 0;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003680 static const int kEntrySize = 2;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003681};
3682
3683
3684// ObjectHashTable maps keys that are arbitrary objects to object values by
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003685// using the identity hash of the key for hashing purposes.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003686class ObjectHashTable: public HashTable<ObjectHashTable,
3687 ObjectHashTableShape,
3688 Handle<Object> > {
3689 typedef HashTable<
3690 ObjectHashTable, ObjectHashTableShape, Handle<Object> > DerivedHashTable;
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003691 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003692 DECLARE_CAST(ObjectHashTable)
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003693
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003694 // Attempt to shrink hash table after removal of key.
3695 MUST_USE_RESULT static inline Handle<ObjectHashTable> Shrink(
3696 Handle<ObjectHashTable> table,
3697 Handle<Object> key);
3698
3699 // Looks up the value associated with the given key. The hole value is
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003700 // returned in case the key is not present.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003701 Object* Lookup(Handle<Object> key);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003702 Object* Lookup(Handle<Object> key, int32_t hash);
3703 Object* Lookup(Isolate* isolate, Handle<Object> key, int32_t hash);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003704
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003705 // Adds (or overwrites) the value associated with the given key.
3706 static Handle<ObjectHashTable> Put(Handle<ObjectHashTable> table,
3707 Handle<Object> key,
3708 Handle<Object> value);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003709 static Handle<ObjectHashTable> Put(Handle<ObjectHashTable> table,
3710 Handle<Object> key, Handle<Object> value,
3711 int32_t hash);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003712
3713 // Returns an ObjectHashTable (possibly |table|) where |key| has been removed.
3714 static Handle<ObjectHashTable> Remove(Handle<ObjectHashTable> table,
3715 Handle<Object> key,
3716 bool* was_present);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003717 static Handle<ObjectHashTable> Remove(Handle<ObjectHashTable> table,
3718 Handle<Object> key, bool* was_present,
3719 int32_t hash);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003720
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003721 protected:
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003722 friend class MarkCompactCollector;
3723
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003724 void AddEntry(int entry, Object* key, Object* value);
3725 void RemoveEntry(int entry);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003726
3727 // Returns the index to the value of an entry.
3728 static inline int EntryToValueIndex(int entry) {
3729 return EntryToIndex(entry) + 1;
3730 }
3731};
3732
3733
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003734// OrderedHashTable is a HashTable with Object keys that preserves
3735// insertion order. There are Map and Set interfaces (OrderedHashMap
3736// and OrderedHashTable, below). It is meant to be used by JSMap/JSSet.
3737//
3738// Only Object* keys are supported, with Object::SameValueZero() used as the
3739// equality operator and Object::GetHash() for the hash function.
3740//
3741// Based on the "Deterministic Hash Table" as described by Jason Orendorff at
3742// https://wiki.mozilla.org/User:Jorend/Deterministic_hash_tables
3743// Originally attributed to Tyler Close.
3744//
3745// Memory layout:
3746// [0]: bucket count
3747// [1]: element count
3748// [2]: deleted element count
3749// [3..(3 + NumberOfBuckets() - 1)]: "hash table", where each item is an
3750// offset into the data table (see below) where the
3751// first item in this bucket is stored.
3752// [3 + NumberOfBuckets()..length]: "data table", an array of length
3753// Capacity() * kEntrySize, where the first entrysize
3754// items are handled by the derived class and the
3755// item at kChainOffset is another entry into the
3756// data table indicating the next entry in this hash
3757// bucket.
3758//
3759// When we transition the table to a new version we obsolete it and reuse parts
3760// of the memory to store information how to transition an iterator to the new
3761// table:
3762//
3763// Memory layout for obsolete table:
3764// [0]: bucket count
3765// [1]: Next newer table
3766// [2]: Number of removed holes or -1 when the table was cleared.
3767// [3..(3 + NumberOfRemovedHoles() - 1)]: The indexes of the removed holes.
3768// [3 + NumberOfRemovedHoles()..length]: Not used
3769//
3770template<class Derived, class Iterator, int entrysize>
3771class OrderedHashTable: public FixedArray {
3772 public:
3773 // Returns an OrderedHashTable with a capacity of at least |capacity|.
3774 static Handle<Derived> Allocate(
3775 Isolate* isolate, int capacity, PretenureFlag pretenure = NOT_TENURED);
3776
3777 // Returns an OrderedHashTable (possibly |table|) with enough space
3778 // to add at least one new element.
3779 static Handle<Derived> EnsureGrowable(Handle<Derived> table);
3780
3781 // Returns an OrderedHashTable (possibly |table|) that's shrunken
3782 // if possible.
3783 static Handle<Derived> Shrink(Handle<Derived> table);
3784
3785 // Returns a new empty OrderedHashTable and records the clearing so that
3786 // exisiting iterators can be updated.
3787 static Handle<Derived> Clear(Handle<Derived> table);
3788
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003789 // Returns a true if the OrderedHashTable contains the key
3790 static bool HasKey(Handle<Derived> table, Handle<Object> key);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003791
3792 int NumberOfElements() {
3793 return Smi::cast(get(kNumberOfElementsIndex))->value();
3794 }
3795
3796 int NumberOfDeletedElements() {
3797 return Smi::cast(get(kNumberOfDeletedElementsIndex))->value();
3798 }
3799
3800 int UsedCapacity() { return NumberOfElements() + NumberOfDeletedElements(); }
3801
3802 int NumberOfBuckets() {
3803 return Smi::cast(get(kNumberOfBucketsIndex))->value();
3804 }
3805
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003806 // Returns an index into |this| for the given entry.
3807 int EntryToIndex(int entry) {
3808 return kHashTableStartIndex + NumberOfBuckets() + (entry * kEntrySize);
3809 }
3810
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003811 int HashToBucket(int hash) { return hash & (NumberOfBuckets() - 1); }
3812
3813 int HashToEntry(int hash) {
3814 int bucket = HashToBucket(hash);
3815 Object* entry = this->get(kHashTableStartIndex + bucket);
3816 return Smi::cast(entry)->value();
3817 }
3818
3819 int KeyToFirstEntry(Object* key) {
3820 Object* hash = key->GetHash();
3821 // If the object does not have an identity hash, it was never used as a key
3822 if (hash->IsUndefined()) return kNotFound;
3823 return HashToEntry(Smi::cast(hash)->value());
3824 }
3825
3826 int NextChainEntry(int entry) {
3827 Object* next_entry = get(EntryToIndex(entry) + kChainOffset);
3828 return Smi::cast(next_entry)->value();
3829 }
3830
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003831 Object* KeyAt(int entry) { return get(EntryToIndex(entry)); }
3832
3833 bool IsObsolete() {
3834 return !get(kNextTableIndex)->IsSmi();
3835 }
3836
3837 // The next newer table. This is only valid if the table is obsolete.
3838 Derived* NextTable() {
3839 return Derived::cast(get(kNextTableIndex));
3840 }
3841
3842 // When the table is obsolete we store the indexes of the removed holes.
3843 int RemovedIndexAt(int index) {
3844 return Smi::cast(get(kRemovedHolesIndex + index))->value();
3845 }
3846
3847 static const int kNotFound = -1;
3848 static const int kMinCapacity = 4;
3849
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003850 static const int kNumberOfBucketsIndex = 0;
3851 static const int kNumberOfElementsIndex = kNumberOfBucketsIndex + 1;
3852 static const int kNumberOfDeletedElementsIndex = kNumberOfElementsIndex + 1;
3853 static const int kHashTableStartIndex = kNumberOfDeletedElementsIndex + 1;
3854 static const int kNextTableIndex = kNumberOfElementsIndex;
3855
3856 static const int kNumberOfBucketsOffset =
3857 kHeaderSize + kNumberOfBucketsIndex * kPointerSize;
3858 static const int kNumberOfElementsOffset =
3859 kHeaderSize + kNumberOfElementsIndex * kPointerSize;
3860 static const int kNumberOfDeletedElementsOffset =
3861 kHeaderSize + kNumberOfDeletedElementsIndex * kPointerSize;
3862 static const int kHashTableStartOffset =
3863 kHeaderSize + kHashTableStartIndex * kPointerSize;
3864 static const int kNextTableOffset =
3865 kHeaderSize + kNextTableIndex * kPointerSize;
3866
3867 static const int kEntrySize = entrysize + 1;
3868 static const int kChainOffset = entrysize;
3869
3870 static const int kLoadFactor = 2;
3871
3872 // NumberOfDeletedElements is set to kClearedTableSentinel when
3873 // the table is cleared, which allows iterator transitions to
3874 // optimize that case.
3875 static const int kClearedTableSentinel = -1;
3876
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003877 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003878 static Handle<Derived> Rehash(Handle<Derived> table, int new_capacity);
3879
3880 void SetNumberOfBuckets(int num) {
3881 set(kNumberOfBucketsIndex, Smi::FromInt(num));
3882 }
3883
3884 void SetNumberOfElements(int num) {
3885 set(kNumberOfElementsIndex, Smi::FromInt(num));
3886 }
3887
3888 void SetNumberOfDeletedElements(int num) {
3889 set(kNumberOfDeletedElementsIndex, Smi::FromInt(num));
3890 }
3891
3892 int Capacity() {
3893 return NumberOfBuckets() * kLoadFactor;
3894 }
3895
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003896 void SetNextTable(Derived* next_table) {
3897 set(kNextTableIndex, next_table);
3898 }
3899
3900 void SetRemovedIndexAt(int index, int removed_index) {
3901 return set(kRemovedHolesIndex + index, Smi::FromInt(removed_index));
3902 }
3903
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003904 static const int kRemovedHolesIndex = kHashTableStartIndex;
3905
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003906 static const int kMaxCapacity =
3907 (FixedArray::kMaxLength - kHashTableStartIndex)
3908 / (1 + (kEntrySize * kLoadFactor));
3909};
3910
3911
3912class JSSetIterator;
3913
3914
3915class OrderedHashSet: public OrderedHashTable<
3916 OrderedHashSet, JSSetIterator, 1> {
3917 public:
3918 DECLARE_CAST(OrderedHashSet)
3919
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003920 static Handle<OrderedHashSet> Add(Handle<OrderedHashSet> table,
3921 Handle<Object> value);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003922};
3923
3924
3925class JSMapIterator;
3926
3927
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003928class OrderedHashMap
3929 : public OrderedHashTable<OrderedHashMap, JSMapIterator, 2> {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003930 public:
3931 DECLARE_CAST(OrderedHashMap)
3932
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003933 inline Object* ValueAt(int entry);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003934
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003935 static const int kValueOffset = 1;
3936};
3937
3938
3939template <int entrysize>
3940class WeakHashTableShape : public BaseShape<Handle<Object> > {
3941 public:
3942 static inline bool IsMatch(Handle<Object> key, Object* other);
3943 static inline uint32_t Hash(Handle<Object> key);
3944 static inline uint32_t HashForObject(Handle<Object> key, Object* object);
3945 static inline Handle<Object> AsHandle(Isolate* isolate, Handle<Object> key);
3946 static const int kPrefixSize = 0;
3947 static const int kEntrySize = entrysize;
3948};
3949
3950
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003951// WeakHashTable maps keys that are arbitrary heap objects to heap object
3952// values. The table wraps the keys in weak cells and store values directly.
3953// Thus it references keys weakly and values strongly.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003954class WeakHashTable: public HashTable<WeakHashTable,
3955 WeakHashTableShape<2>,
3956 Handle<Object> > {
3957 typedef HashTable<
3958 WeakHashTable, WeakHashTableShape<2>, Handle<Object> > DerivedHashTable;
3959 public:
3960 DECLARE_CAST(WeakHashTable)
3961
3962 // Looks up the value associated with the given key. The hole value is
3963 // returned in case the key is not present.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003964 Object* Lookup(Handle<HeapObject> key);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003965
3966 // Adds (or overwrites) the value associated with the given key. Mapping a
3967 // key to the hole value causes removal of the whole entry.
3968 MUST_USE_RESULT static Handle<WeakHashTable> Put(Handle<WeakHashTable> table,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003969 Handle<HeapObject> key,
3970 Handle<HeapObject> value);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003971
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003972 static Handle<FixedArray> GetValues(Handle<WeakHashTable> table);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003973
3974 private:
3975 friend class MarkCompactCollector;
3976
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003977 void AddEntry(int entry, Handle<WeakCell> key, Handle<HeapObject> value);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003978
3979 // Returns the index to the value of an entry.
3980 static inline int EntryToValueIndex(int entry) {
3981 return EntryToIndex(entry) + 1;
3982 }
3983};
3984
3985
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003986// ScopeInfo represents information about different scopes of a source
3987// program and the allocation of the scope's variables. Scope information
3988// is stored in a compressed form in ScopeInfo objects and is used
3989// at runtime (stack dumps, deoptimization, etc.).
3990
3991// This object provides quick access to scope info details for runtime
3992// routines.
3993class ScopeInfo : public FixedArray {
3994 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003995 DECLARE_CAST(ScopeInfo)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003996
3997 // Return the type of this scope.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003998 ScopeType scope_type();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003999
4000 // Does this scope call eval?
4001 bool CallsEval();
4002
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004003 // Return the language mode of this scope.
4004 LanguageMode language_mode();
4005
4006 // True if this scope is a (var) declaration scope.
4007 bool is_declaration_scope();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004008
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004009 // Does this scope make a sloppy eval call?
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004010 bool CallsSloppyEval() { return CallsEval() && is_sloppy(language_mode()); }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004011
4012 // Return the total number of locals allocated on the stack and in the
4013 // context. This includes the parameters that are allocated in the context.
4014 int LocalCount();
4015
4016 // Return the number of stack slots for code. This number consists of two
4017 // parts:
4018 // 1. One stack slot per stack allocated local.
4019 // 2. One stack slot for the function name if it is stack allocated.
4020 int StackSlotCount();
4021
4022 // Return the number of context slots for code if a context is allocated. This
4023 // number consists of three parts:
4024 // 1. Size of fixed header for every context: Context::MIN_CONTEXT_SLOTS
4025 // 2. One context slot per context allocated local.
4026 // 3. One context slot for the function name if it is context allocated.
4027 // Parameters allocated in the context count as context allocated locals. If
4028 // no contexts are allocated for this scope ContextLength returns 0.
4029 int ContextLength();
4030
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004031 // Does this scope declare a "this" binding?
4032 bool HasReceiver();
4033
4034 // Does this scope declare a "this" binding, and the "this" binding is stack-
4035 // or context-allocated?
4036 bool HasAllocatedReceiver();
4037
4038 // Does this scope declare a "new.target" binding?
4039 bool HasNewTarget();
4040
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004041 // Is this scope the scope of a named function expression?
4042 bool HasFunctionName();
4043
4044 // Return if this has context allocated locals.
4045 bool HasHeapAllocatedLocals();
4046
4047 // Return if contexts are allocated for this scope.
4048 bool HasContext();
4049
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004050 // Return if this is a function scope with "use asm".
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004051 inline bool IsAsmModule();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004052
4053 // Return if this is a nested function within an asm module scope.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004054 inline bool IsAsmFunction();
4055
4056 inline bool HasSimpleParameters();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004057
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004058 // Return the function_name if present.
4059 String* FunctionName();
4060
4061 // Return the name of the given parameter.
4062 String* ParameterName(int var);
4063
4064 // Return the name of the given local.
4065 String* LocalName(int var);
4066
4067 // Return the name of the given stack local.
4068 String* StackLocalName(int var);
4069
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004070 // Return the name of the given stack local.
4071 int StackLocalIndex(int var);
4072
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004073 // Return the name of the given context local.
4074 String* ContextLocalName(int var);
4075
4076 // Return the mode of the given context local.
4077 VariableMode ContextLocalMode(int var);
4078
4079 // Return the initialization flag of the given context local.
4080 InitializationFlag ContextLocalInitFlag(int var);
4081
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004082 // Return the initialization flag of the given context local.
4083 MaybeAssignedFlag ContextLocalMaybeAssignedFlag(int var);
4084
4085 // Return true if this local was introduced by the compiler, and should not be
4086 // exposed to the user in a debugger.
4087 bool LocalIsSynthetic(int var);
4088
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004089 String* StrongModeFreeVariableName(int var);
4090 int StrongModeFreeVariableStartPosition(int var);
4091 int StrongModeFreeVariableEndPosition(int var);
4092
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004093 // Lookup support for serialized scope info. Returns the
4094 // the stack slot index for a given slot name if the slot is
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004095 // present; otherwise returns a value < 0. The name must be an internalized
4096 // string.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004097 int StackSlotIndex(String* name);
4098
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004099 // Lookup support for serialized scope info. Returns the local context slot
4100 // index for a given slot name if the slot is present; otherwise
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004101 // returns a value < 0. The name must be an internalized string.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004102 // If the slot is present and mode != NULL, sets *mode to the corresponding
4103 // mode for that variable.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004104 static int ContextSlotIndex(Handle<ScopeInfo> scope_info, Handle<String> name,
4105 VariableMode* mode, InitializationFlag* init_flag,
4106 MaybeAssignedFlag* maybe_assigned_flag);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004107
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004108 // Similar to ContextSlotIndex() but this method searches only among
4109 // global slots of the serialized scope info. Returns the context slot index
4110 // for a given slot name if the slot is present; otherwise returns a
4111 // value < 0. The name must be an internalized string. If the slot is present
4112 // and mode != NULL, sets *mode to the corresponding mode for that variable.
4113 static int ContextGlobalSlotIndex(Handle<ScopeInfo> scope_info,
4114 Handle<String> name, VariableMode* mode,
4115 InitializationFlag* init_flag,
4116 MaybeAssignedFlag* maybe_assigned_flag);
4117
4118 // Lookup the name of a certain context slot by its index.
4119 String* ContextSlotName(int slot_index);
4120
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004121 // Lookup support for serialized scope info. Returns the
4122 // parameter index for a given parameter name if the parameter is present;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004123 // otherwise returns a value < 0. The name must be an internalized string.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004124 int ParameterIndex(String* name);
4125
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004126 // Lookup support for serialized scope info. Returns the function context
4127 // slot index if the function name is present and context-allocated (named
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004128 // function expressions, only), otherwise returns a value < 0. The name
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004129 // must be an internalized string.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004130 int FunctionContextSlotIndex(String* name, VariableMode* mode);
4131
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004132 // Lookup support for serialized scope info. Returns the receiver context
4133 // slot index if scope has a "this" binding, and the binding is
4134 // context-allocated. Otherwise returns a value < 0.
4135 int ReceiverContextSlotIndex();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004136
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004137 FunctionKind function_kind();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004138
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004139 static Handle<ScopeInfo> Create(Isolate* isolate, Zone* zone, Scope* scope);
4140 static Handle<ScopeInfo> CreateGlobalThisBinding(Isolate* isolate);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004141
4142 // Serializes empty scope info.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004143 static ScopeInfo* Empty(Isolate* isolate);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004144
4145#ifdef DEBUG
4146 void Print();
4147#endif
4148
4149 // The layout of the static part of a ScopeInfo is as follows. Each entry is
4150 // numeric and occupies one array slot.
4151 // 1. A set of properties of the scope
4152 // 2. The number of parameters. This only applies to function scopes. For
4153 // non-function scopes this is 0.
4154 // 3. The number of non-parameter variables allocated on the stack.
4155 // 4. The number of non-parameter and parameter variables allocated in the
4156 // context.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004157#define FOR_EACH_SCOPE_INFO_NUMERIC_FIELD(V) \
4158 V(Flags) \
4159 V(ParameterCount) \
4160 V(StackLocalCount) \
4161 V(ContextLocalCount) \
4162 V(ContextGlobalCount) \
4163 V(StrongModeFreeVariableCount)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004164
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004165#define FIELD_ACCESSORS(name) \
4166 inline void Set##name(int value); \
4167 inline int name();
4168 FOR_EACH_SCOPE_INFO_NUMERIC_FIELD(FIELD_ACCESSORS)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004169#undef FIELD_ACCESSORS
4170
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004171 enum {
4172#define DECL_INDEX(name) k##name,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004173 FOR_EACH_SCOPE_INFO_NUMERIC_FIELD(DECL_INDEX)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004174#undef DECL_INDEX
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004175 kVariablePartIndex
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004176 };
4177
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004178 private:
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004179 // The layout of the variable part of a ScopeInfo is as follows:
4180 // 1. ParameterEntries:
4181 // This part stores the names of the parameters for function scopes. One
4182 // slot is used per parameter, so in total this part occupies
4183 // ParameterCount() slots in the array. For other scopes than function
4184 // scopes ParameterCount() is 0.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004185 // 2. StackLocalFirstSlot:
4186 // Index of a first stack slot for stack local. Stack locals belonging to
4187 // this scope are located on a stack at slots starting from this index.
4188 // 3. StackLocalEntries:
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004189 // Contains the names of local variables that are allocated on the stack,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004190 // in increasing order of the stack slot index. First local variable has
4191 // a stack slot index defined in StackLocalFirstSlot (point 2 above).
4192 // One slot is used per stack local, so in total this part occupies
4193 // StackLocalCount() slots in the array.
4194 // 4. ContextLocalNameEntries:
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004195 // Contains the names of local variables and parameters that are allocated
4196 // in the context. They are stored in increasing order of the context slot
4197 // index starting with Context::MIN_CONTEXT_SLOTS. One slot is used per
4198 // context local, so in total this part occupies ContextLocalCount() slots
4199 // in the array.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004200 // 5. ContextLocalInfoEntries:
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004201 // Contains the variable modes and initialization flags corresponding to
4202 // the context locals in ContextLocalNameEntries. One slot is used per
4203 // context local, so in total this part occupies ContextLocalCount()
4204 // slots in the array.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004205 // 6. StrongModeFreeVariableNameEntries:
4206 // Stores the names of strong mode free variables.
4207 // 7. StrongModeFreeVariablePositionEntries:
4208 // Stores the locations (start and end position) of strong mode free
4209 // variables.
4210 // 8. RecieverEntryIndex:
4211 // If the scope binds a "this" value, one slot is reserved to hold the
4212 // context or stack slot index for the variable.
4213 // 9. FunctionNameEntryIndex:
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004214 // If the scope belongs to a named function expression this part contains
4215 // information about the function variable. It always occupies two array
4216 // slots: a. The name of the function variable.
4217 // b. The context or stack slot index for the variable.
4218 int ParameterEntriesIndex();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004219 int StackLocalFirstSlotIndex();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004220 int StackLocalEntriesIndex();
4221 int ContextLocalNameEntriesIndex();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004222 int ContextGlobalNameEntriesIndex();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004223 int ContextLocalInfoEntriesIndex();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004224 int ContextGlobalInfoEntriesIndex();
4225 int StrongModeFreeVariableNameEntriesIndex();
4226 int StrongModeFreeVariablePositionEntriesIndex();
4227 int ReceiverEntryIndex();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004228 int FunctionNameEntryIndex();
4229
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004230 int Lookup(Handle<String> name, int start, int end, VariableMode* mode,
4231 VariableLocation* location, InitializationFlag* init_flag,
4232 MaybeAssignedFlag* maybe_assigned_flag);
4233
4234 // Used for the function name variable for named function expressions, and for
4235 // the receiver.
4236 enum VariableAllocationInfo { NONE, STACK, CONTEXT, UNUSED };
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004237
4238 // Properties of scopes.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04004239 class ScopeTypeField : public BitField<ScopeType, 0, 4> {};
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004240 class CallsEvalField : public BitField<bool, ScopeTypeField::kNext, 1> {};
4241 STATIC_ASSERT(LANGUAGE_END == 3);
4242 class LanguageModeField
4243 : public BitField<LanguageMode, CallsEvalField::kNext, 2> {};
4244 class DeclarationScopeField
4245 : public BitField<bool, LanguageModeField::kNext, 1> {};
4246 class ReceiverVariableField
4247 : public BitField<VariableAllocationInfo, DeclarationScopeField::kNext,
4248 2> {};
4249 class HasNewTargetField
4250 : public BitField<bool, ReceiverVariableField::kNext, 1> {};
4251 class FunctionVariableField
4252 : public BitField<VariableAllocationInfo, HasNewTargetField::kNext, 2> {};
4253 class FunctionVariableMode
4254 : public BitField<VariableMode, FunctionVariableField::kNext, 3> {};
4255 class AsmModuleField : public BitField<bool, FunctionVariableMode::kNext, 1> {
4256 };
4257 class AsmFunctionField : public BitField<bool, AsmModuleField::kNext, 1> {};
4258 class HasSimpleParametersField
4259 : public BitField<bool, AsmFunctionField::kNext, 1> {};
4260 class FunctionKindField
4261 : public BitField<FunctionKind, HasSimpleParametersField::kNext, 8> {};
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004262
4263 // BitFields representing the encoded information for context locals in the
4264 // ContextLocalInfoEntries part.
4265 class ContextLocalMode: public BitField<VariableMode, 0, 3> {};
4266 class ContextLocalInitFlag: public BitField<InitializationFlag, 3, 1> {};
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004267 class ContextLocalMaybeAssignedFlag
4268 : public BitField<MaybeAssignedFlag, 4, 1> {};
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004269
4270 friend class ScopeIterator;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004271};
4272
4273
Kristian Monsen80d68ea2010-09-08 11:05:35 +01004274// The cache for maps used by normalized (dictionary mode) objects.
4275// Such maps do not have property descriptors, so a typical program
4276// needs very limited number of distinct normalized maps.
4277class NormalizedMapCache: public FixedArray {
4278 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004279 static Handle<NormalizedMapCache> New(Isolate* isolate);
Kristian Monsen80d68ea2010-09-08 11:05:35 +01004280
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004281 MUST_USE_RESULT MaybeHandle<Map> Get(Handle<Map> fast_map,
4282 PropertyNormalizationMode mode);
4283 void Set(Handle<Map> fast_map, Handle<Map> normalized_map);
Kristian Monsen80d68ea2010-09-08 11:05:35 +01004284
Kristian Monsen80d68ea2010-09-08 11:05:35 +01004285 void Clear();
4286
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004287 DECLARE_CAST(NormalizedMapCache)
Kristian Monsen80d68ea2010-09-08 11:05:35 +01004288
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004289 static inline bool IsNormalizedMapCache(const Object* obj);
4290
4291 DECLARE_VERIFIER(NormalizedMapCache)
4292 private:
4293 static const int kEntries = 64;
4294
4295 static inline int GetIndex(Handle<Map> map);
4296
4297 // The following declarations hide base class methods.
4298 Object* get(int index);
4299 void set(int index, Object* value);
Kristian Monsen80d68ea2010-09-08 11:05:35 +01004300};
4301
4302
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004303// ByteArray represents fixed sized byte arrays. Used for the relocation info
4304// that is attached to code objects.
Ben Murdoch69a99ed2011-11-30 16:03:39 +00004305class ByteArray: public FixedArrayBase {
Steve Blocka7e24c12009-10-30 11:49:00 +00004306 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004307 inline int Size();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004308
Steve Blocka7e24c12009-10-30 11:49:00 +00004309 // Setter and getter.
4310 inline byte get(int index);
4311 inline void set(int index, byte value);
4312
4313 // Treat contents as an int array.
4314 inline int get_int(int index);
4315
4316 static int SizeFor(int length) {
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01004317 return OBJECT_POINTER_ALIGN(kHeaderSize + length);
Steve Blocka7e24c12009-10-30 11:49:00 +00004318 }
4319 // We use byte arrays for free blocks in the heap. Given a desired size in
4320 // bytes that is a multiple of the word size and big enough to hold a byte
4321 // array, this function returns the number of elements a byte array should
4322 // have.
4323 static int LengthFor(int size_in_bytes) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004324 DCHECK(IsAligned(size_in_bytes, kPointerSize));
4325 DCHECK(size_in_bytes >= kHeaderSize);
Steve Blocka7e24c12009-10-30 11:49:00 +00004326 return size_in_bytes - kHeaderSize;
4327 }
4328
4329 // Returns data start address.
4330 inline Address GetDataStartAddress();
4331
4332 // Returns a pointer to the ByteArray object for a given data start address.
4333 static inline ByteArray* FromDataStartAddress(Address address);
4334
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004335 DECLARE_CAST(ByteArray)
Steve Blocka7e24c12009-10-30 11:49:00 +00004336
4337 // Dispatched behavior.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004338 inline int ByteArraySize();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004339 DECLARE_PRINTER(ByteArray)
4340 DECLARE_VERIFIER(ByteArray)
Steve Blocka7e24c12009-10-30 11:49:00 +00004341
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01004342 // Layout description.
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01004343 static const int kAlignedSize = OBJECT_POINTER_ALIGN(kHeaderSize);
Steve Blocka7e24c12009-10-30 11:49:00 +00004344
Leon Clarkee46be812010-01-19 14:06:41 +00004345 // Maximal memory consumption for a single ByteArray.
4346 static const int kMaxSize = 512 * MB;
4347 // Maximal length of a single ByteArray.
4348 static const int kMaxLength = kMaxSize - kHeaderSize;
4349
Steve Blocka7e24c12009-10-30 11:49:00 +00004350 private:
4351 DISALLOW_IMPLICIT_CONSTRUCTORS(ByteArray);
4352};
4353
4354
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004355// BytecodeArray represents a sequence of interpreter bytecodes.
4356class BytecodeArray : public FixedArrayBase {
4357 public:
4358 static int SizeFor(int length) {
4359 return OBJECT_POINTER_ALIGN(kHeaderSize + length);
4360 }
4361
4362 // Setter and getter
4363 inline byte get(int index);
4364 inline void set(int index, byte value);
4365
4366 // Returns data start address.
4367 inline Address GetFirstBytecodeAddress();
4368
4369 // Accessors for frame size.
4370 inline int frame_size() const;
4371 inline void set_frame_size(int frame_size);
4372
4373 // Accessor for register count (derived from frame_size).
4374 inline int register_count() const;
4375
4376 // Accessors for parameter count (including implicit 'this' receiver).
4377 inline int parameter_count() const;
4378 inline void set_parameter_count(int number_of_parameters);
4379
4380 // Accessors for the constant pool.
4381 DECL_ACCESSORS(constant_pool, FixedArray)
4382
4383 DECLARE_CAST(BytecodeArray)
4384
4385 // Dispatched behavior.
4386 inline int BytecodeArraySize();
4387
4388 DECLARE_PRINTER(BytecodeArray)
4389 DECLARE_VERIFIER(BytecodeArray)
4390
4391 void Disassemble(std::ostream& os);
4392
4393 // Layout description.
4394 static const int kFrameSizeOffset = FixedArrayBase::kHeaderSize;
4395 static const int kParameterSizeOffset = kFrameSizeOffset + kIntSize;
4396 static const int kConstantPoolOffset = kParameterSizeOffset + kIntSize;
4397 static const int kHeaderSize = kConstantPoolOffset + kPointerSize;
4398
4399 static const int kAlignedSize = OBJECT_POINTER_ALIGN(kHeaderSize);
4400
4401 // Maximal memory consumption for a single BytecodeArray.
4402 static const int kMaxSize = 512 * MB;
4403 // Maximal length of a single BytecodeArray.
4404 static const int kMaxLength = kMaxSize - kHeaderSize;
4405
4406 class BodyDescriptor;
4407
4408 private:
4409 DISALLOW_IMPLICIT_CONSTRUCTORS(BytecodeArray);
4410};
4411
4412
4413// FreeSpace are fixed-size free memory blocks used by the heap and GC.
4414// They look like heap objects (are heap object tagged and have a map) so that
4415// the heap remains iterable. They have a size and a next pointer.
4416// The next pointer is the raw address of the next FreeSpace object (or NULL)
4417// in the free list.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004418class FreeSpace: public HeapObject {
4419 public:
4420 // [size]: size of the free space including the header.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004421 inline int size() const;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004422 inline void set_size(int value);
4423
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004424 inline int nobarrier_size() const;
4425 inline void nobarrier_set_size(int value);
4426
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004427 inline int Size();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004428
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004429 // Accessors for the next field.
4430 inline FreeSpace* next();
4431 inline void set_next(FreeSpace* next);
4432
4433 inline static FreeSpace* cast(HeapObject* obj);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004434
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004435 // Dispatched behavior.
4436 DECLARE_PRINTER(FreeSpace)
4437 DECLARE_VERIFIER(FreeSpace)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004438
4439 // Layout description.
4440 // Size is smi tagged when it is stored.
4441 static const int kSizeOffset = HeapObject::kHeaderSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004442 static const int kNextOffset = POINTER_SIZE_ALIGN(kSizeOffset + kPointerSize);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004443
4444 private:
4445 DISALLOW_IMPLICIT_CONSTRUCTORS(FreeSpace);
4446};
4447
4448
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004449// V has parameters (Type, type, TYPE, C type, element_size)
4450#define TYPED_ARRAYS(V) \
4451 V(Uint8, uint8, UINT8, uint8_t, 1) \
4452 V(Int8, int8, INT8, int8_t, 1) \
4453 V(Uint16, uint16, UINT16, uint16_t, 2) \
4454 V(Int16, int16, INT16, int16_t, 2) \
4455 V(Uint32, uint32, UINT32, uint32_t, 4) \
4456 V(Int32, int32, INT32, int32_t, 4) \
4457 V(Float32, float32, FLOAT32, float, 4) \
4458 V(Float64, float64, FLOAT64, double, 8) \
4459 V(Uint8Clamped, uint8_clamped, UINT8_CLAMPED, uint8_t, 1)
4460
4461
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004462class FixedTypedArrayBase: public FixedArrayBase {
4463 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004464 // [base_pointer]: Either points to the FixedTypedArrayBase itself or nullptr.
4465 DECL_ACCESSORS(base_pointer, Object)
4466
4467 // [external_pointer]: Contains the offset between base_pointer and the start
4468 // of the data. If the base_pointer is a nullptr, the external_pointer
4469 // therefore points to the actual backing store.
4470 DECL_ACCESSORS(external_pointer, void)
4471
4472 // Dispatched behavior.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004473 DECLARE_CAST(FixedTypedArrayBase)
4474
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004475 static const int kBasePointerOffset = FixedArrayBase::kHeaderSize;
4476 static const int kExternalPointerOffset = kBasePointerOffset + kPointerSize;
4477 static const int kHeaderSize =
4478 DOUBLE_POINTER_ALIGN(kExternalPointerOffset + kPointerSize);
4479
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004480 static const int kDataOffset = kHeaderSize;
4481
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004482 class BodyDescriptor;
4483
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004484 inline int size();
4485
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004486 static inline int TypedArraySize(InstanceType type, int length);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004487 inline int TypedArraySize(InstanceType type);
4488
4489 // Use with care: returns raw pointer into heap.
4490 inline void* DataPtr();
4491
4492 inline int DataSize();
4493
4494 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004495 static inline int ElementSize(InstanceType type);
4496
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004497 inline int DataSize(InstanceType type);
4498
4499 DISALLOW_IMPLICIT_CONSTRUCTORS(FixedTypedArrayBase);
4500};
4501
4502
4503template <class Traits>
4504class FixedTypedArray: public FixedTypedArrayBase {
4505 public:
4506 typedef typename Traits::ElementType ElementType;
4507 static const InstanceType kInstanceType = Traits::kInstanceType;
4508
4509 DECLARE_CAST(FixedTypedArray<Traits>)
4510
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004511 inline ElementType get_scalar(int index);
4512 static inline Handle<Object> get(Handle<FixedTypedArray> array, int index);
4513 inline void set(int index, ElementType value);
4514
4515 static inline ElementType from_int(int value);
4516 static inline ElementType from_double(double value);
4517
4518 // This accessor applies the correct conversion from Smi, HeapNumber
4519 // and undefined.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004520 inline void SetValue(uint32_t index, Object* value);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004521
4522 DECLARE_PRINTER(FixedTypedArray)
4523 DECLARE_VERIFIER(FixedTypedArray)
4524
4525 private:
4526 DISALLOW_IMPLICIT_CONSTRUCTORS(FixedTypedArray);
4527};
4528
4529#define FIXED_TYPED_ARRAY_TRAITS(Type, type, TYPE, elementType, size) \
4530 class Type##ArrayTraits { \
4531 public: /* NOLINT */ \
4532 typedef elementType ElementType; \
4533 static const InstanceType kInstanceType = FIXED_##TYPE##_ARRAY_TYPE; \
4534 static const char* Designator() { return #type " array"; } \
4535 static inline Handle<Object> ToHandle(Isolate* isolate, \
4536 elementType scalar); \
4537 static inline elementType defaultValue(); \
4538 }; \
4539 \
4540 typedef FixedTypedArray<Type##ArrayTraits> Fixed##Type##Array;
4541
4542TYPED_ARRAYS(FIXED_TYPED_ARRAY_TRAITS)
4543
4544#undef FIXED_TYPED_ARRAY_TRAITS
4545
Emily Bernierd0a1eb72015-03-24 16:35:39 -04004546
Ben Murdochb0fe1622011-05-05 13:52:32 +01004547// DeoptimizationInputData is a fixed array used to hold the deoptimization
4548// data for code generated by the Hydrogen/Lithium compiler. It also
4549// contains information about functions that were inlined. If N different
4550// functions were inlined then first N elements of the literal array will
4551// contain these functions.
4552//
4553// It can be empty.
4554class DeoptimizationInputData: public FixedArray {
4555 public:
4556 // Layout description. Indices in the array.
4557 static const int kTranslationByteArrayIndex = 0;
4558 static const int kInlinedFunctionCountIndex = 1;
4559 static const int kLiteralArrayIndex = 2;
4560 static const int kOsrAstIdIndex = 3;
4561 static const int kOsrPcOffsetIndex = 4;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004562 static const int kOptimizationIdIndex = 5;
4563 static const int kSharedFunctionInfoIndex = 6;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004564 static const int kWeakCellCacheIndex = 7;
4565 static const int kFirstDeoptEntryIndex = 8;
Ben Murdochb0fe1622011-05-05 13:52:32 +01004566
4567 // Offsets of deopt entry elements relative to the start of the entry.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004568 static const int kAstIdRawOffset = 0;
Ben Murdochb0fe1622011-05-05 13:52:32 +01004569 static const int kTranslationIndexOffset = 1;
4570 static const int kArgumentsStackHeightOffset = 2;
Ben Murdoch2b4ba112012-01-20 14:57:15 +00004571 static const int kPcOffset = 3;
4572 static const int kDeoptEntrySize = 4;
Ben Murdochb0fe1622011-05-05 13:52:32 +01004573
4574 // Simple element accessors.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004575#define DECLARE_ELEMENT_ACCESSORS(name, type) \
4576 inline type* name(); \
4577 inline void Set##name(type* value);
Ben Murdochb0fe1622011-05-05 13:52:32 +01004578
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004579 DECLARE_ELEMENT_ACCESSORS(TranslationByteArray, ByteArray)
4580 DECLARE_ELEMENT_ACCESSORS(InlinedFunctionCount, Smi)
4581 DECLARE_ELEMENT_ACCESSORS(LiteralArray, FixedArray)
4582 DECLARE_ELEMENT_ACCESSORS(OsrAstId, Smi)
4583 DECLARE_ELEMENT_ACCESSORS(OsrPcOffset, Smi)
4584 DECLARE_ELEMENT_ACCESSORS(OptimizationId, Smi)
4585 DECLARE_ELEMENT_ACCESSORS(SharedFunctionInfo, Object)
4586 DECLARE_ELEMENT_ACCESSORS(WeakCellCache, Object)
Ben Murdochb0fe1622011-05-05 13:52:32 +01004587
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004588#undef DECLARE_ELEMENT_ACCESSORS
Ben Murdochb0fe1622011-05-05 13:52:32 +01004589
4590 // Accessors for elements of the ith deoptimization entry.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004591#define DECLARE_ENTRY_ACCESSORS(name, type) \
4592 inline type* name(int i); \
4593 inline void Set##name(int i, type* value);
Ben Murdochb0fe1622011-05-05 13:52:32 +01004594
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004595 DECLARE_ENTRY_ACCESSORS(AstIdRaw, Smi)
4596 DECLARE_ENTRY_ACCESSORS(TranslationIndex, Smi)
4597 DECLARE_ENTRY_ACCESSORS(ArgumentsStackHeight, Smi)
4598 DECLARE_ENTRY_ACCESSORS(Pc, Smi)
Ben Murdochb0fe1622011-05-05 13:52:32 +01004599
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004600#undef DECLARE_ENTRY_ACCESSORS
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004601
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004602 inline BailoutId AstId(int i);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004603
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004604 inline void SetAstId(int i, BailoutId value);
Ben Murdochb0fe1622011-05-05 13:52:32 +01004605
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004606 inline int DeoptCount();
Ben Murdochb0fe1622011-05-05 13:52:32 +01004607
4608 // Allocates a DeoptimizationInputData.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004609 static Handle<DeoptimizationInputData> New(Isolate* isolate,
4610 int deopt_entry_count,
4611 PretenureFlag pretenure);
Ben Murdochb0fe1622011-05-05 13:52:32 +01004612
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004613 DECLARE_CAST(DeoptimizationInputData)
Ben Murdochb0fe1622011-05-05 13:52:32 +01004614
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00004615#ifdef ENABLE_DISASSEMBLER
Emily Bernierd0a1eb72015-03-24 16:35:39 -04004616 void DeoptimizationInputDataPrint(std::ostream& os); // NOLINT
Ben Murdochb0fe1622011-05-05 13:52:32 +01004617#endif
4618
4619 private:
4620 static int IndexForEntry(int i) {
4621 return kFirstDeoptEntryIndex + (i * kDeoptEntrySize);
4622 }
4623
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004624
4625 static int LengthFor(int entry_count) { return IndexForEntry(entry_count); }
Ben Murdochb0fe1622011-05-05 13:52:32 +01004626};
4627
4628
4629// DeoptimizationOutputData is a fixed array used to hold the deoptimization
4630// data for code generated by the full compiler.
4631// The format of the these objects is
4632// [i * 2]: Ast ID for ith deoptimization.
4633// [i * 2 + 1]: PC and state of ith deoptimization
4634class DeoptimizationOutputData: public FixedArray {
4635 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004636 inline int DeoptPoints();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004637
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004638 inline BailoutId AstId(int index);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004639
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004640 inline void SetAstId(int index, BailoutId id);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004641
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004642 inline Smi* PcAndState(int index);
4643 inline void SetPcAndState(int index, Smi* offset);
Ben Murdochb0fe1622011-05-05 13:52:32 +01004644
4645 static int LengthOfFixedArray(int deopt_points) {
4646 return deopt_points * 2;
4647 }
4648
4649 // Allocates a DeoptimizationOutputData.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004650 static Handle<DeoptimizationOutputData> New(Isolate* isolate,
4651 int number_of_deopt_points,
4652 PretenureFlag pretenure);
Ben Murdochb0fe1622011-05-05 13:52:32 +01004653
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004654 DECLARE_CAST(DeoptimizationOutputData)
Ben Murdochb0fe1622011-05-05 13:52:32 +01004655
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00004656#if defined(OBJECT_PRINT) || defined(ENABLE_DISASSEMBLER)
Emily Bernierd0a1eb72015-03-24 16:35:39 -04004657 void DeoptimizationOutputDataPrint(std::ostream& os); // NOLINT
Ben Murdochb0fe1622011-05-05 13:52:32 +01004658#endif
4659};
4660
4661
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004662// A literals array contains the literals for a JSFunction. It also holds
4663// the type feedback vector.
4664class LiteralsArray : public FixedArray {
4665 public:
4666 static const int kVectorIndex = 0;
4667 static const int kFirstLiteralIndex = 1;
4668 static const int kOffsetToFirstLiteral =
4669 FixedArray::kHeaderSize + kPointerSize;
4670
4671 static int OffsetOfLiteralAt(int index) {
4672 return SizeFor(index + kFirstLiteralIndex);
4673 }
4674
4675 inline TypeFeedbackVector* feedback_vector() const;
4676 inline void set_feedback_vector(TypeFeedbackVector* vector);
4677 inline Object* literal(int literal_index) const;
4678 inline void set_literal(int literal_index, Object* literal);
4679 inline int literals_count() const;
4680
4681 static Handle<LiteralsArray> New(Isolate* isolate,
4682 Handle<TypeFeedbackVector> vector,
4683 int number_of_literals,
4684 PretenureFlag pretenure);
4685
4686 DECLARE_CAST(LiteralsArray)
4687
4688 private:
4689 inline Object* get(int index) const;
4690 inline void set(int index, Object* value);
4691 inline void set(int index, Smi* value);
4692 inline void set(int index, Object* value, WriteBarrierMode mode);
4693};
4694
4695
4696// HandlerTable is a fixed array containing entries for exception handlers in
4697// the code object it is associated with. The tables comes in two flavors:
4698// 1) Based on ranges: Used for unoptimized code. Contains one entry per
4699// exception handler and a range representing the try-block covered by that
4700// handler. Layout looks as follows:
4701// [ range-start , range-end , handler-offset , stack-depth ]
4702// 2) Based on return addresses: Used for turbofanned code. Contains one entry
4703// per call-site that could throw an exception. Layout looks as follows:
4704// [ return-address-offset , handler-offset ]
4705class HandlerTable : public FixedArray {
4706 public:
4707 // Conservative prediction whether a given handler will locally catch an
4708 // exception or cause a re-throw to outside the code boundary. Since this is
4709 // undecidable it is merely an approximation (e.g. useful for debugger).
4710 enum CatchPrediction { UNCAUGHT, CAUGHT };
4711
4712 // Accessors for handler table based on ranges.
4713 inline void SetRangeStart(int index, int value);
4714 inline void SetRangeEnd(int index, int value);
4715 inline void SetRangeHandler(int index, int offset, CatchPrediction pred);
4716 inline void SetRangeDepth(int index, int value);
4717
4718 // Accessors for handler table based on return addresses.
4719 inline void SetReturnOffset(int index, int value);
4720 inline void SetReturnHandler(int index, int offset, CatchPrediction pred);
4721
4722 // Lookup handler in a table based on ranges.
4723 int LookupRange(int pc_offset, int* stack_depth, CatchPrediction* prediction);
4724
4725 // Lookup handler in a table based on return addresses.
4726 int LookupReturn(int pc_offset, CatchPrediction* prediction);
4727
4728 // Returns the required length of the underlying fixed array.
4729 static int LengthForRange(int entries) { return entries * kRangeEntrySize; }
4730 static int LengthForReturn(int entries) { return entries * kReturnEntrySize; }
4731
4732 DECLARE_CAST(HandlerTable)
4733
4734#if defined(OBJECT_PRINT) || defined(ENABLE_DISASSEMBLER)
4735 void HandlerTableRangePrint(std::ostream& os); // NOLINT
4736 void HandlerTableReturnPrint(std::ostream& os); // NOLINT
4737#endif
4738
4739 private:
4740 // Layout description for handler table based on ranges.
4741 static const int kRangeStartIndex = 0;
4742 static const int kRangeEndIndex = 1;
4743 static const int kRangeHandlerIndex = 2;
4744 static const int kRangeDepthIndex = 3;
4745 static const int kRangeEntrySize = 4;
4746
4747 // Layout description for handler table based on return addresses.
4748 static const int kReturnOffsetIndex = 0;
4749 static const int kReturnHandlerIndex = 1;
4750 static const int kReturnEntrySize = 2;
4751
4752 // Encoding of the {handler} field.
4753 class HandlerPredictionField : public BitField<CatchPrediction, 0, 1> {};
4754 class HandlerOffsetField : public BitField<int, 1, 30> {};
4755};
4756
Ben Murdochb8e0da22011-05-16 14:20:40 +01004757
Steve Blocka7e24c12009-10-30 11:49:00 +00004758// Code describes objects with on-the-fly generated machine code.
4759class Code: public HeapObject {
4760 public:
4761 // Opaque data type for encapsulating code flags like kind, inline
4762 // cache state, and arguments count.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004763 typedef uint32_t Flags;
4764
4765#define NON_IC_KIND_LIST(V) \
4766 V(FUNCTION) \
4767 V(OPTIMIZED_FUNCTION) \
4768 V(STUB) \
4769 V(HANDLER) \
4770 V(BUILTIN) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004771 V(REGEXP) \
4772 V(WASM_FUNCTION)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004773
4774#define IC_KIND_LIST(V) \
4775 V(LOAD_IC) \
4776 V(KEYED_LOAD_IC) \
4777 V(CALL_IC) \
4778 V(STORE_IC) \
4779 V(KEYED_STORE_IC) \
4780 V(BINARY_OP_IC) \
4781 V(COMPARE_IC) \
4782 V(COMPARE_NIL_IC) \
4783 V(TO_BOOLEAN_IC)
4784
4785#define CODE_KIND_LIST(V) \
4786 NON_IC_KIND_LIST(V) \
4787 IC_KIND_LIST(V)
Steve Blocka7e24c12009-10-30 11:49:00 +00004788
4789 enum Kind {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004790#define DEFINE_CODE_KIND_ENUM(name) name,
4791 CODE_KIND_LIST(DEFINE_CODE_KIND_ENUM)
4792#undef DEFINE_CODE_KIND_ENUM
4793 NUMBER_OF_KINDS
Steve Blocka7e24c12009-10-30 11:49:00 +00004794 };
4795
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004796 // No more than 32 kinds. The value is currently encoded in five bits in
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004797 // Flags.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004798 STATIC_ASSERT(NUMBER_OF_KINDS <= 32);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004799
4800 static const char* Kind2String(Kind kind);
4801
4802 // Types of stubs.
4803 enum StubType {
4804 NORMAL,
4805 FAST
Steve Blocka7e24c12009-10-30 11:49:00 +00004806 };
4807
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004808 static const int kPrologueOffsetNotSet = -1;
Ben Murdochb8e0da22011-05-16 14:20:40 +01004809
Steve Blocka7e24c12009-10-30 11:49:00 +00004810#ifdef ENABLE_DISASSEMBLER
4811 // Printing
Steve Blocka7e24c12009-10-30 11:49:00 +00004812 static const char* ICState2String(InlineCacheState state);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004813 static const char* StubType2String(StubType type);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04004814 static void PrintExtraICState(std::ostream& os, // NOLINT
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004815 Kind kind, ExtraICState extra);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04004816 void Disassemble(const char* name, std::ostream& os); // NOLINT
Steve Blocka7e24c12009-10-30 11:49:00 +00004817#endif // ENABLE_DISASSEMBLER
4818
4819 // [instruction_size]: Size of the native instructions
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004820 inline int instruction_size() const;
Steve Blocka7e24c12009-10-30 11:49:00 +00004821 inline void set_instruction_size(int value);
4822
Leon Clarkeac952652010-07-15 11:15:24 +01004823 // [relocation_info]: Code relocation information
4824 DECL_ACCESSORS(relocation_info, ByteArray)
Ben Murdochb0fe1622011-05-05 13:52:32 +01004825 void InvalidateRelocation();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004826 void InvalidateEmbeddedObjects();
Leon Clarkeac952652010-07-15 11:15:24 +01004827
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004828 // [handler_table]: Fixed array containing offsets of exception handlers.
4829 DECL_ACCESSORS(handler_table, FixedArray)
4830
Ben Murdochb0fe1622011-05-05 13:52:32 +01004831 // [deoptimization_data]: Array containing data for deopt.
4832 DECL_ACCESSORS(deoptimization_data, FixedArray)
4833
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004834 // [raw_type_feedback_info]: This field stores various things, depending on
4835 // the kind of the code object.
4836 // FUNCTION => type feedback information.
4837 // STUB and ICs => major/minor key as Smi.
4838 DECL_ACCESSORS(raw_type_feedback_info, Object)
4839 inline Object* type_feedback_info();
4840 inline void set_type_feedback_info(
4841 Object* value, WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
4842 inline uint32_t stub_key();
4843 inline void set_stub_key(uint32_t key);
4844
4845 // [next_code_link]: Link for lists of optimized or deoptimized code.
4846 // Note that storage for this field is overlapped with typefeedback_info.
4847 DECL_ACCESSORS(next_code_link, Object)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004848
4849 // [gc_metadata]: Field used to hold GC related metadata. The contents of this
Ben Murdoch257744e2011-11-30 15:57:28 +00004850 // field does not have to be traced during garbage collection since
4851 // it is only used by the garbage collector itself.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004852 DECL_ACCESSORS(gc_metadata, Object)
4853
4854 // [ic_age]: Inline caching age: the value of the Heap::global_ic_age
4855 // at the moment when this object was created.
4856 inline void set_ic_age(int count);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004857 inline int ic_age() const;
4858
4859 // [prologue_offset]: Offset of the function prologue, used for aging
4860 // FUNCTIONs and OPTIMIZED_FUNCTIONs.
4861 inline int prologue_offset() const;
4862 inline void set_prologue_offset(int offset);
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01004863
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004864 // [constant_pool offset]: Offset of the constant pool.
4865 // Valid for FLAG_enable_embedded_constant_pool only
4866 inline int constant_pool_offset() const;
4867 inline void set_constant_pool_offset(int offset);
4868
Ben Murdochb0fe1622011-05-05 13:52:32 +01004869 // Unchecked accessors to be used during GC.
Leon Clarkeac952652010-07-15 11:15:24 +01004870 inline ByteArray* unchecked_relocation_info();
4871
Steve Blocka7e24c12009-10-30 11:49:00 +00004872 inline int relocation_size();
Steve Blocka7e24c12009-10-30 11:49:00 +00004873
Steve Blocka7e24c12009-10-30 11:49:00 +00004874 // [flags]: Various code flags.
4875 inline Flags flags();
4876 inline void set_flags(Flags flags);
4877
4878 // [flags]: Access to specific code flags.
4879 inline Kind kind();
4880 inline InlineCacheState ic_state(); // Only valid for IC stubs.
Ben Murdochb8e0da22011-05-16 14:20:40 +01004881 inline ExtraICState extra_ic_state(); // Only valid for IC stubs.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004882
4883 inline StubType type(); // Only valid for monomorphic IC stubs.
Steve Blocka7e24c12009-10-30 11:49:00 +00004884
4885 // Testers for IC stub kinds.
4886 inline bool is_inline_cache_stub();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004887 inline bool is_debug_stub();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004888 inline bool is_handler();
4889 inline bool is_load_stub();
4890 inline bool is_keyed_load_stub();
4891 inline bool is_store_stub();
4892 inline bool is_keyed_store_stub();
4893 inline bool is_call_stub();
4894 inline bool is_binary_op_stub();
4895 inline bool is_compare_ic_stub();
4896 inline bool is_compare_nil_ic_stub();
4897 inline bool is_to_boolean_ic_stub();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004898 inline bool is_keyed_stub();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004899 inline bool is_optimized_code();
4900 inline bool is_interpreter_entry_trampoline();
4901 inline bool embeds_maps_weakly();
Ben Murdochb0fe1622011-05-05 13:52:32 +01004902
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004903 inline bool IsCodeStubOrIC();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004904 inline bool IsJavaScriptCode();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004905
4906 inline void set_raw_kind_specific_flags1(int value);
4907 inline void set_raw_kind_specific_flags2(int value);
4908
4909 // [is_crankshafted]: For kind STUB or ICs, tells whether or not a code
4910 // object was generated by either the hydrogen or the TurboFan optimizing
4911 // compiler (but it may not be an optimized function).
4912 inline bool is_crankshafted();
4913 inline bool is_hydrogen_stub(); // Crankshafted, but not a function.
4914 inline void set_is_crankshafted(bool value);
4915
4916 // [is_turbofanned]: For kind STUB or OPTIMIZED_FUNCTION, tells whether the
4917 // code object was generated by the TurboFan optimizing compiler.
4918 inline bool is_turbofanned();
4919 inline void set_is_turbofanned(bool value);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004920
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004921 // [can_have_weak_objects]: For kind OPTIMIZED_FUNCTION, tells whether the
4922 // embedded objects in code should be treated weakly.
4923 inline bool can_have_weak_objects();
4924 inline void set_can_have_weak_objects(bool value);
Ben Murdochb0fe1622011-05-05 13:52:32 +01004925
4926 // [has_deoptimization_support]: For FUNCTION kind, tells if it has
4927 // deoptimization support.
4928 inline bool has_deoptimization_support();
4929 inline void set_has_deoptimization_support(bool value);
4930
Ben Murdoch589d6972011-11-30 16:04:58 +00004931 // [has_debug_break_slots]: For FUNCTION kind, tells if it has
4932 // been compiled with debug break slots.
4933 inline bool has_debug_break_slots();
4934 inline void set_has_debug_break_slots(bool value);
4935
Emily Bernierd0a1eb72015-03-24 16:35:39 -04004936 // [has_reloc_info_for_serialization]: For FUNCTION kind, tells if its
4937 // reloc info includes runtime and external references to support
4938 // serialization/deserialization.
4939 inline bool has_reloc_info_for_serialization();
4940 inline void set_has_reloc_info_for_serialization(bool value);
4941
Ben Murdochb0fe1622011-05-05 13:52:32 +01004942 // [allow_osr_at_loop_nesting_level]: For FUNCTION kind, tells for
4943 // how long the function has been marked for OSR and therefore which
4944 // level of loop nesting we are willing to do on-stack replacement
4945 // for.
4946 inline void set_allow_osr_at_loop_nesting_level(int level);
4947 inline int allow_osr_at_loop_nesting_level();
4948
Ben Murdoch8f9999f2012-04-23 10:39:17 +01004949 // [profiler_ticks]: For FUNCTION kind, tells for how many profiler ticks
4950 // the code object was seen on the stack with no IC patching going on.
4951 inline int profiler_ticks();
4952 inline void set_profiler_ticks(int ticks);
4953
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004954 // [builtin_index]: For BUILTIN kind, tells which builtin index it has.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04004955 // For builtins, tells which builtin index it has.
4956 // Note that builtins can have a code kind other than BUILTIN, which means
4957 // that for arbitrary code objects, this index value may be random garbage.
4958 // To verify in that case, compare the code object to the indexed builtin.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004959 inline int builtin_index();
4960 inline void set_builtin_index(int id);
4961
Ben Murdochb0fe1622011-05-05 13:52:32 +01004962 // [stack_slots]: For kind OPTIMIZED_FUNCTION, the number of stack slots
4963 // reserved in the code prologue.
4964 inline unsigned stack_slots();
4965 inline void set_stack_slots(unsigned slots);
4966
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004967 // [safepoint_table_start]: For kind OPTIMIZED_FUNCTION, the offset in
Ben Murdochb0fe1622011-05-05 13:52:32 +01004968 // the instruction stream where the safepoint table starts.
Steve Block1e0659c2011-05-24 12:43:12 +01004969 inline unsigned safepoint_table_offset();
4970 inline void set_safepoint_table_offset(unsigned offset);
Ben Murdochb0fe1622011-05-05 13:52:32 +01004971
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004972 // [back_edge_table_start]: For kind FUNCTION, the offset in the
4973 // instruction stream where the back edge table starts.
4974 inline unsigned back_edge_table_offset();
4975 inline void set_back_edge_table_offset(unsigned offset);
Ben Murdochb0fe1622011-05-05 13:52:32 +01004976
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004977 inline bool back_edges_patched_for_osr();
Ben Murdochb0fe1622011-05-05 13:52:32 +01004978
Ben Murdoch69a99ed2011-11-30 16:03:39 +00004979 // [to_boolean_foo]: For kind TO_BOOLEAN_IC tells what state the stub is in.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004980 inline uint16_t to_boolean_state();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004981
4982 // [marked_for_deoptimization]: For kind OPTIMIZED_FUNCTION tells whether
4983 // the code is going to be deoptimized because of dead embedded maps.
4984 inline bool marked_for_deoptimization();
4985 inline void set_marked_for_deoptimization(bool flag);
4986
4987 // [constant_pool]: The constant pool for this function.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004988 inline Address constant_pool();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004989
Ben Murdochb8e0da22011-05-16 14:20:40 +01004990 // Get the safepoint entry for the given pc.
4991 SafepointEntry GetSafepointEntry(Address pc);
Ben Murdochb0fe1622011-05-05 13:52:32 +01004992
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004993 // Find an object in a stub with a specified map
4994 Object* FindNthObject(int n, Map* match_map);
4995
4996 // Find the first allocation site in an IC stub.
4997 AllocationSite* FindFirstAllocationSite();
Ben Murdochb0fe1622011-05-05 13:52:32 +01004998
4999 // Find the first map in an IC stub.
5000 Map* FindFirstMap();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005001 void FindAllMaps(MapHandleList* maps);
Steve Blocka7e24c12009-10-30 11:49:00 +00005002
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005003 // Find the first handler in an IC stub.
5004 Code* FindFirstHandler();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005005
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005006 // Find |length| handlers and put them into |code_list|. Returns false if not
5007 // enough handlers can be found.
5008 bool FindHandlers(CodeHandleList* code_list, int length = -1);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005009
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005010 // Find the handler for |map|.
5011 MaybeHandle<Code> FindHandlerForMap(Map* map);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005012
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005013 // Find the first name in an IC stub.
5014 Name* FindFirstName();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005015
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005016 class FindAndReplacePattern;
5017 // For each (map-to-find, object-to-replace) pair in the pattern, this
5018 // function replaces the corresponding placeholder in the code with the
5019 // object-to-replace. The function assumes that pairs in the pattern come in
5020 // the same order as the placeholders in the code.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005021 // If the placeholder is a weak cell, then the value of weak cell is matched
5022 // against the map-to-find.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005023 void FindAndReplace(const FindAndReplacePattern& pattern);
5024
5025 // The entire code object including its header is copied verbatim to the
5026 // snapshot so that it can be written in one, fast, memcpy during
5027 // deserialization. The deserializer will overwrite some pointers, rather
5028 // like a runtime linker, but the random allocation addresses used in the
5029 // mksnapshot process would still be present in the unlinked snapshot data,
5030 // which would make snapshot production non-reproducible. This method wipes
5031 // out the to-be-overwritten header data for reproducible snapshots.
5032 inline void WipeOutHeader();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005033
Steve Blocka7e24c12009-10-30 11:49:00 +00005034 // Flags operations.
Ben Murdochb8e0da22011-05-16 14:20:40 +01005035 static inline Flags ComputeFlags(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005036 Kind kind, InlineCacheState ic_state = UNINITIALIZED,
5037 ExtraICState extra_ic_state = kNoExtraICState, StubType type = NORMAL,
5038 CacheHolderFlag holder = kCacheOnReceiver);
Steve Blocka7e24c12009-10-30 11:49:00 +00005039
5040 static inline Flags ComputeMonomorphicFlags(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005041 Kind kind, ExtraICState extra_ic_state = kNoExtraICState,
5042 CacheHolderFlag holder = kCacheOnReceiver, StubType type = NORMAL);
5043
5044 static inline Flags ComputeHandlerFlags(
5045 Kind handler_kind, StubType type = NORMAL,
5046 CacheHolderFlag holder = kCacheOnReceiver);
Steve Blocka7e24c12009-10-30 11:49:00 +00005047
Steve Blocka7e24c12009-10-30 11:49:00 +00005048 static inline InlineCacheState ExtractICStateFromFlags(Flags flags);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005049 static inline StubType ExtractTypeFromFlags(Flags flags);
5050 static inline CacheHolderFlag ExtractCacheHolderFromFlags(Flags flags);
Ben Murdoch589d6972011-11-30 16:04:58 +00005051 static inline Kind ExtractKindFromFlags(Flags flags);
Ben Murdoch589d6972011-11-30 16:04:58 +00005052 static inline ExtraICState ExtractExtraICStateFromFlags(Flags flags);
Ben Murdoch589d6972011-11-30 16:04:58 +00005053
Steve Blocka7e24c12009-10-30 11:49:00 +00005054 static inline Flags RemoveTypeFromFlags(Flags flags);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005055 static inline Flags RemoveTypeAndHolderFromFlags(Flags flags);
Steve Blocka7e24c12009-10-30 11:49:00 +00005056
5057 // Convert a target address into a code object.
5058 static inline Code* GetCodeFromTargetAddress(Address address);
5059
Steve Block791712a2010-08-27 10:21:07 +01005060 // Convert an entry address into an object.
5061 static inline Object* GetObjectFromEntryAddress(Address location_of_address);
5062
Steve Blocka7e24c12009-10-30 11:49:00 +00005063 // Returns the address of the first instruction.
5064 inline byte* instruction_start();
5065
Leon Clarkeac952652010-07-15 11:15:24 +01005066 // Returns the address right after the last instruction.
5067 inline byte* instruction_end();
5068
Steve Blocka7e24c12009-10-30 11:49:00 +00005069 // Returns the size of the instructions, padding, and relocation information.
5070 inline int body_size();
5071
5072 // Returns the address of the first relocation info (read backwards!).
5073 inline byte* relocation_start();
5074
5075 // Code entry point.
5076 inline byte* entry();
5077
5078 // Returns true if pc is inside this object's instructions.
5079 inline bool contains(byte* pc);
5080
Steve Blocka7e24c12009-10-30 11:49:00 +00005081 // Relocate the code by delta bytes. Called to signal that this code
5082 // object has been moved by delta bytes.
Steve Blockd0582a62009-12-15 09:54:21 +00005083 void Relocate(intptr_t delta);
Steve Blocka7e24c12009-10-30 11:49:00 +00005084
5085 // Migrate code described by desc.
5086 void CopyFrom(const CodeDesc& desc);
5087
Ben Murdoch3bec4d22010-07-22 14:51:16 +01005088 // Returns the object size for a given body (used for allocation).
5089 static int SizeFor(int body_size) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005090 DCHECK_SIZE_TAG_ALIGNED(body_size);
Ben Murdoch3bec4d22010-07-22 14:51:16 +01005091 return RoundUp(kHeaderSize + body_size, kCodeAlignment);
Steve Blocka7e24c12009-10-30 11:49:00 +00005092 }
5093
5094 // Calculate the size of the code object to report for log events. This takes
5095 // the layout of the code object into account.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005096 inline int ExecutableSize();
Steve Blocka7e24c12009-10-30 11:49:00 +00005097
5098 // Locating source position.
5099 int SourcePosition(Address pc);
5100 int SourceStatementPosition(Address pc);
5101
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005102 DECLARE_CAST(Code)
Steve Blocka7e24c12009-10-30 11:49:00 +00005103
5104 // Dispatched behavior.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005105 inline int CodeSize();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005106
5107 DECLARE_PRINTER(Code)
5108 DECLARE_VERIFIER(Code)
5109
Ben Murdoch8f9999f2012-04-23 10:39:17 +01005110 void ClearInlineCaches();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005111 void ClearInlineCaches(Kind kind);
5112
5113 BailoutId TranslatePcOffsetToAstId(uint32_t pc_offset);
5114 uint32_t TranslateAstIdToPcOffset(BailoutId ast_id);
5115
5116#define DECLARE_CODE_AGE_ENUM(X) k##X##CodeAge,
5117 enum Age {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005118 kToBeExecutedOnceCodeAge = -3,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005119 kNotExecutedCodeAge = -2,
5120 kExecutedOnceCodeAge = -1,
5121 kNoAgeCodeAge = 0,
5122 CODE_AGE_LIST(DECLARE_CODE_AGE_ENUM)
5123 kAfterLastCodeAge,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005124 kFirstCodeAge = kToBeExecutedOnceCodeAge,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005125 kLastCodeAge = kAfterLastCodeAge - 1,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005126 kCodeAgeCount = kAfterLastCodeAge - kFirstCodeAge - 1,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005127 kIsOldCodeAge = kSexagenarianCodeAge,
5128 kPreAgedCodeAge = kIsOldCodeAge - 1
5129 };
5130#undef DECLARE_CODE_AGE_ENUM
5131
5132 // Code aging. Indicates how many full GCs this code has survived without
5133 // being entered through the prologue. Used to determine when it is
5134 // relatively safe to flush this code object and replace it with the lazy
5135 // compilation stub.
5136 static void MakeCodeAgeSequenceYoung(byte* sequence, Isolate* isolate);
5137 static void MarkCodeAsExecuted(byte* sequence, Isolate* isolate);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005138 void MakeYoung(Isolate* isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005139 void MarkToBeExecutedOnce(Isolate* isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005140 void MakeOlder(MarkingParity);
5141 static bool IsYoungSequence(Isolate* isolate, byte* sequence);
5142 bool IsOld();
5143 Age GetAge();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005144 static inline Code* GetPreAgedCodeAgeStub(Isolate* isolate) {
5145 return GetCodeAgeStub(isolate, kNotExecutedCodeAge, NO_MARKING_PARITY);
5146 }
5147
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005148 void PrintDeoptLocation(FILE* out, Address pc);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005149 bool CanDeoptAt(Address pc);
5150
5151#ifdef VERIFY_HEAP
5152 void VerifyEmbeddedObjectsDependency();
5153#endif
5154
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005155#ifdef DEBUG
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005156 enum VerifyMode { kNoContextSpecificPointers, kNoContextRetainingPointers };
5157 void VerifyEmbeddedObjects(VerifyMode mode = kNoContextRetainingPointers);
5158 static void VerifyRecompiledCode(Code* old_code, Code* new_code);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005159#endif // DEBUG
5160
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005161 inline bool CanContainWeakObjects();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005162
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005163 inline bool IsWeakObject(Object* object);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005164
5165 static inline bool IsWeakObjectInOptimizedCode(Object* object);
Ben Murdochb0fe1622011-05-05 13:52:32 +01005166
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005167 static Handle<WeakCell> WeakCellFor(Handle<Code> code);
5168 WeakCell* CachedWeakCell();
5169
Ben Murdochb0fe1622011-05-05 13:52:32 +01005170 // Max loop nesting marker used to postpose OSR. We don't take loop
5171 // nesting that is deeper than 5 levels into account.
5172 static const int kMaxLoopNestingMarker = 6;
5173
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005174 static const int kConstantPoolSize =
5175 FLAG_enable_embedded_constant_pool ? kIntSize : 0;
5176
Steve Blocka7e24c12009-10-30 11:49:00 +00005177 // Layout description.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005178 static const int kRelocationInfoOffset = HeapObject::kHeaderSize;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005179 static const int kHandlerTableOffset = kRelocationInfoOffset + kPointerSize;
Ben Murdochb0fe1622011-05-05 13:52:32 +01005180 static const int kDeoptimizationDataOffset =
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005181 kHandlerTableOffset + kPointerSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005182 // For FUNCTION kind, we store the type feedback info here.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005183 static const int kTypeFeedbackInfoOffset =
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01005184 kDeoptimizationDataOffset + kPointerSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005185 static const int kNextCodeLinkOffset = kTypeFeedbackInfoOffset + kPointerSize;
5186 static const int kGCMetadataOffset = kNextCodeLinkOffset + kPointerSize;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005187 static const int kInstructionSizeOffset = kGCMetadataOffset + kPointerSize;
5188 static const int kICAgeOffset = kInstructionSizeOffset + kIntSize;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005189 static const int kFlagsOffset = kICAgeOffset + kIntSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005190 static const int kKindSpecificFlags1Offset = kFlagsOffset + kIntSize;
5191 static const int kKindSpecificFlags2Offset =
5192 kKindSpecificFlags1Offset + kIntSize;
5193 // Note: We might be able to squeeze this into the flags above.
5194 static const int kPrologueOffset = kKindSpecificFlags2Offset + kIntSize;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005195 static const int kConstantPoolOffset = kPrologueOffset + kIntSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005196 static const int kHeaderPaddingStart =
5197 kConstantPoolOffset + kConstantPoolSize;
Ben Murdochb0fe1622011-05-05 13:52:32 +01005198
Steve Blocka7e24c12009-10-30 11:49:00 +00005199 // Add padding to align the instruction start following right after
5200 // the Code object header.
5201 static const int kHeaderSize =
Ben Murdochb0fe1622011-05-05 13:52:32 +01005202 (kHeaderPaddingStart + kCodeAlignmentMask) & ~kCodeAlignmentMask;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005203
5204 class BodyDescriptor;
Steve Blocka7e24c12009-10-30 11:49:00 +00005205
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005206 // Byte offsets within kKindSpecificFlags1Offset.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005207 static const int kFullCodeFlags = kKindSpecificFlags1Offset;
Ben Murdoch589d6972011-11-30 16:04:58 +00005208 class FullCodeFlagsHasDeoptimizationSupportField:
5209 public BitField<bool, 0, 1> {}; // NOLINT
5210 class FullCodeFlagsHasDebugBreakSlotsField: public BitField<bool, 1, 1> {};
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005211 class FullCodeFlagsHasRelocInfoForSerialization
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005212 : public BitField<bool, 2, 1> {};
5213 // Bit 3 in this bitfield is unused.
5214 class ProfilerTicksField : public BitField<int, 4, 28> {};
Steve Blocka7e24c12009-10-30 11:49:00 +00005215
Ben Murdoch589d6972011-11-30 16:04:58 +00005216 // Flags layout. BitField<type, shift, size>.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005217 class ICStateField : public BitField<InlineCacheState, 0, 3> {};
5218 class TypeField : public BitField<StubType, 3, 1> {};
5219 class CacheHolderField : public BitField<CacheHolderFlag, 4, 2> {};
5220 class KindField : public BitField<Kind, 6, 5> {};
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005221 class ExtraICStateField: public BitField<ExtraICState, 11,
5222 PlatformSmiTagging::kSmiValueSize - 11 + 1> {}; // NOLINT
Steve Blocka7e24c12009-10-30 11:49:00 +00005223
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005224 // KindSpecificFlags1 layout (STUB and OPTIMIZED_FUNCTION)
5225 static const int kStackSlotsFirstBit = 0;
5226 static const int kStackSlotsBitCount = 24;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005227 static const int kMarkedForDeoptimizationBit =
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005228 kStackSlotsFirstBit + kStackSlotsBitCount;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005229 static const int kIsTurbofannedBit = kMarkedForDeoptimizationBit + 1;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005230 static const int kCanHaveWeakObjects = kIsTurbofannedBit + 1;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005231
5232 STATIC_ASSERT(kStackSlotsFirstBit + kStackSlotsBitCount <= 32);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005233 STATIC_ASSERT(kCanHaveWeakObjects + 1 <= 32);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005234
5235 class StackSlotsField: public BitField<int,
5236 kStackSlotsFirstBit, kStackSlotsBitCount> {}; // NOLINT
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005237 class MarkedForDeoptimizationField
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005238 : public BitField<bool, kMarkedForDeoptimizationBit, 1> {}; // NOLINT
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005239 class IsTurbofannedField : public BitField<bool, kIsTurbofannedBit, 1> {
5240 }; // NOLINT
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005241 class CanHaveWeakObjectsField
5242 : public BitField<bool, kCanHaveWeakObjects, 1> {}; // NOLINT
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005243
5244 // KindSpecificFlags2 layout (ALL)
5245 static const int kIsCrankshaftedBit = 0;
5246 class IsCrankshaftedField: public BitField<bool,
5247 kIsCrankshaftedBit, 1> {}; // NOLINT
5248
5249 // KindSpecificFlags2 layout (STUB and OPTIMIZED_FUNCTION)
5250 static const int kSafepointTableOffsetFirstBit = kIsCrankshaftedBit + 1;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005251 static const int kSafepointTableOffsetBitCount = 30;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005252
5253 STATIC_ASSERT(kSafepointTableOffsetFirstBit +
5254 kSafepointTableOffsetBitCount <= 32);
5255 STATIC_ASSERT(1 + kSafepointTableOffsetBitCount <= 32);
5256
5257 class SafepointTableOffsetField: public BitField<int,
5258 kSafepointTableOffsetFirstBit,
5259 kSafepointTableOffsetBitCount> {}; // NOLINT
5260
5261 // KindSpecificFlags2 layout (FUNCTION)
5262 class BackEdgeTableOffsetField: public BitField<int,
5263 kIsCrankshaftedBit + 1, 27> {}; // NOLINT
5264 class AllowOSRAtLoopNestingLevelField: public BitField<int,
5265 kIsCrankshaftedBit + 1 + 27, 4> {}; // NOLINT
5266 STATIC_ASSERT(AllowOSRAtLoopNestingLevelField::kMax >= kMaxLoopNestingMarker);
5267
5268 static const int kArgumentsBits = 16;
5269 static const int kMaxArguments = (1 << kArgumentsBits) - 1;
Steve Blocka7e24c12009-10-30 11:49:00 +00005270
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005271 // This constant should be encodable in an ARM instruction.
Steve Blocka7e24c12009-10-30 11:49:00 +00005272 static const int kFlagsNotUsedInLookup =
Ben Murdoch589d6972011-11-30 16:04:58 +00005273 TypeField::kMask | CacheHolderField::kMask;
Steve Blocka7e24c12009-10-30 11:49:00 +00005274
5275 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005276 friend class RelocIterator;
5277 friend class Deoptimizer; // For FindCodeAgeSequence.
5278
5279 void ClearInlineCaches(Kind* kind);
5280
5281 // Code aging
5282 byte* FindCodeAgeSequence();
5283 static void GetCodeAgeAndParity(Code* code, Age* age,
5284 MarkingParity* parity);
5285 static void GetCodeAgeAndParity(Isolate* isolate, byte* sequence, Age* age,
5286 MarkingParity* parity);
5287 static Code* GetCodeAgeStub(Isolate* isolate, Age age, MarkingParity parity);
5288
5289 // Code aging -- platform-specific
5290 static void PatchPlatformCodeAge(Isolate* isolate,
5291 byte* sequence, Age age,
5292 MarkingParity parity);
5293
Steve Blocka7e24c12009-10-30 11:49:00 +00005294 DISALLOW_IMPLICIT_CONSTRUCTORS(Code);
5295};
5296
5297
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005298// Dependent code is a singly linked list of fixed arrays. Each array contains
5299// code objects in weak cells for one dependent group. The suffix of the array
5300// can be filled with the undefined value if the number of codes is less than
5301// the length of the array.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005302//
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005303// +------+-----------------+--------+--------+-----+--------+-----------+-----+
5304// | next | count & group 1 | code 1 | code 2 | ... | code n | undefined | ... |
5305// +------+-----------------+--------+--------+-----+--------+-----------+-----+
5306// |
5307// V
5308// +------+-----------------+--------+--------+-----+--------+-----------+-----+
5309// | next | count & group 2 | code 1 | code 2 | ... | code m | undefined | ... |
5310// +------+-----------------+--------+--------+-----+--------+-----------+-----+
5311// |
5312// V
5313// empty_fixed_array()
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005314//
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005315// The list of fixed arrays is ordered by dependency groups.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005316
5317class DependentCode: public FixedArray {
5318 public:
5319 enum DependencyGroup {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005320 // Group of code that weakly embed this map and depend on being
5321 // deoptimized when the map is garbage collected.
5322 kWeakCodeGroup,
5323 // Group of code that embed a transition to this map, and depend on being
5324 // deoptimized when the transition is replaced by a new version.
5325 kTransitionGroup,
5326 // Group of code that omit run-time prototype checks for prototypes
5327 // described by this map. The group is deoptimized whenever an object
5328 // described by this map changes shape (and transitions to a new map),
5329 // possibly invalidating the assumptions embedded in the code.
5330 kPrototypeCheckGroup,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005331 // Group of code that depends on global property values in property cells
5332 // not being changed.
5333 kPropertyCellChangedGroup,
5334 // Group of code that omit run-time type checks for the field(s) introduced
5335 // by this map.
5336 kFieldTypeGroup,
5337 // Group of code that omit run-time type checks for initial maps of
5338 // constructors.
5339 kInitialMapChangedGroup,
5340 // Group of code that depends on tenuring information in AllocationSites
5341 // not being changed.
5342 kAllocationSiteTenuringChangedGroup,
5343 // Group of code that depends on element transition information in
5344 // AllocationSites not being changed.
5345 kAllocationSiteTransitionChangedGroup
5346 };
5347
5348 static const int kGroupCount = kAllocationSiteTransitionChangedGroup + 1;
5349
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005350 bool Contains(DependencyGroup group, WeakCell* code_cell);
5351 bool IsEmpty(DependencyGroup group);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005352
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005353 static Handle<DependentCode> InsertCompilationDependencies(
5354 Handle<DependentCode> entries, DependencyGroup group,
5355 Handle<Foreign> info);
5356
5357 static Handle<DependentCode> InsertWeakCode(Handle<DependentCode> entries,
5358 DependencyGroup group,
5359 Handle<WeakCell> code_cell);
5360
5361 void UpdateToFinishedCode(DependencyGroup group, Foreign* info,
5362 WeakCell* code_cell);
5363
5364 void RemoveCompilationDependencies(DependentCode::DependencyGroup group,
5365 Foreign* info);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005366
5367 void DeoptimizeDependentCodeGroup(Isolate* isolate,
5368 DependentCode::DependencyGroup group);
5369
5370 bool MarkCodeForDeoptimization(Isolate* isolate,
5371 DependentCode::DependencyGroup group);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005372
5373 // The following low-level accessors should only be used by this class
5374 // and the mark compact collector.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005375 inline DependentCode* next_link();
5376 inline void set_next_link(DependentCode* next);
5377 inline int count();
5378 inline void set_count(int value);
5379 inline DependencyGroup group();
5380 inline void set_group(DependencyGroup group);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005381 inline Object* object_at(int i);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005382 inline void set_object_at(int i, Object* object);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005383 inline void clear_at(int i);
5384 inline void copy(int from, int to);
5385 DECLARE_CAST(DependentCode)
5386
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005387 static const char* DependencyGroupName(DependencyGroup group);
5388 static void SetMarkedForDeoptimization(Code* code, DependencyGroup group);
5389
5390 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005391 static Handle<DependentCode> Insert(Handle<DependentCode> entries,
5392 DependencyGroup group,
5393 Handle<Object> object);
5394 static Handle<DependentCode> New(DependencyGroup group, Handle<Object> object,
5395 Handle<DependentCode> next);
5396 static Handle<DependentCode> EnsureSpace(Handle<DependentCode> entries);
5397 // Compact by removing cleared weak cells and return true if there was
5398 // any cleared weak cell.
5399 bool Compact();
5400 static int Grow(int number_of_entries) {
5401 if (number_of_entries < 5) return number_of_entries + 1;
5402 return number_of_entries * 5 / 4;
5403 }
5404 inline int flags();
5405 inline void set_flags(int flags);
5406 class GroupField : public BitField<int, 0, 3> {};
5407 class CountField : public BitField<int, 3, 27> {};
5408 STATIC_ASSERT(kGroupCount <= GroupField::kMax + 1);
5409 static const int kNextLinkIndex = 0;
5410 static const int kFlagsIndex = 1;
5411 static const int kCodesStartIndex = 2;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005412};
5413
5414
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005415class PrototypeInfo;
5416
5417
Steve Blocka7e24c12009-10-30 11:49:00 +00005418// All heap objects have a Map that describes their structure.
5419// A Map contains information about:
5420// - Size information about the object
5421// - How to iterate over an object (for garbage collection)
5422class Map: public HeapObject {
5423 public:
5424 // Instance size.
Steve Block791712a2010-08-27 10:21:07 +01005425 // Size in bytes or kVariableSizeSentinel if instances do not have
5426 // a fixed size.
Steve Blocka7e24c12009-10-30 11:49:00 +00005427 inline int instance_size();
5428 inline void set_instance_size(int value);
5429
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005430 // Only to clear an unused byte, remove once byte is used.
5431 inline void clear_unused();
Steve Blocka7e24c12009-10-30 11:49:00 +00005432
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005433 // [inobject_properties_or_constructor_function_index]: Provides access
5434 // to the inobject properties in case of JSObject maps, or the constructor
5435 // function index in case of primitive maps.
5436 inline int inobject_properties_or_constructor_function_index();
5437 inline void set_inobject_properties_or_constructor_function_index(int value);
5438 // Count of properties allocated in the object (JSObject only).
5439 inline int GetInObjectProperties();
5440 inline void SetInObjectProperties(int value);
5441 // Index of the constructor function in the native context (primitives only),
5442 // or the special sentinel value to indicate that there is no object wrapper
5443 // for the primitive (i.e. in case of null or undefined).
5444 static const int kNoConstructorFunctionIndex = 0;
5445 inline int GetConstructorFunctionIndex();
5446 inline void SetConstructorFunctionIndex(int value);
5447 static MaybeHandle<JSFunction> GetConstructorFunction(
5448 Handle<Map> map, Handle<Context> native_context);
Steve Blocka7e24c12009-10-30 11:49:00 +00005449
5450 // Instance type.
5451 inline InstanceType instance_type();
5452 inline void set_instance_type(InstanceType value);
5453
5454 // Tells how many unused property fields are available in the
5455 // instance (only used for JSObject in fast mode).
5456 inline int unused_property_fields();
5457 inline void set_unused_property_fields(int value);
5458
5459 // Bit field.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005460 inline byte bit_field() const;
Steve Blocka7e24c12009-10-30 11:49:00 +00005461 inline void set_bit_field(byte value);
5462
5463 // Bit field 2.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005464 inline byte bit_field2() const;
Steve Blocka7e24c12009-10-30 11:49:00 +00005465 inline void set_bit_field2(byte value);
5466
Ben Murdoch257744e2011-11-30 15:57:28 +00005467 // Bit field 3.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005468 inline uint32_t bit_field3() const;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005469 inline void set_bit_field3(uint32_t bits);
5470
5471 class EnumLengthBits: public BitField<int,
5472 0, kDescriptorIndexBitCount> {}; // NOLINT
5473 class NumberOfOwnDescriptorsBits: public BitField<int,
5474 kDescriptorIndexBitCount, kDescriptorIndexBitCount> {}; // NOLINT
5475 STATIC_ASSERT(kDescriptorIndexBitCount + kDescriptorIndexBitCount == 20);
5476 class DictionaryMap : public BitField<bool, 20, 1> {};
5477 class OwnsDescriptors : public BitField<bool, 21, 1> {};
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005478 class IsHiddenPrototype : public BitField<bool, 22, 1> {};
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005479 class Deprecated : public BitField<bool, 23, 1> {};
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005480 class IsUnstable : public BitField<bool, 24, 1> {};
5481 class IsMigrationTarget : public BitField<bool, 25, 1> {};
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005482 class IsStrong : public BitField<bool, 26, 1> {};
5483 class NewTargetIsBase : public BitField<bool, 27, 1> {};
5484 // Bit 28 is free.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005485
5486 // Keep this bit field at the very end for better code in
5487 // Builtins::kJSConstructStubGeneric stub.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005488 // This counter is used for in-object slack tracking.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005489 // The in-object slack tracking is considered enabled when the counter is
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005490 // non zero.
5491 class ConstructionCounter : public BitField<int, 29, 3> {};
5492 static const int kSlackTrackingCounterStart = 7;
5493 static const int kSlackTrackingCounterEnd = 1;
5494 static const int kNoSlackTracking = 0;
5495 STATIC_ASSERT(kSlackTrackingCounterStart <= ConstructionCounter::kMax);
5496
5497
5498 // Inobject slack tracking is the way to reclaim unused inobject space.
5499 //
5500 // The instance size is initially determined by adding some slack to
5501 // expected_nof_properties (to allow for a few extra properties added
5502 // after the constructor). There is no guarantee that the extra space
5503 // will not be wasted.
5504 //
5505 // Here is the algorithm to reclaim the unused inobject space:
5506 // - Detect the first constructor call for this JSFunction.
5507 // When it happens enter the "in progress" state: initialize construction
5508 // counter in the initial_map.
5509 // - While the tracking is in progress initialize unused properties of a new
5510 // object with one_pointer_filler_map instead of undefined_value (the "used"
5511 // part is initialized with undefined_value as usual). This way they can
5512 // be resized quickly and safely.
5513 // - Once enough objects have been created compute the 'slack'
5514 // (traverse the map transition tree starting from the
5515 // initial_map and find the lowest value of unused_property_fields).
5516 // - Traverse the transition tree again and decrease the instance size
5517 // of every map. Existing objects will resize automatically (they are
5518 // filled with one_pointer_filler_map). All further allocations will
5519 // use the adjusted instance size.
5520 // - SharedFunctionInfo's expected_nof_properties left unmodified since
5521 // allocations made using different closures could actually create different
5522 // kind of objects (see prototype inheritance pattern).
5523 //
5524 // Important: inobject slack tracking is not attempted during the snapshot
5525 // creation.
5526
5527 static const int kGenerousAllocationCount =
5528 kSlackTrackingCounterStart - kSlackTrackingCounterEnd + 1;
5529
5530 // Starts the tracking by initializing object constructions countdown counter.
5531 void StartInobjectSlackTracking();
5532
5533 // True if the object constructions countdown counter is a range
5534 // [kSlackTrackingCounterEnd, kSlackTrackingCounterStart].
5535 inline bool IsInobjectSlackTrackingInProgress();
5536
5537 // Does the tracking step.
5538 inline void InobjectSlackTrackingStep();
5539
5540 // Completes inobject slack tracking for the transition tree starting at this
5541 // initial map.
5542 void CompleteInobjectSlackTracking();
Ben Murdoch257744e2011-11-30 15:57:28 +00005543
Steve Blocka7e24c12009-10-30 11:49:00 +00005544 // Tells whether the object in the prototype property will be used
5545 // for instances created from this function. If the prototype
5546 // property is set to a value that is not a JSObject, the prototype
5547 // property will not be used to create instances of the function.
5548 // See ECMA-262, 13.2.2.
5549 inline void set_non_instance_prototype(bool value);
5550 inline bool has_non_instance_prototype();
5551
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005552 // Tells whether the instance has a [[Construct]] internal method.
5553 // This property is implemented according to ES6, section 7.2.4.
5554 inline void set_is_constructor();
5555 inline bool is_constructor() const;
Steve Block6ded16b2010-05-10 14:33:55 +01005556
Steve Blocka7e24c12009-10-30 11:49:00 +00005557 // Tells whether the instance with this map should be ignored by the
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005558 // Object.getPrototypeOf() function and the __proto__ accessor.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005559 inline void set_is_hidden_prototype();
5560 inline bool is_hidden_prototype() const;
Steve Blocka7e24c12009-10-30 11:49:00 +00005561
5562 // Records and queries whether the instance has a named interceptor.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005563 inline void set_has_named_interceptor();
5564 inline bool has_named_interceptor();
Steve Blocka7e24c12009-10-30 11:49:00 +00005565
5566 // Records and queries whether the instance has an indexed interceptor.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005567 inline void set_has_indexed_interceptor();
5568 inline bool has_indexed_interceptor();
Steve Blocka7e24c12009-10-30 11:49:00 +00005569
5570 // Tells whether the instance is undetectable.
5571 // An undetectable object is a special class of JSObject: 'typeof' operator
5572 // returns undefined, ToBoolean returns false. Otherwise it behaves like
5573 // a normal JS object. It is useful for implementing undetectable
5574 // document.all in Firefox & Safari.
5575 // See https://bugzilla.mozilla.org/show_bug.cgi?id=248549.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005576 inline void set_is_undetectable();
5577 inline bool is_undetectable();
Steve Blocka7e24c12009-10-30 11:49:00 +00005578
Steve Blocka7e24c12009-10-30 11:49:00 +00005579 // Tells whether the instance has a call-as-function handler.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005580 inline void set_is_observed();
5581 inline bool is_observed();
Steve Blocka7e24c12009-10-30 11:49:00 +00005582
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005583 // Tells whether the instance has a [[Call]] internal method.
5584 // This property is implemented according to ES6, section 7.2.3.
5585 inline void set_is_callable();
5586 inline bool is_callable() const;
Steve Blocka7e24c12009-10-30 11:49:00 +00005587
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005588 inline void set_is_strong();
5589 inline bool is_strong();
5590 inline void set_new_target_is_base(bool value);
5591 inline bool new_target_is_base();
Steve Block8defd9f2010-07-08 12:39:36 +01005592 inline void set_is_extensible(bool value);
5593 inline bool is_extensible();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005594 inline void set_is_prototype_map(bool value);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005595 inline bool is_prototype_map() const;
Steve Block8defd9f2010-07-08 12:39:36 +01005596
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005597 inline void set_elements_kind(ElementsKind elements_kind);
5598 inline ElementsKind elements_kind();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005599
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005600 // Tells whether the instance has fast elements that are only Smis.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005601 inline bool has_fast_smi_elements();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005602
Steve Block8defd9f2010-07-08 12:39:36 +01005603 // Tells whether the instance has fast elements.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005604 inline bool has_fast_object_elements();
5605 inline bool has_fast_smi_or_object_elements();
5606 inline bool has_fast_double_elements();
5607 inline bool has_fast_elements();
5608 inline bool has_sloppy_arguments_elements();
5609 inline bool has_fixed_typed_array_elements();
5610 inline bool has_dictionary_elements();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005611
5612 static bool IsValidElementsTransition(ElementsKind from_kind,
5613 ElementsKind to_kind);
5614
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005615 // Returns true if the current map doesn't have DICTIONARY_ELEMENTS but if a
5616 // map with DICTIONARY_ELEMENTS was found in the prototype chain.
5617 bool DictionaryElementsInPrototypeChainOnly();
Kristian Monsen0d5e1162010-09-30 15:31:59 +01005618
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005619 inline Map* ElementsTransitionMap();
Kristian Monsen0d5e1162010-09-30 15:31:59 +01005620
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005621 inline FixedArrayBase* GetInitialElements();
Kristian Monsen0d5e1162010-09-30 15:31:59 +01005622
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005623 // [raw_transitions]: Provides access to the transitions storage field.
5624 // Don't call set_raw_transitions() directly to overwrite transitions, use
5625 // the TransitionArray::ReplaceTransitions() wrapper instead!
5626 DECL_ACCESSORS(raw_transitions, Object)
5627 // [prototype_info]: Per-prototype metadata. Aliased with transitions
5628 // (which prototype maps don't have).
5629 DECL_ACCESSORS(prototype_info, Object)
5630 // PrototypeInfo is created lazily using this helper (which installs it on
5631 // the given prototype's map).
5632 static Handle<PrototypeInfo> GetOrCreatePrototypeInfo(
5633 Handle<JSObject> prototype, Isolate* isolate);
5634 static Handle<PrototypeInfo> GetOrCreatePrototypeInfo(
5635 Handle<Map> prototype_map, Isolate* isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005636
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005637 // [prototype chain validity cell]: Associated with a prototype object,
5638 // stored in that object's map's PrototypeInfo, indicates that prototype
5639 // chains through this object are currently valid. The cell will be
5640 // invalidated and replaced when the prototype chain changes.
5641 static Handle<Cell> GetOrCreatePrototypeChainValidityCell(Handle<Map> map,
5642 Isolate* isolate);
5643 static const int kPrototypeChainValid = 0;
5644 static const int kPrototypeChainInvalid = 1;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005645
5646 Map* FindRootMap();
5647 Map* FindFieldOwner(int descriptor);
5648
5649 inline int GetInObjectPropertyOffset(int index);
5650
5651 int NumberOfFields();
5652
5653 // TODO(ishell): candidate with JSObject::MigrateToMap().
5654 bool InstancesNeedRewriting(Map* target, int target_number_of_fields,
5655 int target_inobject, int target_unused,
5656 int* old_number_of_fields);
5657 // TODO(ishell): moveit!
5658 static Handle<Map> GeneralizeAllFieldRepresentations(Handle<Map> map);
5659 MUST_USE_RESULT static Handle<HeapType> GeneralizeFieldType(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005660 Representation rep1, Handle<HeapType> type1, Representation rep2,
5661 Handle<HeapType> type2, Isolate* isolate);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005662 static void GeneralizeFieldType(Handle<Map> map, int modify_index,
5663 Representation new_representation,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005664 Handle<HeapType> new_field_type);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005665 static Handle<Map> ReconfigureProperty(Handle<Map> map, int modify_index,
5666 PropertyKind new_kind,
5667 PropertyAttributes new_attributes,
5668 Representation new_representation,
5669 Handle<HeapType> new_field_type,
5670 StoreMode store_mode);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005671 static Handle<Map> CopyGeneralizeAllRepresentations(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005672 Handle<Map> map, int modify_index, StoreMode store_mode,
5673 PropertyKind kind, PropertyAttributes attributes, const char* reason);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005674
5675 static Handle<Map> PrepareForDataProperty(Handle<Map> old_map,
5676 int descriptor_number,
5677 Handle<Object> value);
5678
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005679 static Handle<Map> Normalize(Handle<Map> map, PropertyNormalizationMode mode,
5680 const char* reason);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005681
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005682 // Tells whether the map is used for JSObjects in dictionary mode (ie
5683 // normalized objects, ie objects for which HasFastProperties returns false).
5684 // A map can never be used for both dictionary mode and fast mode JSObjects.
5685 // False by default and for HeapObjects that are not JSObjects.
5686 inline void set_dictionary_map(bool value);
5687 inline bool is_dictionary_map();
Kristian Monsen0d5e1162010-09-30 15:31:59 +01005688
Steve Blocka7e24c12009-10-30 11:49:00 +00005689 // Tells whether the instance needs security checks when accessing its
5690 // properties.
5691 inline void set_is_access_check_needed(bool access_check_needed);
5692 inline bool is_access_check_needed();
5693
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005694 // Returns true if map has a non-empty stub code cache.
5695 inline bool has_code_cache();
5696
Steve Blocka7e24c12009-10-30 11:49:00 +00005697 // [prototype]: implicit prototype object.
5698 DECL_ACCESSORS(prototype, Object)
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005699 // TODO(jkummerow): make set_prototype private.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005700 static void SetPrototype(
5701 Handle<Map> map, Handle<Object> prototype,
5702 PrototypeOptimizationMode proto_mode = FAST_PROTOTYPE);
Steve Blocka7e24c12009-10-30 11:49:00 +00005703
5704 // [constructor]: points back to the function responsible for this map.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005705 // The field overlaps with the back pointer. All maps in a transition tree
5706 // have the same constructor, so maps with back pointers can walk the
5707 // back pointer chain until they find the map holding their constructor.
5708 DECL_ACCESSORS(constructor_or_backpointer, Object)
5709 inline Object* GetConstructor() const;
5710 inline void SetConstructor(Object* constructor,
5711 WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
5712 // [back pointer]: points back to the parent map from which a transition
5713 // leads to this map. The field overlaps with the constructor (see above).
5714 inline Object* GetBackPointer();
5715 inline void SetBackPointer(Object* value,
5716 WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
Steve Blocka7e24c12009-10-30 11:49:00 +00005717
5718 // [instance descriptors]: describes the object.
5719 DECL_ACCESSORS(instance_descriptors, DescriptorArray)
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005720
5721 // [layout descriptor]: describes the object layout.
5722 DECL_ACCESSORS(layout_descriptor, LayoutDescriptor)
5723 // |layout descriptor| accessor which can be used from GC.
5724 inline LayoutDescriptor* layout_descriptor_gc_safe();
5725 inline bool HasFastPointerLayout() const;
5726
5727 // |layout descriptor| accessor that is safe to call even when
5728 // FLAG_unbox_double_fields is disabled (in this case Map does not contain
5729 // |layout_descriptor| field at all).
5730 inline LayoutDescriptor* GetLayoutDescriptor();
5731
5732 inline void UpdateDescriptors(DescriptorArray* descriptors,
5733 LayoutDescriptor* layout_descriptor);
5734 inline void InitializeDescriptors(DescriptorArray* descriptors,
5735 LayoutDescriptor* layout_descriptor);
Ben Murdoch257744e2011-11-30 15:57:28 +00005736
Steve Blocka7e24c12009-10-30 11:49:00 +00005737 // [stub cache]: contains stubs compiled for this map.
Steve Block6ded16b2010-05-10 14:33:55 +01005738 DECL_ACCESSORS(code_cache, Object)
Steve Blocka7e24c12009-10-30 11:49:00 +00005739
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005740 // [dependent code]: list of optimized codes that weakly embed this map.
5741 DECL_ACCESSORS(dependent_code, DependentCode)
5742
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005743 // [weak cell cache]: cache that stores a weak cell pointing to this map.
5744 DECL_ACCESSORS(weak_cell_cache, Object)
Kristian Monsen80d68ea2010-09-08 11:05:35 +01005745
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005746 inline PropertyDetails GetLastDescriptorDetails();
5747
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005748 inline int LastAdded();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005749
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005750 inline int NumberOfOwnDescriptors();
5751 inline void SetNumberOfOwnDescriptors(int number);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005752
5753 inline Cell* RetrieveDescriptorsPointer();
5754
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005755 inline int EnumLength();
5756 inline void SetEnumLength(int length);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005757
5758 inline bool owns_descriptors();
5759 inline void set_owns_descriptors(bool owns_descriptors);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005760 inline void mark_unstable();
5761 inline bool is_stable();
5762 inline void set_migration_target(bool value);
5763 inline bool is_migration_target();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005764 inline void set_construction_counter(int value);
5765 inline int construction_counter();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005766 inline void deprecate();
5767 inline bool is_deprecated();
5768 inline bool CanBeDeprecated();
5769 // Returns a non-deprecated version of the input. If the input was not
5770 // deprecated, it is directly returned. Otherwise, the non-deprecated version
5771 // is found by re-transitioning from the root of the transition tree using the
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005772 // descriptor array of the map. Returns MaybeHandle<Map>() if no updated map
5773 // is found.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005774 static MaybeHandle<Map> TryUpdate(Handle<Map> map) WARN_UNUSED_RESULT;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005775
5776 // Returns a non-deprecated version of the input. This method may deprecate
5777 // existing maps along the way if encodings conflict. Not for use while
5778 // gathering type feedback. Use TryUpdate in those cases instead.
5779 static Handle<Map> Update(Handle<Map> map);
5780
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005781 static inline Handle<Map> CopyInitialMap(Handle<Map> map);
5782 static Handle<Map> CopyInitialMap(Handle<Map> map, int instance_size,
5783 int in_object_properties,
5784 int unused_property_fields);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005785 static Handle<Map> CopyDropDescriptors(Handle<Map> map);
5786 static Handle<Map> CopyInsertDescriptor(Handle<Map> map,
5787 Descriptor* descriptor,
5788 TransitionFlag flag);
5789
5790 MUST_USE_RESULT static MaybeHandle<Map> CopyWithField(
5791 Handle<Map> map,
5792 Handle<Name> name,
5793 Handle<HeapType> type,
5794 PropertyAttributes attributes,
5795 Representation representation,
5796 TransitionFlag flag);
5797
5798 MUST_USE_RESULT static MaybeHandle<Map> CopyWithConstant(
5799 Handle<Map> map,
5800 Handle<Name> name,
5801 Handle<Object> constant,
5802 PropertyAttributes attributes,
5803 TransitionFlag flag);
5804
5805 // Returns a new map with all transitions dropped from the given map and
5806 // the ElementsKind set.
5807 static Handle<Map> TransitionElementsTo(Handle<Map> map,
5808 ElementsKind to_kind);
5809
5810 static Handle<Map> AsElementsKind(Handle<Map> map, ElementsKind kind);
5811
5812 static Handle<Map> CopyAsElementsKind(Handle<Map> map,
5813 ElementsKind kind,
5814 TransitionFlag flag);
5815
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005816 static Handle<Map> AsLanguageMode(Handle<Map> initial_map,
5817 LanguageMode language_mode,
5818 FunctionKind kind);
5819
5820
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005821 static Handle<Map> CopyForObserved(Handle<Map> map);
5822
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005823 static Handle<Map> CopyForPreventExtensions(Handle<Map> map,
5824 PropertyAttributes attrs_to_add,
5825 Handle<Symbol> transition_marker,
5826 const char* reason);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005827
5828 static Handle<Map> FixProxy(Handle<Map> map, InstanceType type, int size);
5829
5830
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005831 // Maximal number of fast properties. Used to restrict the number of map
5832 // transitions to avoid an explosion in the number of maps for objects used as
5833 // dictionaries.
5834 inline bool TooManyFastProperties(StoreFromKeyed store_mode);
5835 static Handle<Map> TransitionToDataProperty(Handle<Map> map,
5836 Handle<Name> name,
5837 Handle<Object> value,
5838 PropertyAttributes attributes,
5839 StoreFromKeyed store_mode);
5840 static Handle<Map> TransitionToAccessorProperty(
5841 Handle<Map> map, Handle<Name> name, AccessorComponent component,
5842 Handle<Object> accessor, PropertyAttributes attributes);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005843 static Handle<Map> ReconfigureExistingProperty(Handle<Map> map,
5844 int descriptor,
5845 PropertyKind kind,
5846 PropertyAttributes attributes);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005847
5848 inline void AppendDescriptor(Descriptor* desc);
Steve Blocka7e24c12009-10-30 11:49:00 +00005849
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005850 // Returns a copy of the map, prepared for inserting into the transition
5851 // tree (if the |map| owns descriptors then the new one will share
5852 // descriptors with |map|).
5853 static Handle<Map> CopyForTransition(Handle<Map> map, const char* reason);
5854
Steve Blocka7e24c12009-10-30 11:49:00 +00005855 // Returns a copy of the map, with all transitions dropped from the
5856 // instance descriptors.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005857 static Handle<Map> Copy(Handle<Map> map, const char* reason);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005858 static Handle<Map> Create(Isolate* isolate, int inobject_properties);
Steve Blocka7e24c12009-10-30 11:49:00 +00005859
5860 // Returns the next free property index (only valid for FAST MODE).
5861 int NextFreePropertyIndex();
5862
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005863 // Returns the number of properties described in instance_descriptors
5864 // filtering out properties with the specified attributes.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005865 int NumberOfDescribedProperties(DescriptorFlag which = OWN_DESCRIPTORS,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005866 PropertyFilter filter = ALL_PROPERTIES);
Steve Blocka7e24c12009-10-30 11:49:00 +00005867
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005868 DECLARE_CAST(Map)
Steve Blocka7e24c12009-10-30 11:49:00 +00005869
5870 // Code cache operations.
5871
5872 // Clears the code cache.
Steve Block44f0eee2011-05-26 01:26:41 +01005873 inline void ClearCodeCache(Heap* heap);
Steve Blocka7e24c12009-10-30 11:49:00 +00005874
5875 // Update code cache.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005876 static void UpdateCodeCache(Handle<Map> map,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005877 Handle<Name> name,
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005878 Handle<Code> code);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005879
5880 // Extend the descriptor array of the map with the list of descriptors.
5881 // In case of duplicates, the latest descriptor is used.
5882 static void AppendCallbackDescriptors(Handle<Map> map,
5883 Handle<Object> descriptors);
5884
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005885 static inline int SlackForArraySize(int old_size, int size_limit);
5886
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005887 static void EnsureDescriptorSlack(Handle<Map> map, int slack);
Steve Blocka7e24c12009-10-30 11:49:00 +00005888
5889 // Returns the found code or undefined if absent.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005890 Object* FindInCodeCache(Name* name, Code::Flags flags);
Steve Blocka7e24c12009-10-30 11:49:00 +00005891
5892 // Returns the non-negative index of the code object if it is in the
5893 // cache and -1 otherwise.
Steve Block6ded16b2010-05-10 14:33:55 +01005894 int IndexInCodeCache(Object* name, Code* code);
Steve Blocka7e24c12009-10-30 11:49:00 +00005895
5896 // Removes a code object from the code cache at the given index.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005897 void RemoveFromCodeCache(Name* name, Code* code, int index);
Steve Blocka7e24c12009-10-30 11:49:00 +00005898
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005899 // Computes a hash value for this map, to be used in HashTables and such.
5900 int Hash();
5901
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005902 // Returns the map that this map transitions to if its elements_kind
5903 // is changed to |elements_kind|, or NULL if no such map is cached yet.
5904 // |safe_to_add_transitions| is set to false if adding transitions is not
5905 // allowed.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005906 Map* LookupElementsTransitionMap(ElementsKind elements_kind);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005907
5908 // Returns the transitioned map for this map with the most generic
5909 // elements_kind that's found in |candidates|, or null handle if no match is
5910 // found at all.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005911 static Handle<Map> FindTransitionedMap(Handle<Map> map,
5912 MapHandleList* candidates);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005913
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005914 inline bool CanTransition();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005915
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005916 inline bool IsBooleanMap();
5917 inline bool IsPrimitiveMap();
5918 inline bool IsJSReceiverMap();
5919 inline bool IsJSObjectMap();
5920 inline bool IsJSArrayMap();
5921 inline bool IsJSFunctionMap();
5922 inline bool IsStringMap();
5923 inline bool IsJSProxyMap();
5924 inline bool IsJSGlobalProxyMap();
5925 inline bool IsJSGlobalObjectMap();
5926 inline bool IsJSTypedArrayMap();
5927 inline bool IsJSDataViewMap();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005928
5929 inline bool CanOmitMapChecks();
5930
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005931 static void AddDependentCode(Handle<Map> map,
5932 DependentCode::DependencyGroup group,
5933 Handle<Code> code);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005934
5935 bool IsMapInArrayPrototypeChain();
Ben Murdoch592a9fc2012-03-05 11:04:45 +00005936
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005937 static Handle<WeakCell> WeakCellForMap(Handle<Map> map);
5938
Steve Blocka7e24c12009-10-30 11:49:00 +00005939 // Dispatched behavior.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005940 DECLARE_PRINTER(Map)
5941 DECLARE_VERIFIER(Map)
5942
5943#ifdef VERIFY_HEAP
5944 void DictionaryMapVerify();
5945 void VerifyOmittedMapChecks();
Steve Blocka7e24c12009-10-30 11:49:00 +00005946#endif
5947
Iain Merrick75681382010-08-19 15:07:18 +01005948 inline int visitor_id();
5949 inline void set_visitor_id(int visitor_id);
Ben Murdoch3bec4d22010-07-22 14:51:16 +01005950
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005951 static Handle<Map> TransitionToPrototype(Handle<Map> map,
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005952 Handle<Object> prototype,
5953 PrototypeOptimizationMode mode);
Steve Block053d10c2011-06-13 19:13:29 +01005954
Steve Blocka7e24c12009-10-30 11:49:00 +00005955 static const int kMaxPreAllocatedPropertyFields = 255;
5956
5957 // Layout description.
5958 static const int kInstanceSizesOffset = HeapObject::kHeaderSize;
5959 static const int kInstanceAttributesOffset = kInstanceSizesOffset + kIntSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005960 static const int kBitField3Offset = kInstanceAttributesOffset + kIntSize;
5961 static const int kPrototypeOffset = kBitField3Offset + kPointerSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005962 static const int kConstructorOrBackPointerOffset =
5963 kPrototypeOffset + kPointerSize;
5964 // When there is only one transition, it is stored directly in this field;
5965 // otherwise a transition array is used.
5966 // For prototype maps, this slot is used to store this map's PrototypeInfo
5967 // struct.
5968 static const int kTransitionsOrPrototypeInfoOffset =
5969 kConstructorOrBackPointerOffset + kPointerSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005970 static const int kDescriptorsOffset =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005971 kTransitionsOrPrototypeInfoOffset + kPointerSize;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005972#if V8_DOUBLE_FIELDS_UNBOXING
5973 static const int kLayoutDecriptorOffset = kDescriptorsOffset + kPointerSize;
5974 static const int kCodeCacheOffset = kLayoutDecriptorOffset + kPointerSize;
5975#else
5976 static const int kLayoutDecriptorOffset = 1; // Must not be ever accessed.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005977 static const int kCodeCacheOffset = kDescriptorsOffset + kPointerSize;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005978#endif
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005979 static const int kDependentCodeOffset = kCodeCacheOffset + kPointerSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005980 static const int kWeakCellCacheOffset = kDependentCodeOffset + kPointerSize;
5981 static const int kSize = kWeakCellCacheOffset + kPointerSize;
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01005982
5983 // Layout of pointer fields. Heap iteration code relies on them
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005984 // being continuously allocated.
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01005985 static const int kPointerFieldsBeginOffset = Map::kPrototypeOffset;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005986 static const int kPointerFieldsEndOffset = kSize;
Steve Blocka7e24c12009-10-30 11:49:00 +00005987
5988 // Byte offsets within kInstanceSizesOffset.
5989 static const int kInstanceSizeOffset = kInstanceSizesOffset + 0;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005990 static const int kInObjectPropertiesOrConstructorFunctionIndexByte = 1;
5991 static const int kInObjectPropertiesOrConstructorFunctionIndexOffset =
5992 kInstanceSizesOffset + kInObjectPropertiesOrConstructorFunctionIndexByte;
5993 // Note there is one byte available for use here.
5994 static const int kUnusedByte = 2;
5995 static const int kUnusedOffset = kInstanceSizesOffset + kUnusedByte;
Iain Merrick9ac36c92010-09-13 15:29:50 +01005996 static const int kVisitorIdByte = 3;
5997 static const int kVisitorIdOffset = kInstanceSizesOffset + kVisitorIdByte;
Steve Blocka7e24c12009-10-30 11:49:00 +00005998
5999 // Byte offsets within kInstanceAttributesOffset attributes.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006000#if V8_TARGET_LITTLE_ENDIAN
6001 // Order instance type and bit field together such that they can be loaded
6002 // together as a 16-bit word with instance type in the lower 8 bits regardless
6003 // of endianess. Also provide endian-independent offset to that 16-bit word.
Steve Blocka7e24c12009-10-30 11:49:00 +00006004 static const int kInstanceTypeOffset = kInstanceAttributesOffset + 0;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006005 static const int kBitFieldOffset = kInstanceAttributesOffset + 1;
6006#else
6007 static const int kBitFieldOffset = kInstanceAttributesOffset + 0;
6008 static const int kInstanceTypeOffset = kInstanceAttributesOffset + 1;
6009#endif
6010 static const int kInstanceTypeAndBitFieldOffset =
6011 kInstanceAttributesOffset + 0;
6012 static const int kBitField2Offset = kInstanceAttributesOffset + 2;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006013 static const int kUnusedPropertyFieldsByte = 3;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006014 static const int kUnusedPropertyFieldsOffset = kInstanceAttributesOffset + 3;
Steve Blocka7e24c12009-10-30 11:49:00 +00006015
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006016 STATIC_ASSERT(kInstanceTypeAndBitFieldOffset ==
6017 Internals::kMapInstanceTypeAndBitFieldOffset);
Steve Blocka7e24c12009-10-30 11:49:00 +00006018
6019 // Bit positions for bit field.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006020 static const int kHasNonInstancePrototype = 0;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006021 static const int kIsCallable = 1;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006022 static const int kHasNamedInterceptor = 2;
6023 static const int kHasIndexedInterceptor = 3;
6024 static const int kIsUndetectable = 4;
6025 static const int kIsObserved = 5;
6026 static const int kIsAccessCheckNeeded = 6;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006027 static const int kIsConstructor = 7;
Steve Blocka7e24c12009-10-30 11:49:00 +00006028
6029 // Bit positions for bit field 2
Andrei Popescu31002712010-02-23 13:46:05 +00006030 static const int kIsExtensible = 0;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006031 // Bit 1 is free.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006032 class IsPrototypeMapBits : public BitField<bool, 2, 1> {};
6033 class ElementsKindBits: public BitField<ElementsKind, 3, 5> {};
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00006034
6035 // Derived values from bit field 2
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00006036 static const int8_t kMaximumBitField2FastElementValue = static_cast<int8_t>(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006037 (FAST_ELEMENTS + 1) << Map::ElementsKindBits::kShift) - 1;
6038 static const int8_t kMaximumBitField2FastSmiElementValue =
6039 static_cast<int8_t>((FAST_SMI_ELEMENTS + 1) <<
6040 Map::ElementsKindBits::kShift) - 1;
6041 static const int8_t kMaximumBitField2FastHoleyElementValue =
6042 static_cast<int8_t>((FAST_HOLEY_ELEMENTS + 1) <<
6043 Map::ElementsKindBits::kShift) - 1;
6044 static const int8_t kMaximumBitField2FastHoleySmiElementValue =
6045 static_cast<int8_t>((FAST_HOLEY_SMI_ELEMENTS + 1) <<
6046 Map::ElementsKindBits::kShift) - 1;
Steve Blocka7e24c12009-10-30 11:49:00 +00006047
Iain Merrick75681382010-08-19 15:07:18 +01006048 typedef FixedBodyDescriptor<kPointerFieldsBeginOffset,
6049 kPointerFieldsEndOffset,
6050 kSize> BodyDescriptor;
6051
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006052 // Compares this map to another to see if they describe equivalent objects.
6053 // If |mode| is set to CLEAR_INOBJECT_PROPERTIES, |other| is treated as if
6054 // it had exactly zero inobject properties.
6055 // The "shared" flags of both this map and |other| are ignored.
6056 bool EquivalentToForNormalization(Map* other, PropertyNormalizationMode mode);
6057
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006058 // Returns true if given field is unboxed double.
6059 inline bool IsUnboxedDoubleField(FieldIndex index);
6060
6061#if TRACE_MAPS
6062 static void TraceTransition(const char* what, Map* from, Map* to, Name* name);
6063 static void TraceAllTransitions(Map* map);
6064#endif
6065
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006066 static inline Handle<Map> AddMissingTransitionsForTesting(
6067 Handle<Map> split_map, Handle<DescriptorArray> descriptors,
6068 Handle<LayoutDescriptor> full_layout_descriptor);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006069
Steve Blocka7e24c12009-10-30 11:49:00 +00006070 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006071 static void ConnectTransition(Handle<Map> parent, Handle<Map> child,
6072 Handle<Name> name, SimpleTransitionFlag flag);
6073
6074 bool EquivalentToForTransition(Map* other);
6075 static Handle<Map> RawCopy(Handle<Map> map, int instance_size);
6076 static Handle<Map> ShareDescriptor(Handle<Map> map,
6077 Handle<DescriptorArray> descriptors,
6078 Descriptor* descriptor);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006079 static Handle<Map> AddMissingTransitions(
6080 Handle<Map> map, Handle<DescriptorArray> descriptors,
6081 Handle<LayoutDescriptor> full_layout_descriptor);
6082 static void InstallDescriptors(
6083 Handle<Map> parent_map, Handle<Map> child_map, int new_descriptor,
6084 Handle<DescriptorArray> descriptors,
6085 Handle<LayoutDescriptor> full_layout_descriptor);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006086 static Handle<Map> CopyAddDescriptor(Handle<Map> map,
6087 Descriptor* descriptor,
6088 TransitionFlag flag);
6089 static Handle<Map> CopyReplaceDescriptors(
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006090 Handle<Map> map, Handle<DescriptorArray> descriptors,
6091 Handle<LayoutDescriptor> layout_descriptor, TransitionFlag flag,
6092 MaybeHandle<Name> maybe_name, const char* reason,
6093 SimpleTransitionFlag simple_flag);
6094
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006095 static Handle<Map> CopyReplaceDescriptor(Handle<Map> map,
6096 Handle<DescriptorArray> descriptors,
6097 Descriptor* descriptor,
6098 int index,
6099 TransitionFlag flag);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006100 static MUST_USE_RESULT MaybeHandle<Map> TryReconfigureExistingProperty(
6101 Handle<Map> map, int descriptor, PropertyKind kind,
6102 PropertyAttributes attributes, const char** reason);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006103
6104 static Handle<Map> CopyNormalized(Handle<Map> map,
6105 PropertyNormalizationMode mode);
6106
6107 // Fires when the layout of an object with a leaf map changes.
6108 // This includes adding transitions to the leaf map or changing
6109 // the descriptor array.
6110 inline void NotifyLeafMapLayoutChange();
6111
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006112 void DeprecateTransitionTree();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006113
6114 void ReplaceDescriptors(DescriptorArray* new_descriptors,
6115 LayoutDescriptor* new_layout_descriptor);
6116
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006117
6118 Map* FindLastMatchMap(int verbatim, int length, DescriptorArray* descriptors);
6119
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006120 // Update field type of the given descriptor to new representation and new
6121 // type. The type must be prepared for storing in descriptor array:
6122 // it must be either a simple type or a map wrapped in a weak cell.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006123 void UpdateFieldType(int descriptor_number, Handle<Name> name,
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006124 Representation new_representation,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006125 Handle<Object> new_wrapped_type);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006126
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006127 void PrintReconfiguration(FILE* file, int modify_index, PropertyKind kind,
6128 PropertyAttributes attributes);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006129 void PrintGeneralization(FILE* file,
6130 const char* reason,
6131 int modify_index,
6132 int split,
6133 int descriptors,
6134 bool constant_to_field,
6135 Representation old_representation,
6136 Representation new_representation,
6137 HeapType* old_field_type,
6138 HeapType* new_field_type);
6139
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006140 static const int kFastPropertiesSoftLimit = 12;
6141 static const int kMaxFastProperties = 128;
6142
Steve Blocka7e24c12009-10-30 11:49:00 +00006143 DISALLOW_IMPLICIT_CONSTRUCTORS(Map);
6144};
6145
6146
6147// An abstract superclass, a marker class really, for simple structure classes.
Ben Murdoch257744e2011-11-30 15:57:28 +00006148// It doesn't carry much functionality but allows struct classes to be
Steve Blocka7e24c12009-10-30 11:49:00 +00006149// identified in the type system.
6150class Struct: public HeapObject {
6151 public:
6152 inline void InitializeBody(int object_size);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006153 DECLARE_CAST(Struct)
6154};
6155
6156
6157// A simple one-element struct, useful where smis need to be boxed.
6158class Box : public Struct {
6159 public:
6160 // [value]: the boxed contents.
6161 DECL_ACCESSORS(value, Object)
6162
6163 DECLARE_CAST(Box)
6164
6165 // Dispatched behavior.
6166 DECLARE_PRINTER(Box)
6167 DECLARE_VERIFIER(Box)
6168
6169 static const int kValueOffset = HeapObject::kHeaderSize;
6170 static const int kSize = kValueOffset + kPointerSize;
6171
6172 private:
6173 DISALLOW_IMPLICIT_CONSTRUCTORS(Box);
Steve Blocka7e24c12009-10-30 11:49:00 +00006174};
6175
6176
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006177// Container for metadata stored on each prototype map.
6178class PrototypeInfo : public Struct {
6179 public:
6180 static const int UNREGISTERED = -1;
6181
6182 // [prototype_users]: WeakFixedArray containing maps using this prototype,
6183 // or Smi(0) if uninitialized.
6184 DECL_ACCESSORS(prototype_users, Object)
6185 // [registry_slot]: Slot in prototype's user registry where this user
6186 // is stored. Returns UNREGISTERED if this prototype has not been registered.
6187 inline int registry_slot() const;
6188 inline void set_registry_slot(int slot);
6189 // [validity_cell]: Cell containing the validity bit for prototype chains
6190 // going through this object, or Smi(0) if uninitialized.
6191 // When a prototype object changes its map, then both its own validity cell
6192 // and those of all "downstream" prototypes are invalidated; handlers for a
6193 // given receiver embed the currently valid cell for that receiver's prototype
6194 // during their compilation and check it on execution.
6195 DECL_ACCESSORS(validity_cell, Object)
6196
6197 DECLARE_CAST(PrototypeInfo)
6198
6199 // Dispatched behavior.
6200 DECLARE_PRINTER(PrototypeInfo)
6201 DECLARE_VERIFIER(PrototypeInfo)
6202
6203 static const int kPrototypeUsersOffset = HeapObject::kHeaderSize;
6204 static const int kRegistrySlotOffset = kPrototypeUsersOffset + kPointerSize;
6205 static const int kValidityCellOffset = kRegistrySlotOffset + kPointerSize;
6206 static const int kConstructorNameOffset = kValidityCellOffset + kPointerSize;
6207 static const int kSize = kConstructorNameOffset + kPointerSize;
6208
6209 private:
6210 DISALLOW_IMPLICIT_CONSTRUCTORS(PrototypeInfo);
6211};
6212
6213
6214// Pair used to store both a ScopeInfo and an extension object in the extension
6215// slot of a block context. Needed in the rare case where a declaration block
6216// scope (a "varblock" as used to desugar parameter destructuring) also contains
6217// a sloppy direct eval. (In no other case both are needed at the same time.)
6218class SloppyBlockWithEvalContextExtension : public Struct {
6219 public:
6220 // [scope_info]: Scope info.
6221 DECL_ACCESSORS(scope_info, ScopeInfo)
6222 // [extension]: Extension object.
6223 DECL_ACCESSORS(extension, JSObject)
6224
6225 DECLARE_CAST(SloppyBlockWithEvalContextExtension)
6226
6227 // Dispatched behavior.
6228 DECLARE_PRINTER(SloppyBlockWithEvalContextExtension)
6229 DECLARE_VERIFIER(SloppyBlockWithEvalContextExtension)
6230
6231 static const int kScopeInfoOffset = HeapObject::kHeaderSize;
6232 static const int kExtensionOffset = kScopeInfoOffset + kPointerSize;
6233 static const int kSize = kExtensionOffset + kPointerSize;
6234
6235 private:
6236 DISALLOW_IMPLICIT_CONSTRUCTORS(SloppyBlockWithEvalContextExtension);
6237};
6238
6239
Steve Blocka7e24c12009-10-30 11:49:00 +00006240// Script describes a script which has been added to the VM.
6241class Script: public Struct {
6242 public:
6243 // Script types.
6244 enum Type {
6245 TYPE_NATIVE = 0,
6246 TYPE_EXTENSION = 1,
6247 TYPE_NORMAL = 2
6248 };
6249
6250 // Script compilation types.
6251 enum CompilationType {
6252 COMPILATION_TYPE_HOST = 0,
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08006253 COMPILATION_TYPE_EVAL = 1
Steve Blocka7e24c12009-10-30 11:49:00 +00006254 };
6255
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006256 // Script compilation state.
6257 enum CompilationState {
6258 COMPILATION_STATE_INITIAL = 0,
6259 COMPILATION_STATE_COMPILED = 1
6260 };
6261
Steve Blocka7e24c12009-10-30 11:49:00 +00006262 // [source]: the script source.
6263 DECL_ACCESSORS(source, Object)
6264
6265 // [name]: the script name.
6266 DECL_ACCESSORS(name, Object)
6267
6268 // [id]: the script id.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006269 DECL_INT_ACCESSORS(id)
Steve Blocka7e24c12009-10-30 11:49:00 +00006270
6271 // [line_offset]: script line offset in resource from where it was extracted.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006272 DECL_INT_ACCESSORS(line_offset)
Steve Blocka7e24c12009-10-30 11:49:00 +00006273
6274 // [column_offset]: script column offset in resource from where it was
6275 // extracted.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006276 DECL_INT_ACCESSORS(column_offset)
Steve Blocka7e24c12009-10-30 11:49:00 +00006277
Steve Blocka7e24c12009-10-30 11:49:00 +00006278 // [context_data]: context data for the context this script was compiled in.
6279 DECL_ACCESSORS(context_data, Object)
6280
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006281 // [wrapper]: the wrapper cache. This is either undefined or a WeakCell.
6282 DECL_ACCESSORS(wrapper, HeapObject)
Steve Blocka7e24c12009-10-30 11:49:00 +00006283
6284 // [type]: the script type.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006285 DECL_INT_ACCESSORS(type)
Steve Blocka7e24c12009-10-30 11:49:00 +00006286
Steve Blockd0582a62009-12-15 09:54:21 +00006287 // [line_ends]: FixedArray of line ends positions.
Steve Blocka7e24c12009-10-30 11:49:00 +00006288 DECL_ACCESSORS(line_ends, Object)
6289
Steve Blockd0582a62009-12-15 09:54:21 +00006290 // [eval_from_shared]: for eval scripts the shared funcion info for the
6291 // function from which eval was called.
6292 DECL_ACCESSORS(eval_from_shared, Object)
Steve Blocka7e24c12009-10-30 11:49:00 +00006293
6294 // [eval_from_instructions_offset]: the instruction offset in the code for the
6295 // function from which eval was called where eval was called.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006296 DECL_INT_ACCESSORS(eval_from_instructions_offset)
6297
6298 // [shared_function_infos]: weak fixed array containing all shared
6299 // function infos created from this script.
6300 DECL_ACCESSORS(shared_function_infos, Object)
Steve Blocka7e24c12009-10-30 11:49:00 +00006301
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006302 // [flags]: Holds an exciting bitfield.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006303 DECL_INT_ACCESSORS(flags)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006304
6305 // [source_url]: sourceURL from magic comment
6306 DECL_ACCESSORS(source_url, Object)
6307
6308 // [source_url]: sourceMappingURL magic comment
6309 DECL_ACCESSORS(source_mapping_url, Object)
6310
6311 // [compilation_type]: how the the script was compiled. Encoded in the
6312 // 'flags' field.
6313 inline CompilationType compilation_type();
6314 inline void set_compilation_type(CompilationType type);
6315
6316 // [compilation_state]: determines whether the script has already been
6317 // compiled. Encoded in the 'flags' field.
6318 inline CompilationState compilation_state();
6319 inline void set_compilation_state(CompilationState state);
6320
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006321 // [hide_source]: determines whether the script source can be exposed as
6322 // function source. Encoded in the 'flags' field.
6323 inline bool hide_source();
6324 inline void set_hide_source(bool value);
6325
6326 // [origin_options]: optional attributes set by the embedder via ScriptOrigin,
6327 // and used by the embedder to make decisions about the script. V8 just passes
6328 // this through. Encoded in the 'flags' field.
6329 inline v8::ScriptOriginOptions origin_options();
6330 inline void set_origin_options(ScriptOriginOptions origin_options);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006331
6332 DECLARE_CAST(Script)
Steve Blocka7e24c12009-10-30 11:49:00 +00006333
Steve Block3ce2e202009-11-05 08:53:23 +00006334 // If script source is an external string, check that the underlying
6335 // resource is accessible. Otherwise, always return true.
6336 inline bool HasValidSource();
6337
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006338 // Convert code position into column number.
6339 static int GetColumnNumber(Handle<Script> script, int code_pos);
6340
6341 // Convert code position into (zero-based) line number.
6342 // The non-handlified version does not allocate, but may be much slower.
6343 static int GetLineNumber(Handle<Script> script, int code_pos);
6344 int GetLineNumber(int code_pos);
6345
6346 static Handle<Object> GetNameOrSourceURL(Handle<Script> script);
6347
6348 // Init line_ends array with code positions of line ends inside script source.
6349 static void InitLineEnds(Handle<Script> script);
6350
6351 // Get the JS object wrapping the given script; create it if none exists.
6352 static Handle<JSObject> GetWrapper(Handle<Script> script);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006353
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006354 // Look through the list of existing shared function infos to find one
6355 // that matches the function literal. Return empty handle if not found.
6356 MaybeHandle<SharedFunctionInfo> FindSharedFunctionInfo(FunctionLiteral* fun);
6357
6358 // Iterate over all script objects on the heap.
6359 class Iterator {
6360 public:
6361 explicit Iterator(Isolate* isolate);
6362 Script* Next();
6363
6364 private:
6365 WeakFixedArray::Iterator iterator_;
6366 DISALLOW_COPY_AND_ASSIGN(Iterator);
6367 };
6368
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006369 // Dispatched behavior.
6370 DECLARE_PRINTER(Script)
6371 DECLARE_VERIFIER(Script)
Steve Blocka7e24c12009-10-30 11:49:00 +00006372
6373 static const int kSourceOffset = HeapObject::kHeaderSize;
6374 static const int kNameOffset = kSourceOffset + kPointerSize;
6375 static const int kLineOffsetOffset = kNameOffset + kPointerSize;
6376 static const int kColumnOffsetOffset = kLineOffsetOffset + kPointerSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006377 static const int kContextOffset = kColumnOffsetOffset + kPointerSize;
Steve Blocka7e24c12009-10-30 11:49:00 +00006378 static const int kWrapperOffset = kContextOffset + kPointerSize;
6379 static const int kTypeOffset = kWrapperOffset + kPointerSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006380 static const int kLineEndsOffset = kTypeOffset + kPointerSize;
Steve Blocka7e24c12009-10-30 11:49:00 +00006381 static const int kIdOffset = kLineEndsOffset + kPointerSize;
Steve Blockd0582a62009-12-15 09:54:21 +00006382 static const int kEvalFromSharedOffset = kIdOffset + kPointerSize;
Steve Blocka7e24c12009-10-30 11:49:00 +00006383 static const int kEvalFrominstructionsOffsetOffset =
Steve Blockd0582a62009-12-15 09:54:21 +00006384 kEvalFromSharedOffset + kPointerSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006385 static const int kSharedFunctionInfosOffset =
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006386 kEvalFrominstructionsOffsetOffset + kPointerSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006387 static const int kFlagsOffset = kSharedFunctionInfosOffset + kPointerSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006388 static const int kSourceUrlOffset = kFlagsOffset + kPointerSize;
6389 static const int kSourceMappingUrlOffset = kSourceUrlOffset + kPointerSize;
6390 static const int kSize = kSourceMappingUrlOffset + kPointerSize;
Steve Blocka7e24c12009-10-30 11:49:00 +00006391
6392 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006393 int GetLineNumberWithArray(int code_pos);
6394
6395 // Bit positions in the flags field.
6396 static const int kCompilationTypeBit = 0;
6397 static const int kCompilationStateBit = 1;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006398 static const int kHideSourceBit = 2;
6399 static const int kOriginOptionsShift = 3;
6400 static const int kOriginOptionsSize = 3;
6401 static const int kOriginOptionsMask = ((1 << kOriginOptionsSize) - 1)
6402 << kOriginOptionsShift;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006403
Steve Blocka7e24c12009-10-30 11:49:00 +00006404 DISALLOW_IMPLICIT_CONSTRUCTORS(Script);
6405};
6406
6407
Ben Murdochb0fe1622011-05-05 13:52:32 +01006408// List of builtin functions we want to identify to improve code
6409// generation.
6410//
6411// Each entry has a name of a global object property holding an object
6412// optionally followed by ".prototype", a name of a builtin function
6413// on the object (the one the id is set for), and a label.
6414//
6415// Installation of ids for the selected builtin functions is handled
6416// by the bootstrapper.
Ben Murdochb0fe1622011-05-05 13:52:32 +01006417#define FUNCTIONS_WITH_ID_LIST(V) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006418 V(Array.prototype, indexOf, ArrayIndexOf) \
6419 V(Array.prototype, lastIndexOf, ArrayLastIndexOf) \
Ben Murdochb0fe1622011-05-05 13:52:32 +01006420 V(Array.prototype, push, ArrayPush) \
6421 V(Array.prototype, pop, ArrayPop) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006422 V(Array.prototype, shift, ArrayShift) \
Ben Murdoch42effa52011-08-19 16:40:31 +01006423 V(Function.prototype, apply, FunctionApply) \
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006424 V(Function.prototype, call, FunctionCall) \
Ben Murdochb0fe1622011-05-05 13:52:32 +01006425 V(String.prototype, charCodeAt, StringCharCodeAt) \
6426 V(String.prototype, charAt, StringCharAt) \
6427 V(String, fromCharCode, StringFromCharCode) \
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006428 V(Math, random, MathRandom) \
Ben Murdochb0fe1622011-05-05 13:52:32 +01006429 V(Math, floor, MathFloor) \
6430 V(Math, round, MathRound) \
6431 V(Math, ceil, MathCeil) \
6432 V(Math, abs, MathAbs) \
6433 V(Math, log, MathLog) \
Ben Murdochb0fe1622011-05-05 13:52:32 +01006434 V(Math, exp, MathExp) \
6435 V(Math, sqrt, MathSqrt) \
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006436 V(Math, pow, MathPow) \
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006437 V(Math, max, MathMax) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006438 V(Math, min, MathMin) \
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006439 V(Math, cos, MathCos) \
6440 V(Math, sin, MathSin) \
6441 V(Math, tan, MathTan) \
6442 V(Math, acos, MathAcos) \
6443 V(Math, asin, MathAsin) \
6444 V(Math, atan, MathAtan) \
6445 V(Math, atan2, MathAtan2) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006446 V(Math, imul, MathImul) \
6447 V(Math, clz32, MathClz32) \
6448 V(Math, fround, MathFround)
Ben Murdochb0fe1622011-05-05 13:52:32 +01006449
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006450#define ATOMIC_FUNCTIONS_WITH_ID_LIST(V) \
6451 V(Atomics, load, AtomicsLoad) \
6452 V(Atomics, store, AtomicsStore)
6453
Ben Murdochb0fe1622011-05-05 13:52:32 +01006454enum BuiltinFunctionId {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006455 kArrayCode,
Ben Murdochb0fe1622011-05-05 13:52:32 +01006456#define DECLARE_FUNCTION_ID(ignored1, ignore2, name) \
6457 k##name,
6458 FUNCTIONS_WITH_ID_LIST(DECLARE_FUNCTION_ID)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006459 ATOMIC_FUNCTIONS_WITH_ID_LIST(DECLARE_FUNCTION_ID)
Ben Murdochb0fe1622011-05-05 13:52:32 +01006460#undef DECLARE_FUNCTION_ID
6461 // Fake id for a special case of Math.pow. Note, it continues the
6462 // list of math functions.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006463 kMathPowHalf
Ben Murdochb0fe1622011-05-05 13:52:32 +01006464};
6465
6466
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006467// Result of searching in an optimized code map of a SharedFunctionInfo. Note
6468// that both {code} and {literals} can be NULL to pass search result status.
6469struct CodeAndLiterals {
6470 Code* code; // Cached optimized code.
6471 LiteralsArray* literals; // Cached literals array.
6472};
6473
6474
Steve Blocka7e24c12009-10-30 11:49:00 +00006475// SharedFunctionInfo describes the JSFunction information that can be
6476// shared by multiple instances of the function.
6477class SharedFunctionInfo: public HeapObject {
6478 public:
6479 // [name]: Function name.
6480 DECL_ACCESSORS(name, Object)
6481
6482 // [code]: Function code.
6483 DECL_ACCESSORS(code, Code)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006484 inline void ReplaceCode(Code* code);
6485
6486 // [optimized_code_map]: Map from native context to optimized code
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006487 // and a shared literals array.
6488 DECL_ACCESSORS(optimized_code_map, FixedArray)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006489
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006490 // Returns entry from optimized code map for specified context and OSR entry.
6491 // Note that {code == nullptr, literals == nullptr} indicates no matching
6492 // entry has been found, whereas {code, literals == nullptr} indicates that
6493 // code is context-independent.
6494 CodeAndLiterals SearchOptimizedCodeMap(Context* native_context,
6495 BailoutId osr_ast_id);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006496
6497 // Clear optimized code map.
6498 void ClearOptimizedCodeMap();
6499
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006500 // We have a special root FixedArray with the right shape and values
6501 // to represent the cleared optimized code map. This predicate checks
6502 // if that root is installed.
6503 inline bool OptimizedCodeMapIsCleared() const;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006504
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006505 // Removes a specific optimized code object from the optimized code map.
6506 // In case of non-OSR the code reference is cleared from the cache entry but
6507 // the entry itself is left in the map in order to proceed sharing literals.
6508 void EvictFromOptimizedCodeMap(Code* optimized_code, const char* reason);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006509
6510 // Trims the optimized code map after entries have been removed.
6511 void TrimOptimizedCodeMap(int shrink_by);
6512
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006513 // Add a new entry to the optimized code map for context-independent code.
6514 static void AddSharedCodeToOptimizedCodeMap(Handle<SharedFunctionInfo> shared,
6515 Handle<Code> code);
6516
6517 // Add a new entry to the optimized code map for context-dependent code.
6518 inline static void AddToOptimizedCodeMap(Handle<SharedFunctionInfo> shared,
6519 Handle<Context> native_context,
6520 Handle<Code> code,
6521 Handle<LiteralsArray> literals,
6522 BailoutId osr_ast_id);
6523
6524 // We may already have cached the code, but want to store literals in the
6525 // cache.
6526 inline static void AddLiteralsToOptimizedCodeMap(
6527 Handle<SharedFunctionInfo> shared, Handle<Context> native_context,
6528 Handle<LiteralsArray> literals);
6529
6530 // Set up the link between shared function info and the script. The shared
6531 // function info is added to the list on the script.
6532 static void SetScript(Handle<SharedFunctionInfo> shared,
6533 Handle<Object> script_object);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006534
6535 // Layout description of the optimized code map.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006536 static const int kSharedCodeIndex = 0;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006537 static const int kEntriesStart = 1;
6538 static const int kContextOffset = 0;
6539 static const int kCachedCodeOffset = 1;
6540 static const int kLiteralsOffset = 2;
6541 static const int kOsrAstIdOffset = 3;
6542 static const int kEntryLength = 4;
6543 static const int kInitialLength = kEntriesStart + kEntryLength;
Steve Blocka7e24c12009-10-30 11:49:00 +00006544
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006545 static const int kNotFound = -1;
6546
Ben Murdoch3bec4d22010-07-22 14:51:16 +01006547 // [scope_info]: Scope info.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006548 DECL_ACCESSORS(scope_info, ScopeInfo)
Ben Murdoch3bec4d22010-07-22 14:51:16 +01006549
Steve Blocka7e24c12009-10-30 11:49:00 +00006550 // [construct stub]: Code stub for constructing instances of this function.
6551 DECL_ACCESSORS(construct_stub, Code)
6552
6553 // Returns if this function has been compiled to native code yet.
6554 inline bool is_compiled();
6555
6556 // [length]: The function length - usually the number of declared parameters.
6557 // Use up to 2^30 parameters.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006558 inline int length() const;
Steve Blocka7e24c12009-10-30 11:49:00 +00006559 inline void set_length(int value);
6560
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006561 // [internal formal parameter count]: The declared number of parameters.
6562 // For subclass constructors, also includes new.target.
6563 // The size of function's frame is internal_formal_parameter_count + 1.
6564 inline int internal_formal_parameter_count() const;
6565 inline void set_internal_formal_parameter_count(int value);
Steve Blocka7e24c12009-10-30 11:49:00 +00006566
6567 // Set the formal parameter count so the function code will be
6568 // called without using argument adaptor frames.
6569 inline void DontAdaptArguments();
6570
6571 // [expected_nof_properties]: Expected number of properties for the function.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006572 inline int expected_nof_properties() const;
Steve Blocka7e24c12009-10-30 11:49:00 +00006573 inline void set_expected_nof_properties(int value);
6574
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006575 // [feedback_vector] - accumulates ast node feedback from full-codegen and
6576 // (increasingly) from crankshafted code where sufficient feedback isn't
6577 // available.
6578 DECL_ACCESSORS(feedback_vector, TypeFeedbackVector)
Kristian Monsen0d5e1162010-09-30 15:31:59 +01006579
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006580 // Unconditionally clear the type feedback vector (including vector ICs).
6581 void ClearTypeFeedbackInfo();
6582
6583 // Clear the type feedback vector with a more subtle policy at GC time.
6584 void ClearTypeFeedbackInfoAtGCTime();
6585
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006586#if TRACE_MAPS
6587 // [unique_id] - For --trace-maps purposes, an identifier that's persistent
6588 // even if the GC moves this SharedFunctionInfo.
6589 inline int unique_id() const;
6590 inline void set_unique_id(int value);
6591#endif
6592
Steve Blocka7e24c12009-10-30 11:49:00 +00006593 // [instance class name]: class name for instances.
6594 DECL_ACCESSORS(instance_class_name, Object)
6595
Steve Block6ded16b2010-05-10 14:33:55 +01006596 // [function data]: This field holds some additional data for function.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006597 // Currently it has one of:
6598 // - a FunctionTemplateInfo to make benefit the API [IsApiFunction()].
6599 // - a Smi identifying a builtin function [HasBuiltinFunctionId()].
6600 // - a BytecodeArray for the interpreter [HasBytecodeArray()].
Steve Blocka7e24c12009-10-30 11:49:00 +00006601 // In the long run we don't want all functions to have this field but
6602 // we can fix that when we have a better model for storing hidden data
6603 // on objects.
6604 DECL_ACCESSORS(function_data, Object)
6605
Steve Block6ded16b2010-05-10 14:33:55 +01006606 inline bool IsApiFunction();
6607 inline FunctionTemplateInfo* get_api_func_data();
Ben Murdochb0fe1622011-05-05 13:52:32 +01006608 inline bool HasBuiltinFunctionId();
Ben Murdochb0fe1622011-05-05 13:52:32 +01006609 inline BuiltinFunctionId builtin_function_id();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006610 inline bool HasBytecodeArray();
6611 inline BytecodeArray* bytecode_array();
Steve Block6ded16b2010-05-10 14:33:55 +01006612
Steve Blocka7e24c12009-10-30 11:49:00 +00006613 // [script info]: Script from which the function originates.
6614 DECL_ACCESSORS(script, Object)
6615
Steve Block6ded16b2010-05-10 14:33:55 +01006616 // [num_literals]: Number of literals used by this function.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006617 inline int num_literals() const;
Steve Block6ded16b2010-05-10 14:33:55 +01006618 inline void set_num_literals(int value);
6619
Steve Blocka7e24c12009-10-30 11:49:00 +00006620 // [start_position_and_type]: Field used to store both the source code
6621 // position, whether or not the function is a function expression,
6622 // and whether or not the function is a toplevel function. The two
6623 // least significants bit indicates whether the function is an
6624 // expression and the rest contains the source code position.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006625 inline int start_position_and_type() const;
Steve Blocka7e24c12009-10-30 11:49:00 +00006626 inline void set_start_position_and_type(int value);
6627
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006628 // The function is subject to debugging if a debug info is attached.
6629 inline bool HasDebugInfo();
6630 inline DebugInfo* GetDebugInfo();
6631
6632 // A function has debug code if the compiled code has debug break slots.
6633 inline bool HasDebugCode();
6634
Steve Blocka7e24c12009-10-30 11:49:00 +00006635 // [debug info]: Debug information.
6636 DECL_ACCESSORS(debug_info, Object)
6637
6638 // [inferred name]: Name inferred from variable or property
6639 // assignment of this function. Used to facilitate debugging and
6640 // profiling of JavaScript code written in OO style, where almost
6641 // all functions are anonymous but are assigned to object
6642 // properties.
6643 DECL_ACCESSORS(inferred_name, String)
6644
Ben Murdochf87a2032010-10-22 12:50:53 +01006645 // The function's name if it is non-empty, otherwise the inferred name.
6646 String* DebugName();
6647
Steve Blocka7e24c12009-10-30 11:49:00 +00006648 // Position of the 'function' token in the script source.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006649 inline int function_token_position() const;
Steve Blocka7e24c12009-10-30 11:49:00 +00006650 inline void set_function_token_position(int function_token_position);
6651
6652 // Position of this function in the script source.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006653 inline int start_position() const;
Steve Blocka7e24c12009-10-30 11:49:00 +00006654 inline void set_start_position(int start_position);
6655
6656 // End position of this function in the script source.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006657 inline int end_position() const;
Steve Blocka7e24c12009-10-30 11:49:00 +00006658 inline void set_end_position(int end_position);
6659
6660 // Is this function a function expression in the source code.
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00006661 DECL_BOOLEAN_ACCESSORS(is_expression)
Steve Blocka7e24c12009-10-30 11:49:00 +00006662
6663 // Is this function a top-level function (scripts, evals).
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00006664 DECL_BOOLEAN_ACCESSORS(is_toplevel)
Steve Blocka7e24c12009-10-30 11:49:00 +00006665
6666 // Bit field containing various information collected by the compiler to
6667 // drive optimization.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006668 inline int compiler_hints() const;
Steve Blocka7e24c12009-10-30 11:49:00 +00006669 inline void set_compiler_hints(int value);
6670
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006671 inline int ast_node_count() const;
Ben Murdoch8f9999f2012-04-23 10:39:17 +01006672 inline void set_ast_node_count(int count);
6673
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006674 inline int profiler_ticks() const;
6675 inline void set_profiler_ticks(int ticks);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006676
Ben Murdoch8f9999f2012-04-23 10:39:17 +01006677 // Inline cache age is used to infer whether the function survived a context
6678 // disposal or not. In the former case we reset the opt_count.
6679 inline int ic_age();
6680 inline void set_ic_age(int age);
Ben Murdochb0fe1622011-05-05 13:52:32 +01006681
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01006682 // Indicates if this function can be lazy compiled.
6683 // This is used to determine if we can safely flush code from a function
6684 // when doing GC if we expect that the function will no longer be used.
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00006685 DECL_BOOLEAN_ACCESSORS(allows_lazy_compilation)
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01006686
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006687 // Indicates if this function can be lazy compiled without a context.
6688 // This is used to determine if we can force compilation without reaching
6689 // the function through program execution but through other means (e.g. heap
6690 // iteration by the debugger).
6691 DECL_BOOLEAN_ACCESSORS(allows_lazy_compilation_without_context)
Iain Merrick75681382010-08-19 15:07:18 +01006692
Ben Murdochb0fe1622011-05-05 13:52:32 +01006693 // Indicates whether optimizations have been disabled for this
6694 // shared function info. If a function is repeatedly optimized or if
6695 // we cannot optimize the function we disable optimization to avoid
6696 // spending time attempting to optimize it again.
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00006697 DECL_BOOLEAN_ACCESSORS(optimization_disabled)
Ben Murdochb0fe1622011-05-05 13:52:32 +01006698
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006699 // Indicates the language mode.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006700 inline LanguageMode language_mode();
6701 inline void set_language_mode(LanguageMode language_mode);
Steve Block1e0659c2011-05-24 12:43:12 +01006702
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00006703 // False if the function definitely does not allocate an arguments object.
6704 DECL_BOOLEAN_ACCESSORS(uses_arguments)
6705
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006706 // Indicates that this function uses a super property (or an eval that may
6707 // use a super property).
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006708 // This is needed to set up the [[HomeObject]] on the function instance.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006709 DECL_BOOLEAN_ACCESSORS(needs_home_object)
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006710
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00006711 // True if the function has any duplicated parameter names.
6712 DECL_BOOLEAN_ACCESSORS(has_duplicate_parameters)
6713
6714 // Indicates whether the function is a native function.
Ben Murdoch589d6972011-11-30 16:04:58 +00006715 // These needs special treatment in .call and .apply since
Ben Murdoch257744e2011-11-30 15:57:28 +00006716 // null passed as the receiver should not be translated to the
6717 // global object.
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00006718 DECL_BOOLEAN_ACCESSORS(native)
6719
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006720 // Indicate that this function should always be inlined in optimized code.
6721 DECL_BOOLEAN_ACCESSORS(force_inline)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006722
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00006723 // Indicates that the function was created by the Function function.
6724 // Though it's anonymous, toString should treat it as if it had the name
6725 // "anonymous". We don't set the name itself so that the system does not
6726 // see a binding for it.
6727 DECL_BOOLEAN_ACCESSORS(name_should_print_as_anonymous)
6728
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00006729 // Indicates that the function is anonymous (the name field can be set
6730 // through the API, which does not change this flag).
6731 DECL_BOOLEAN_ACCESSORS(is_anonymous)
Ben Murdoch257744e2011-11-30 15:57:28 +00006732
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006733 // Is this a function or top-level/eval code.
6734 DECL_BOOLEAN_ACCESSORS(is_function)
6735
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006736 // Indicates that code for this function cannot be compiled with Crankshaft.
6737 DECL_BOOLEAN_ACCESSORS(dont_crankshaft)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006738
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006739 // Indicates that code for this function cannot be flushed.
6740 DECL_BOOLEAN_ACCESSORS(dont_flush)
6741
6742 // Indicates that this function is a generator.
6743 DECL_BOOLEAN_ACCESSORS(is_generator)
6744
6745 // Indicates that this function is an arrow function.
6746 DECL_BOOLEAN_ACCESSORS(is_arrow)
6747
6748 // Indicates that this function is a concise method.
6749 DECL_BOOLEAN_ACCESSORS(is_concise_method)
6750
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006751 // Indicates that this function is an accessor (getter or setter).
6752 DECL_BOOLEAN_ACCESSORS(is_accessor_function)
6753
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006754 // Indicates that this function is a default constructor.
6755 DECL_BOOLEAN_ACCESSORS(is_default_constructor)
6756
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006757 // Indicates that this function is an asm function.
6758 DECL_BOOLEAN_ACCESSORS(asm_function)
6759
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006760 // Indicates that the the shared function info is deserialized from cache.
6761 DECL_BOOLEAN_ACCESSORS(deserialized)
6762
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006763 // Indicates that the the shared function info has never been compiled before.
6764 DECL_BOOLEAN_ACCESSORS(never_compiled)
6765
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006766 inline FunctionKind kind();
6767 inline void set_kind(FunctionKind kind);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006768
Ben Murdochb0fe1622011-05-05 13:52:32 +01006769 // Indicates whether or not the code in the shared function support
6770 // deoptimization.
6771 inline bool has_deoptimization_support();
6772
6773 // Enable deoptimization support through recompiled code.
6774 void EnableDeoptimizationSupport(Code* recompiled);
6775
Ben Murdoch257744e2011-11-30 15:57:28 +00006776 // Disable (further) attempted optimization of all functions sharing this
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006777 // shared function info.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006778 void DisableOptimization(BailoutReason reason);
Ben Murdoch257744e2011-11-30 15:57:28 +00006779
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006780 inline BailoutReason disable_optimization_reason();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006781
6782 // Lookup the bailout ID and DCHECK that it exists in the non-optimized
Ben Murdochb0fe1622011-05-05 13:52:32 +01006783 // code, returns whether it asserted (i.e., always true if assertions are
6784 // disabled).
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006785 bool VerifyBailoutId(BailoutId id);
Steve Blocka7e24c12009-10-30 11:49:00 +00006786
6787 // [source code]: Source code for the function.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006788 bool HasSourceCode() const;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006789 Handle<Object> GetSourceCode();
Steve Blocka7e24c12009-10-30 11:49:00 +00006790
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006791 // Number of times the function was optimized.
Ben Murdochb0fe1622011-05-05 13:52:32 +01006792 inline int opt_count();
6793 inline void set_opt_count(int opt_count);
6794
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006795 // Number of times the function was deoptimized.
6796 inline void set_deopt_count(int value);
6797 inline int deopt_count();
6798 inline void increment_deopt_count();
6799
6800 // Number of time we tried to re-enable optimization after it
6801 // was disabled due to high number of deoptimizations.
6802 inline void set_opt_reenable_tries(int value);
6803 inline int opt_reenable_tries();
6804
6805 inline void TryReenableOptimization();
6806
6807 // Stores deopt_count, opt_reenable_tries and ic_age as bit-fields.
6808 inline void set_counters(int value);
6809 inline int counters() const;
6810
6811 // Stores opt_count and bailout_reason as bit-fields.
6812 inline void set_opt_count_and_bailout_reason(int value);
6813 inline int opt_count_and_bailout_reason() const;
6814
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006815 inline void set_disable_optimization_reason(BailoutReason reason);
6816
6817 // Tells whether this function should be subject to debugging.
6818 inline bool IsSubjectToDebugging();
6819
6820 // Whether this function is defined in native code or extensions.
6821 inline bool IsBuiltin();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006822
6823 // Check whether or not this function is inlineable.
6824 bool IsInlineable();
6825
Ben Murdochb0fe1622011-05-05 13:52:32 +01006826 // Source size of this function.
6827 int SourceSize();
6828
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006829 // Returns `false` if formal parameters include rest parameters, optional
6830 // parameters, or destructuring parameters.
6831 // TODO(caitp): make this a flag set during parsing
6832 inline bool has_simple_parameters();
Steve Blocka7e24c12009-10-30 11:49:00 +00006833
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006834 // Initialize a SharedFunctionInfo from a parsed function literal.
6835 static void InitFromFunctionLiteral(Handle<SharedFunctionInfo> shared_info,
6836 FunctionLiteral* lit);
Steve Blocka7e24c12009-10-30 11:49:00 +00006837
6838 // Dispatched behavior.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006839 DECLARE_PRINTER(SharedFunctionInfo)
6840 DECLARE_VERIFIER(SharedFunctionInfo)
Steve Blocka7e24c12009-10-30 11:49:00 +00006841
Ben Murdoch8f9999f2012-04-23 10:39:17 +01006842 void ResetForNewContext(int new_ic_age);
6843
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006844 // Iterate over all shared function infos.
6845 class Iterator {
6846 public:
6847 explicit Iterator(Isolate* isolate);
6848 SharedFunctionInfo* Next();
6849
6850 private:
6851 bool NextScript();
6852
6853 Script::Iterator script_iterator_;
6854 WeakFixedArray::Iterator sfi_iterator_;
6855 DisallowHeapAllocation no_gc_;
6856 DISALLOW_COPY_AND_ASSIGN(Iterator);
6857 };
6858
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006859 DECLARE_CAST(SharedFunctionInfo)
Steve Blocka7e24c12009-10-30 11:49:00 +00006860
6861 // Constants.
6862 static const int kDontAdaptArgumentsSentinel = -1;
6863
6864 // Layout description.
Steve Block6ded16b2010-05-10 14:33:55 +01006865 // Pointer fields.
Steve Blocka7e24c12009-10-30 11:49:00 +00006866 static const int kNameOffset = HeapObject::kHeaderSize;
6867 static const int kCodeOffset = kNameOffset + kPointerSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006868 static const int kOptimizedCodeMapOffset = kCodeOffset + kPointerSize;
6869 static const int kScopeInfoOffset = kOptimizedCodeMapOffset + kPointerSize;
Ben Murdoch3bec4d22010-07-22 14:51:16 +01006870 static const int kConstructStubOffset = kScopeInfoOffset + kPointerSize;
Steve Block6ded16b2010-05-10 14:33:55 +01006871 static const int kInstanceClassNameOffset =
6872 kConstructStubOffset + kPointerSize;
6873 static const int kFunctionDataOffset =
6874 kInstanceClassNameOffset + kPointerSize;
6875 static const int kScriptOffset = kFunctionDataOffset + kPointerSize;
6876 static const int kDebugInfoOffset = kScriptOffset + kPointerSize;
6877 static const int kInferredNameOffset = kDebugInfoOffset + kPointerSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006878 static const int kFeedbackVectorOffset =
Steve Block6ded16b2010-05-10 14:33:55 +01006879 kInferredNameOffset + kPointerSize;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006880#if TRACE_MAPS
6881 static const int kUniqueIdOffset = kFeedbackVectorOffset + kPointerSize;
6882 static const int kLastPointerFieldOffset = kUniqueIdOffset;
6883#else
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006884 // Just to not break the postmortrem support with conditional offsets
6885 static const int kUniqueIdOffset = kFeedbackVectorOffset;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006886 static const int kLastPointerFieldOffset = kFeedbackVectorOffset;
6887#endif
6888
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01006889#if V8_HOST_ARCH_32_BIT
6890 // Smi fields.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006891 static const int kLengthOffset = kLastPointerFieldOffset + kPointerSize;
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01006892 static const int kFormalParameterCountOffset = kLengthOffset + kPointerSize;
6893 static const int kExpectedNofPropertiesOffset =
6894 kFormalParameterCountOffset + kPointerSize;
6895 static const int kNumLiteralsOffset =
6896 kExpectedNofPropertiesOffset + kPointerSize;
6897 static const int kStartPositionAndTypeOffset =
6898 kNumLiteralsOffset + kPointerSize;
6899 static const int kEndPositionOffset =
6900 kStartPositionAndTypeOffset + kPointerSize;
6901 static const int kFunctionTokenPositionOffset =
6902 kEndPositionOffset + kPointerSize;
6903 static const int kCompilerHintsOffset =
6904 kFunctionTokenPositionOffset + kPointerSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006905 static const int kOptCountAndBailoutReasonOffset =
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01006906 kCompilerHintsOffset + kPointerSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006907 static const int kCountersOffset =
6908 kOptCountAndBailoutReasonOffset + kPointerSize;
6909 static const int kAstNodeCountOffset =
6910 kCountersOffset + kPointerSize;
6911 static const int kProfilerTicksOffset =
6912 kAstNodeCountOffset + kPointerSize;
Ben Murdoch8f9999f2012-04-23 10:39:17 +01006913
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01006914 // Total size.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006915 static const int kSize = kProfilerTicksOffset + kPointerSize;
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01006916#else
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006917// The only reason to use smi fields instead of int fields is to allow
6918// iteration without maps decoding during garbage collections.
6919// To avoid wasting space on 64-bit architectures we use the following trick:
6920// we group integer fields into pairs
6921// The least significant integer in each pair is shifted left by 1. By doing
6922// this we guarantee that LSB of each kPointerSize aligned word is not set and
6923// thus this word cannot be treated as pointer to HeapObject during old space
6924// traversal.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006925#if V8_TARGET_LITTLE_ENDIAN
6926 static const int kLengthOffset = kLastPointerFieldOffset + kPointerSize;
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01006927 static const int kFormalParameterCountOffset =
6928 kLengthOffset + kIntSize;
6929
Steve Blocka7e24c12009-10-30 11:49:00 +00006930 static const int kExpectedNofPropertiesOffset =
6931 kFormalParameterCountOffset + kIntSize;
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01006932 static const int kNumLiteralsOffset =
6933 kExpectedNofPropertiesOffset + kIntSize;
6934
6935 static const int kEndPositionOffset =
Steve Block6ded16b2010-05-10 14:33:55 +01006936 kNumLiteralsOffset + kIntSize;
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01006937 static const int kStartPositionAndTypeOffset =
6938 kEndPositionOffset + kIntSize;
6939
6940 static const int kFunctionTokenPositionOffset =
6941 kStartPositionAndTypeOffset + kIntSize;
Steve Block6ded16b2010-05-10 14:33:55 +01006942 static const int kCompilerHintsOffset =
Steve Blocka7e24c12009-10-30 11:49:00 +00006943 kFunctionTokenPositionOffset + kIntSize;
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01006944
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006945 static const int kOptCountAndBailoutReasonOffset =
Steve Block6ded16b2010-05-10 14:33:55 +01006946 kCompilerHintsOffset + kIntSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006947 static const int kCountersOffset =
6948 kOptCountAndBailoutReasonOffset + kIntSize;
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01006949
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006950 static const int kAstNodeCountOffset =
6951 kCountersOffset + kIntSize;
6952 static const int kProfilerTicksOffset =
6953 kAstNodeCountOffset + kIntSize;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006954
Steve Block6ded16b2010-05-10 14:33:55 +01006955 // Total size.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006956 static const int kSize = kProfilerTicksOffset + kIntSize;
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01006957
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006958#elif V8_TARGET_BIG_ENDIAN
6959 static const int kFormalParameterCountOffset =
6960 kLastPointerFieldOffset + kPointerSize;
6961 static const int kLengthOffset = kFormalParameterCountOffset + kIntSize;
6962
6963 static const int kNumLiteralsOffset = kLengthOffset + kIntSize;
6964 static const int kExpectedNofPropertiesOffset = kNumLiteralsOffset + kIntSize;
6965
6966 static const int kStartPositionAndTypeOffset =
6967 kExpectedNofPropertiesOffset + kIntSize;
6968 static const int kEndPositionOffset = kStartPositionAndTypeOffset + kIntSize;
6969
6970 static const int kCompilerHintsOffset = kEndPositionOffset + kIntSize;
6971 static const int kFunctionTokenPositionOffset =
6972 kCompilerHintsOffset + kIntSize;
6973
6974 static const int kCountersOffset = kFunctionTokenPositionOffset + kIntSize;
6975 static const int kOptCountAndBailoutReasonOffset = kCountersOffset + kIntSize;
6976
6977 static const int kProfilerTicksOffset =
6978 kOptCountAndBailoutReasonOffset + kIntSize;
6979 static const int kAstNodeCountOffset = kProfilerTicksOffset + kIntSize;
6980
6981 // Total size.
6982 static const int kSize = kAstNodeCountOffset + kIntSize;
6983
6984#else
6985#error Unknown byte ordering
6986#endif // Big endian
6987#endif // 64-bit
6988
Kristian Monsen0d5e1162010-09-30 15:31:59 +01006989
Steve Block6ded16b2010-05-10 14:33:55 +01006990 static const int kAlignedSize = POINTER_SIZE_ALIGN(kSize);
Steve Blocka7e24c12009-10-30 11:49:00 +00006991
Iain Merrick75681382010-08-19 15:07:18 +01006992 typedef FixedBodyDescriptor<kNameOffset,
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006993 kLastPointerFieldOffset + kPointerSize,
Iain Merrick75681382010-08-19 15:07:18 +01006994 kSize> BodyDescriptor;
6995
Steve Blocka7e24c12009-10-30 11:49:00 +00006996 // Bit positions in start_position_and_type.
6997 // The source code start position is in the 30 most significant bits of
6998 // the start_position_and_type field.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006999 static const int kIsExpressionBit = 0;
7000 static const int kIsTopLevelBit = 1;
Steve Blocka7e24c12009-10-30 11:49:00 +00007001 static const int kStartPositionShift = 2;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007002 static const int kStartPositionMask = ~((1 << kStartPositionShift) - 1);
Steve Blocka7e24c12009-10-30 11:49:00 +00007003
7004 // Bit positions in compiler_hints.
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00007005 enum CompilerHints {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007006 // byte 0
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00007007 kAllowLazyCompilation,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007008 kAllowLazyCompilationWithoutContext,
7009 kOptimizationDisabled,
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00007010 kNative,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007011 kStrictModeFunction,
7012 kStrongModeFunction,
7013 kUsesArguments,
7014 kNeedsHomeObject,
7015 // byte 1
7016 kHasDuplicateParameters,
7017 kForceInline,
7018 kIsAsmFunction,
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00007019 kIsAnonymous,
7020 kNameShouldPrintAsAnonymous,
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007021 kIsFunction,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007022 kDontCrankshaft,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007023 kDontFlush,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007024 // byte 2
7025 kFunctionKind,
7026 kIsArrow = kFunctionKind,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007027 kIsGenerator,
7028 kIsConciseMethod,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007029 kIsAccessorFunction,
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007030 kIsDefaultConstructor,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007031 kIsSubclassConstructor,
7032 kIsBaseConstructor,
7033 kIsInObjectLiteral,
7034 // byte 3
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007035 kDeserialized,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007036 kNeverCompiled,
7037 kCompilerHintsCount, // Pseudo entry
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00007038 };
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007039 // Add hints for other modes when they're added.
7040 STATIC_ASSERT(LANGUAGE_END == 3);
7041 // kFunctionKind has to be byte-aligned
7042 STATIC_ASSERT((kFunctionKind % kBitsPerByte) == 0);
7043// Make sure that FunctionKind and byte 2 are in sync:
7044#define ASSERT_FUNCTION_KIND_ORDER(functionKind, compilerFunctionKind) \
7045 STATIC_ASSERT(FunctionKind::functionKind == \
7046 1 << (compilerFunctionKind - kFunctionKind))
7047 ASSERT_FUNCTION_KIND_ORDER(kArrowFunction, kIsArrow);
7048 ASSERT_FUNCTION_KIND_ORDER(kGeneratorFunction, kIsGenerator);
7049 ASSERT_FUNCTION_KIND_ORDER(kConciseMethod, kIsConciseMethod);
7050 ASSERT_FUNCTION_KIND_ORDER(kAccessorFunction, kIsAccessorFunction);
7051 ASSERT_FUNCTION_KIND_ORDER(kDefaultConstructor, kIsDefaultConstructor);
7052 ASSERT_FUNCTION_KIND_ORDER(kSubclassConstructor, kIsSubclassConstructor);
7053 ASSERT_FUNCTION_KIND_ORDER(kBaseConstructor, kIsBaseConstructor);
7054 ASSERT_FUNCTION_KIND_ORDER(kInObjectLiteral, kIsInObjectLiteral);
7055#undef ASSERT_FUNCTION_KIND_ORDER
Steve Blocka7e24c12009-10-30 11:49:00 +00007056
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007057 class FunctionKindBits : public BitField<FunctionKind, kIsArrow, 8> {};
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007058
7059 class DeoptCountBits : public BitField<int, 0, 4> {};
7060 class OptReenableTriesBits : public BitField<int, 4, 18> {};
7061 class ICAgeBits : public BitField<int, 22, 8> {};
7062
7063 class OptCountBits : public BitField<int, 0, 22> {};
7064 class DisabledOptimizationReasonBits : public BitField<int, 22, 8> {};
7065
Ben Murdoche0cee9b2011-05-25 10:26:03 +01007066 private:
7067#if V8_HOST_ARCH_32_BIT
7068 // On 32 bit platforms, compiler hints is a smi.
7069 static const int kCompilerHintsSmiTagSize = kSmiTagSize;
7070 static const int kCompilerHintsSize = kPointerSize;
7071#else
7072 // On 64 bit platforms, compiler hints is not a smi, see comment above.
7073 static const int kCompilerHintsSmiTagSize = 0;
7074 static const int kCompilerHintsSize = kIntSize;
7075#endif
7076
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00007077 STATIC_ASSERT(SharedFunctionInfo::kCompilerHintsCount <=
7078 SharedFunctionInfo::kCompilerHintsSize * kBitsPerByte);
7079
Ben Murdoche0cee9b2011-05-25 10:26:03 +01007080 public:
Ben Murdoch257744e2011-11-30 15:57:28 +00007081 // Constants for optimizing codegen for strict mode function and
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007082 // native tests when using integer-width instructions.
7083 static const int kStrictModeBit =
7084 kStrictModeFunction + kCompilerHintsSmiTagSize;
7085 static const int kStrongModeBit =
7086 kStrongModeFunction + kCompilerHintsSmiTagSize;
7087 static const int kNativeBit = kNative + kCompilerHintsSmiTagSize;
7088
7089 static const int kClassConstructorBits =
7090 FunctionKind::kClassConstructor
7091 << (kFunctionKind + kCompilerHintsSmiTagSize);
7092
7093 // Constants for optimizing codegen for strict mode function and
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00007094 // native tests.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007095 // Allows to use byte-width instructions.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007096 static const int kStrictModeBitWithinByte = kStrictModeBit % kBitsPerByte;
7097 static const int kStrongModeBitWithinByte = kStrongModeBit % kBitsPerByte;
7098 static const int kNativeBitWithinByte = kNativeBit % kBitsPerByte;
Ben Murdoche0cee9b2011-05-25 10:26:03 +01007099
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007100 static const int kClassConstructorBitsWithinByte =
7101 FunctionKind::kClassConstructor << kCompilerHintsSmiTagSize;
7102 STATIC_ASSERT(kClassConstructorBitsWithinByte < (1 << kBitsPerByte));
Ben Murdoch257744e2011-11-30 15:57:28 +00007103
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007104#if defined(V8_TARGET_LITTLE_ENDIAN)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007105#define BYTE_OFFSET(compiler_hint) \
7106 kCompilerHintsOffset + \
7107 (compiler_hint + kCompilerHintsSmiTagSize) / kBitsPerByte
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007108#elif defined(V8_TARGET_BIG_ENDIAN)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007109#define BYTE_OFFSET(compiler_hint) \
7110 kCompilerHintsOffset + (kCompilerHintsSize - 1) - \
7111 ((compiler_hint + kCompilerHintsSmiTagSize) / kBitsPerByte)
Ben Murdoche0cee9b2011-05-25 10:26:03 +01007112#else
7113#error Unknown byte ordering
7114#endif
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007115 static const int kStrictModeByteOffset = BYTE_OFFSET(kStrictModeFunction);
7116 static const int kStrongModeByteOffset = BYTE_OFFSET(kStrongModeFunction);
7117 static const int kNativeByteOffset = BYTE_OFFSET(kNative);
7118 static const int kFunctionKindByteOffset = BYTE_OFFSET(kFunctionKind);
7119#undef BYTE_OFFSET
Ben Murdoche0cee9b2011-05-25 10:26:03 +01007120
7121 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007122 // Returns entry from optimized code map for specified context and OSR entry.
7123 // The result is either kNotFound, kSharedCodeIndex for context-independent
7124 // entry or a start index of the context-dependent entry.
7125 int SearchOptimizedCodeMapEntry(Context* native_context,
7126 BailoutId osr_ast_id);
7127
7128 // If code is undefined, then existing code won't be overwritten.
7129 static void AddToOptimizedCodeMapInternal(Handle<SharedFunctionInfo> shared,
7130 Handle<Context> native_context,
7131 Handle<HeapObject> code,
7132 Handle<LiteralsArray> literals,
7133 BailoutId osr_ast_id);
7134
Steve Blocka7e24c12009-10-30 11:49:00 +00007135 DISALLOW_IMPLICIT_CONSTRUCTORS(SharedFunctionInfo);
7136};
7137
7138
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007139// Printing support.
7140struct SourceCodeOf {
7141 explicit SourceCodeOf(SharedFunctionInfo* v, int max = -1)
7142 : value(v), max_length(max) {}
7143 const SharedFunctionInfo* value;
7144 int max_length;
7145};
7146
7147
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007148std::ostream& operator<<(std::ostream& os, const SourceCodeOf& v);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007149
7150
7151class JSGeneratorObject: public JSObject {
7152 public:
7153 // [function]: The function corresponding to this generator object.
7154 DECL_ACCESSORS(function, JSFunction)
7155
7156 // [context]: The context of the suspended computation.
7157 DECL_ACCESSORS(context, Context)
7158
7159 // [receiver]: The receiver of the suspended computation.
7160 DECL_ACCESSORS(receiver, Object)
7161
7162 // [continuation]: Offset into code of continuation.
7163 //
7164 // A positive offset indicates a suspended generator. The special
7165 // kGeneratorExecuting and kGeneratorClosed values indicate that a generator
7166 // cannot be resumed.
7167 inline int continuation() const;
7168 inline void set_continuation(int continuation);
7169 inline bool is_closed();
7170 inline bool is_executing();
7171 inline bool is_suspended();
7172
7173 // [operand_stack]: Saved operand stack.
7174 DECL_ACCESSORS(operand_stack, FixedArray)
7175
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007176 DECLARE_CAST(JSGeneratorObject)
7177
7178 // Dispatched behavior.
7179 DECLARE_PRINTER(JSGeneratorObject)
7180 DECLARE_VERIFIER(JSGeneratorObject)
7181
7182 // Magic sentinel values for the continuation.
7183 static const int kGeneratorExecuting = -1;
7184 static const int kGeneratorClosed = 0;
7185
7186 // Layout description.
7187 static const int kFunctionOffset = JSObject::kHeaderSize;
7188 static const int kContextOffset = kFunctionOffset + kPointerSize;
7189 static const int kReceiverOffset = kContextOffset + kPointerSize;
7190 static const int kContinuationOffset = kReceiverOffset + kPointerSize;
7191 static const int kOperandStackOffset = kContinuationOffset + kPointerSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007192 static const int kSize = kOperandStackOffset + kPointerSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007193
7194 // Resume mode, for use by runtime functions.
7195 enum ResumeMode { NEXT, THROW };
7196
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007197 private:
7198 DISALLOW_IMPLICIT_CONSTRUCTORS(JSGeneratorObject);
7199};
7200
7201
7202// Representation for module instance objects.
7203class JSModule: public JSObject {
7204 public:
7205 // [context]: the context holding the module's locals, or undefined if none.
7206 DECL_ACCESSORS(context, Object)
7207
7208 // [scope_info]: Scope info.
7209 DECL_ACCESSORS(scope_info, ScopeInfo)
7210
7211 DECLARE_CAST(JSModule)
7212
7213 // Dispatched behavior.
7214 DECLARE_PRINTER(JSModule)
7215 DECLARE_VERIFIER(JSModule)
7216
7217 // Layout description.
7218 static const int kContextOffset = JSObject::kHeaderSize;
7219 static const int kScopeInfoOffset = kContextOffset + kPointerSize;
7220 static const int kSize = kScopeInfoOffset + kPointerSize;
7221
7222 private:
7223 DISALLOW_IMPLICIT_CONSTRUCTORS(JSModule);
7224};
7225
7226
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007227// JSBoundFunction describes a bound function exotic object.
7228class JSBoundFunction : public JSObject {
7229 public:
7230 // [length]: The bound function "length" property.
7231 DECL_ACCESSORS(length, Object)
7232
7233 // [name]: The bound function "name" property.
7234 DECL_ACCESSORS(name, Object)
7235
7236 // [bound_target_function]: The wrapped function object.
7237 DECL_ACCESSORS(bound_target_function, JSReceiver)
7238
7239 // [bound_this]: The value that is always passed as the this value when
7240 // calling the wrapped function.
7241 DECL_ACCESSORS(bound_this, Object)
7242
7243 // [bound_arguments]: A list of values whose elements are used as the first
7244 // arguments to any call to the wrapped function.
7245 DECL_ACCESSORS(bound_arguments, FixedArray)
7246
7247 // [creation_context]: The native context in which the function was bound.
7248 // TODO(bmeurer, verwaest): Can we (mis)use (unused) constructor field in
7249 // the Map instead of putting this into the object? Only required for
7250 // JSReceiver::GetCreationContext() anyway.
7251 DECL_ACCESSORS(creation_context, Context)
7252
7253 static MaybeHandle<Context> GetFunctionRealm(
7254 Handle<JSBoundFunction> function);
7255
7256 DECLARE_CAST(JSBoundFunction)
7257
7258 // Dispatched behavior.
7259 DECLARE_PRINTER(JSBoundFunction)
7260 DECLARE_VERIFIER(JSBoundFunction)
7261
7262 // The bound function's string representation implemented according
7263 // to ES6 section 19.2.3.5 Function.prototype.toString ( ).
7264 static Handle<String> ToString(Handle<JSBoundFunction> function);
7265
7266 // Layout description.
7267 static const int kBoundTargetFunctionOffset = JSObject::kHeaderSize;
7268 static const int kBoundThisOffset = kBoundTargetFunctionOffset + kPointerSize;
7269 static const int kBoundArgumentsOffset = kBoundThisOffset + kPointerSize;
7270 static const int kCreationContextOffset =
7271 kBoundArgumentsOffset + kPointerSize;
7272 static const int kLengthOffset = kCreationContextOffset + kPointerSize;
7273 static const int kNameOffset = kLengthOffset + kPointerSize;
7274 static const int kSize = kNameOffset + kPointerSize;
7275
7276 // Indices of in-object properties.
7277 static const int kLengthIndex = 0;
7278 static const int kNameIndex = 1;
7279
7280 private:
7281 DISALLOW_IMPLICIT_CONSTRUCTORS(JSBoundFunction);
7282};
7283
7284
Steve Blocka7e24c12009-10-30 11:49:00 +00007285// JSFunction describes JavaScript functions.
7286class JSFunction: public JSObject {
7287 public:
7288 // [prototype_or_initial_map]:
7289 DECL_ACCESSORS(prototype_or_initial_map, Object)
7290
Ben Murdoch589d6972011-11-30 16:04:58 +00007291 // [shared]: The information about the function that
Steve Blocka7e24c12009-10-30 11:49:00 +00007292 // can be shared by instances.
7293 DECL_ACCESSORS(shared, SharedFunctionInfo)
7294
7295 // [context]: The context for this function.
7296 inline Context* context();
Steve Blocka7e24c12009-10-30 11:49:00 +00007297 inline void set_context(Object* context);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007298 inline JSObject* global_proxy();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007299 inline Context* native_context();
7300
7301 static Handle<Context> GetFunctionRealm(Handle<JSFunction> function);
Steve Blocka7e24c12009-10-30 11:49:00 +00007302
7303 // [code]: The generated code object for this function. Executed
7304 // when the function is invoked, e.g. foo() or new foo(). See
7305 // [[Call]] and [[Construct]] description in ECMA-262, section
7306 // 8.6.2, page 27.
7307 inline Code* code();
Ben Murdochb0fe1622011-05-05 13:52:32 +01007308 inline void set_code(Code* code);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007309 inline void set_code_no_write_barrier(Code* code);
Ben Murdochb0fe1622011-05-05 13:52:32 +01007310 inline void ReplaceCode(Code* code);
Steve Blocka7e24c12009-10-30 11:49:00 +00007311
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007312 // Tells whether this function inlines the given shared function info.
7313 bool Inlines(SharedFunctionInfo* candidate);
Ben Murdochb0fe1622011-05-05 13:52:32 +01007314
7315 // Tells whether or not this function has been optimized.
7316 inline bool IsOptimized();
7317
7318 // Mark this function for lazy recompilation. The function will be
7319 // recompiled the next time it is executed.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007320 void MarkForOptimization();
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007321 void AttemptConcurrentOptimization();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007322
Ben Murdochb0fe1622011-05-05 13:52:32 +01007323 // Tells whether or not the function is already marked for lazy
7324 // recompilation.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007325 inline bool IsMarkedForOptimization();
7326 inline bool IsMarkedForConcurrentOptimization();
Ben Murdochb0fe1622011-05-05 13:52:32 +01007327
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007328 // Tells whether or not the function is on the concurrent recompilation queue.
7329 inline bool IsInOptimizationQueue();
7330
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007331 // Completes inobject slack tracking on initial map if it is active.
7332 inline void CompleteInobjectSlackTrackingIfActive();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007333
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007334 // [literals]: Fixed array holding the materialized literals.
Steve Blocka7e24c12009-10-30 11:49:00 +00007335 //
7336 // If the function contains object, regexp or array literals, the
7337 // literals array prefix contains the object, regexp, and array
7338 // function to be used when creating these literals. This is
7339 // necessary so that we do not dynamically lookup the object, regexp
7340 // or array functions. Performing a dynamic lookup, we might end up
7341 // using the functions from a new context that we should not have
7342 // access to.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007343 DECL_ACCESSORS(literals, LiteralsArray)
Steve Blocka7e24c12009-10-30 11:49:00 +00007344
7345 // The initial map for an object created by this constructor.
7346 inline Map* initial_map();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007347 static void SetInitialMap(Handle<JSFunction> function, Handle<Map> map,
7348 Handle<Object> prototype);
Steve Blocka7e24c12009-10-30 11:49:00 +00007349 inline bool has_initial_map();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007350 static void EnsureHasInitialMap(Handle<JSFunction> function);
Steve Blocka7e24c12009-10-30 11:49:00 +00007351
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007352 // Creates a map that matches the constructor's initial map, but with
7353 // [[prototype]] being new.target.prototype. Because new.target can be a
7354 // JSProxy, this can call back into JavaScript.
7355 static MUST_USE_RESULT MaybeHandle<Map> GetDerivedMap(
7356 Isolate* isolate, Handle<JSFunction> constructor,
7357 Handle<JSReceiver> new_target);
7358
Steve Blocka7e24c12009-10-30 11:49:00 +00007359 // Get and set the prototype property on a JSFunction. If the
7360 // function has an initial map the prototype is set on the initial
7361 // map. Otherwise, the prototype is put in the initial map field
7362 // until an initial map is needed.
7363 inline bool has_prototype();
7364 inline bool has_instance_prototype();
7365 inline Object* prototype();
7366 inline Object* instance_prototype();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007367 static void SetPrototype(Handle<JSFunction> function,
7368 Handle<Object> value);
7369 static void SetInstancePrototype(Handle<JSFunction> function,
7370 Handle<Object> value);
7371
Steve Block6ded16b2010-05-10 14:33:55 +01007372 // After prototype is removed, it will not be created when accessed, and
7373 // [[Construct]] from this function will not be allowed.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007374 bool RemovePrototype();
Steve Blocka7e24c12009-10-30 11:49:00 +00007375
7376 // Returns if this function has been compiled to native code yet.
7377 inline bool is_compiled();
7378
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007379 // [next_function_link]: Links functions into various lists, e.g. the list
7380 // of optimized functions hanging off the native_context. The CodeFlusher
7381 // uses this link to chain together flushing candidates. Treated weakly
7382 // by the garbage collector.
Ben Murdochb0fe1622011-05-05 13:52:32 +01007383 DECL_ACCESSORS(next_function_link, Object)
7384
7385 // Prints the name of the function using PrintF.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007386 void PrintName(FILE* out = stdout);
Ben Murdochb0fe1622011-05-05 13:52:32 +01007387
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007388 DECLARE_CAST(JSFunction)
Steve Blocka7e24c12009-10-30 11:49:00 +00007389
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007390 // Calculate the instance size and in-object properties count.
7391 void CalculateInstanceSize(InstanceType instance_type,
7392 int requested_internal_fields, int* instance_size,
7393 int* in_object_properties);
7394 void CalculateInstanceSizeForDerivedClass(InstanceType instance_type,
7395 int requested_internal_fields,
7396 int* instance_size,
7397 int* in_object_properties);
7398
7399 // Visiting policy flags define whether the code entry or next function
7400 // should be visited or not.
7401 enum BodyVisitingPolicy {
7402 kVisitCodeEntry = 1 << 0,
7403 kVisitNextFunction = 1 << 1,
7404
7405 kSkipCodeEntryAndNextFunction = 0,
7406 kVisitCodeEntryAndNextFunction = kVisitCodeEntry | kVisitNextFunction
7407 };
7408 // Iterates the function object according to the visiting policy.
7409 template <BodyVisitingPolicy>
7410 class BodyDescriptorImpl;
7411
7412 // Visit the whole object.
7413 typedef BodyDescriptorImpl<kVisitCodeEntryAndNextFunction> BodyDescriptor;
7414
7415 // Don't visit next function.
7416 typedef BodyDescriptorImpl<kVisitCodeEntry> BodyDescriptorStrongCode;
7417 typedef BodyDescriptorImpl<kSkipCodeEntryAndNextFunction>
7418 BodyDescriptorWeakCode;
Steve Block791712a2010-08-27 10:21:07 +01007419
Steve Blocka7e24c12009-10-30 11:49:00 +00007420 // Dispatched behavior.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007421 DECLARE_PRINTER(JSFunction)
7422 DECLARE_VERIFIER(JSFunction)
Steve Blocka7e24c12009-10-30 11:49:00 +00007423
7424 // Returns the number of allocated literals.
7425 inline int NumberOfLiterals();
7426
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007427 // Used for flags such as --hydrogen-filter.
7428 bool PassesFilter(const char* raw_filter);
Steve Blocka7e24c12009-10-30 11:49:00 +00007429
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007430 // The function's name if it is configured, otherwise shared function info
7431 // debug name.
7432 static Handle<String> GetName(Handle<JSFunction> function);
7433
7434 // The function's displayName if it is set, otherwise name if it is
7435 // configured, otherwise shared function info
7436 // debug name.
7437 static Handle<String> GetDebugName(Handle<JSFunction> function);
7438
7439 // The function's string representation implemented according to
7440 // ES6 section 19.2.3.5 Function.prototype.toString ( ).
7441 static Handle<String> ToString(Handle<JSFunction> function);
7442
Ben Murdochb0fe1622011-05-05 13:52:32 +01007443 // Layout descriptors. The last property (from kNonWeakFieldsEndOffset to
7444 // kSize) is weak and has special handling during garbage collection.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007445 static const int kPrototypeOrInitialMapOffset = JSObject::kHeaderSize;
Steve Blocka7e24c12009-10-30 11:49:00 +00007446 static const int kSharedFunctionInfoOffset =
7447 kPrototypeOrInitialMapOffset + kPointerSize;
7448 static const int kContextOffset = kSharedFunctionInfoOffset + kPointerSize;
7449 static const int kLiteralsOffset = kContextOffset + kPointerSize;
Ben Murdochb0fe1622011-05-05 13:52:32 +01007450 static const int kNonWeakFieldsEndOffset = kLiteralsOffset + kPointerSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007451 static const int kCodeEntryOffset = kNonWeakFieldsEndOffset;
7452 static const int kNextFunctionLinkOffset = kCodeEntryOffset + kPointerSize;
Ben Murdochb0fe1622011-05-05 13:52:32 +01007453 static const int kSize = kNextFunctionLinkOffset + kPointerSize;
Steve Blocka7e24c12009-10-30 11:49:00 +00007454
Steve Blocka7e24c12009-10-30 11:49:00 +00007455 private:
7456 DISALLOW_IMPLICIT_CONSTRUCTORS(JSFunction);
7457};
7458
7459
7460// JSGlobalProxy's prototype must be a JSGlobalObject or null,
7461// and the prototype is hidden. JSGlobalProxy always delegates
7462// property accesses to its prototype if the prototype is not null.
7463//
7464// A JSGlobalProxy can be reinitialized which will preserve its identity.
7465//
7466// Accessing a JSGlobalProxy requires security check.
7467
7468class JSGlobalProxy : public JSObject {
7469 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007470 // [native_context]: the owner native context of this global proxy object.
Steve Blocka7e24c12009-10-30 11:49:00 +00007471 // It is null value if this object is not used by any context.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007472 DECL_ACCESSORS(native_context, Object)
Steve Blocka7e24c12009-10-30 11:49:00 +00007473
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007474 // [hash]: The hash code property (undefined if not initialized yet).
7475 DECL_ACCESSORS(hash, Object)
7476
7477 DECLARE_CAST(JSGlobalProxy)
7478
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007479 inline bool IsDetachedFrom(JSGlobalObject* global) const;
Steve Blocka7e24c12009-10-30 11:49:00 +00007480
7481 // Dispatched behavior.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007482 DECLARE_PRINTER(JSGlobalProxy)
7483 DECLARE_VERIFIER(JSGlobalProxy)
Steve Blocka7e24c12009-10-30 11:49:00 +00007484
7485 // Layout description.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007486 static const int kNativeContextOffset = JSObject::kHeaderSize;
7487 static const int kHashOffset = kNativeContextOffset + kPointerSize;
7488 static const int kSize = kHashOffset + kPointerSize;
Steve Blocka7e24c12009-10-30 11:49:00 +00007489
7490 private:
Steve Blocka7e24c12009-10-30 11:49:00 +00007491 DISALLOW_IMPLICIT_CONSTRUCTORS(JSGlobalProxy);
7492};
7493
7494
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007495// JavaScript global object.
7496class JSGlobalObject : public JSObject {
Steve Blocka7e24c12009-10-30 11:49:00 +00007497 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007498 // [native context]: the natives corresponding to this global object.
7499 DECL_ACCESSORS(native_context, Context)
7500
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007501 // [global proxy]: the global proxy object of the context
7502 DECL_ACCESSORS(global_proxy, JSObject)
Steve Blocka7e24c12009-10-30 11:49:00 +00007503
Steve Blocka7e24c12009-10-30 11:49:00 +00007504
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007505 static void InvalidatePropertyCell(Handle<JSGlobalObject> object,
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007506 Handle<Name> name);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007507 // Ensure that the global object has a cell for the given property name.
7508 static Handle<PropertyCell> EnsurePropertyCell(Handle<JSGlobalObject> global,
7509 Handle<Name> name);
7510
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007511 DECLARE_CAST(JSGlobalObject)
7512
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007513 inline bool IsDetached();
Steve Blocka7e24c12009-10-30 11:49:00 +00007514
7515 // Dispatched behavior.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007516 DECLARE_PRINTER(JSGlobalObject)
7517 DECLARE_VERIFIER(JSGlobalObject)
Steve Blocka7e24c12009-10-30 11:49:00 +00007518
7519 // Layout description.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007520 static const int kNativeContextOffset = JSObject::kHeaderSize;
7521 static const int kGlobalProxyOffset = kNativeContextOffset + kPointerSize;
7522 static const int kHeaderSize = kGlobalProxyOffset + kPointerSize;
7523 static const int kSize = kHeaderSize;
Steve Blocka7e24c12009-10-30 11:49:00 +00007524
7525 private:
7526 DISALLOW_IMPLICIT_CONSTRUCTORS(JSGlobalObject);
7527};
7528
7529
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007530// Representation for JS Wrapper objects, String, Number, Boolean, etc.
Steve Blocka7e24c12009-10-30 11:49:00 +00007531class JSValue: public JSObject {
7532 public:
7533 // [value]: the object being wrapped.
7534 DECL_ACCESSORS(value, Object)
7535
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007536 DECLARE_CAST(JSValue)
Steve Blocka7e24c12009-10-30 11:49:00 +00007537
7538 // Dispatched behavior.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007539 DECLARE_PRINTER(JSValue)
7540 DECLARE_VERIFIER(JSValue)
Steve Blocka7e24c12009-10-30 11:49:00 +00007541
7542 // Layout description.
7543 static const int kValueOffset = JSObject::kHeaderSize;
7544 static const int kSize = kValueOffset + kPointerSize;
7545
7546 private:
7547 DISALLOW_IMPLICIT_CONSTRUCTORS(JSValue);
7548};
7549
Steve Block1e0659c2011-05-24 12:43:12 +01007550
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007551class DateCache;
7552
7553// Representation for JS date objects.
7554class JSDate: public JSObject {
7555 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007556 static MUST_USE_RESULT MaybeHandle<JSDate> New(Handle<JSFunction> constructor,
7557 Handle<JSReceiver> new_target,
7558 double tv);
7559
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007560 // If one component is NaN, all of them are, indicating a NaN time value.
7561 // [value]: the time value.
7562 DECL_ACCESSORS(value, Object)
7563 // [year]: caches year. Either undefined, smi, or NaN.
7564 DECL_ACCESSORS(year, Object)
7565 // [month]: caches month. Either undefined, smi, or NaN.
7566 DECL_ACCESSORS(month, Object)
7567 // [day]: caches day. Either undefined, smi, or NaN.
7568 DECL_ACCESSORS(day, Object)
7569 // [weekday]: caches day of week. Either undefined, smi, or NaN.
7570 DECL_ACCESSORS(weekday, Object)
7571 // [hour]: caches hours. Either undefined, smi, or NaN.
7572 DECL_ACCESSORS(hour, Object)
7573 // [min]: caches minutes. Either undefined, smi, or NaN.
7574 DECL_ACCESSORS(min, Object)
7575 // [sec]: caches seconds. Either undefined, smi, or NaN.
7576 DECL_ACCESSORS(sec, Object)
7577 // [cache stamp]: sample of the date cache stamp at the
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007578 // moment when chached fields were cached.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007579 DECL_ACCESSORS(cache_stamp, Object)
7580
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007581 DECLARE_CAST(JSDate)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007582
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007583 // Returns the time value (UTC) identifying the current time.
7584 static double CurrentTimeValue(Isolate* isolate);
7585
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007586 // Returns the date field with the specified index.
7587 // See FieldIndex for the list of date fields.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007588 static Object* GetField(Object* date, Smi* index);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007589
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007590 static Handle<Object> SetValue(Handle<JSDate> date, double v);
7591
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007592 void SetValue(Object* value, bool is_value_nan);
7593
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007594 // ES6 section 20.3.4.45 Date.prototype [ @@toPrimitive ]
7595 static MUST_USE_RESULT MaybeHandle<Object> ToPrimitive(
7596 Handle<JSReceiver> receiver, Handle<Object> hint);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007597
7598 // Dispatched behavior.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007599 DECLARE_PRINTER(JSDate)
7600 DECLARE_VERIFIER(JSDate)
7601
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007602 // The order is important. It must be kept in sync with date macros
7603 // in macros.py.
7604 enum FieldIndex {
7605 kDateValue,
7606 kYear,
7607 kMonth,
7608 kDay,
7609 kWeekday,
7610 kHour,
7611 kMinute,
7612 kSecond,
7613 kFirstUncachedField,
7614 kMillisecond = kFirstUncachedField,
7615 kDays,
7616 kTimeInDay,
7617 kFirstUTCField,
7618 kYearUTC = kFirstUTCField,
7619 kMonthUTC,
7620 kDayUTC,
7621 kWeekdayUTC,
7622 kHourUTC,
7623 kMinuteUTC,
7624 kSecondUTC,
7625 kMillisecondUTC,
7626 kDaysUTC,
7627 kTimeInDayUTC,
7628 kTimezoneOffset
7629 };
7630
7631 // Layout description.
7632 static const int kValueOffset = JSObject::kHeaderSize;
7633 static const int kYearOffset = kValueOffset + kPointerSize;
7634 static const int kMonthOffset = kYearOffset + kPointerSize;
7635 static const int kDayOffset = kMonthOffset + kPointerSize;
7636 static const int kWeekdayOffset = kDayOffset + kPointerSize;
7637 static const int kHourOffset = kWeekdayOffset + kPointerSize;
7638 static const int kMinOffset = kHourOffset + kPointerSize;
7639 static const int kSecOffset = kMinOffset + kPointerSize;
7640 static const int kCacheStampOffset = kSecOffset + kPointerSize;
7641 static const int kSize = kCacheStampOffset + kPointerSize;
7642
7643 private:
7644 inline Object* DoGetField(FieldIndex index);
7645
7646 Object* GetUTCField(FieldIndex index, double value, DateCache* date_cache);
7647
7648 // Computes and caches the cacheable fields of the date.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007649 inline void SetCachedFields(int64_t local_time_ms, DateCache* date_cache);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007650
7651
7652 DISALLOW_IMPLICIT_CONSTRUCTORS(JSDate);
7653};
7654
7655
Steve Block1e0659c2011-05-24 12:43:12 +01007656// Representation of message objects used for error reporting through
7657// the API. The messages are formatted in JavaScript so this object is
7658// a real JavaScript object. The information used for formatting the
7659// error messages are not directly accessible from JavaScript to
7660// prevent leaking information to user code called during error
7661// formatting.
7662class JSMessageObject: public JSObject {
7663 public:
7664 // [type]: the type of error message.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007665 inline int type() const;
7666 inline void set_type(int value);
Steve Block1e0659c2011-05-24 12:43:12 +01007667
7668 // [arguments]: the arguments for formatting the error message.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007669 DECL_ACCESSORS(argument, Object)
Steve Block1e0659c2011-05-24 12:43:12 +01007670
7671 // [script]: the script from which the error message originated.
7672 DECL_ACCESSORS(script, Object)
7673
Steve Block1e0659c2011-05-24 12:43:12 +01007674 // [stack_frames]: an array of stack frames for this error object.
7675 DECL_ACCESSORS(stack_frames, Object)
7676
7677 // [start_position]: the start position in the script for the error message.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007678 inline int start_position() const;
Steve Block1e0659c2011-05-24 12:43:12 +01007679 inline void set_start_position(int value);
7680
7681 // [end_position]: the end position in the script for the error message.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007682 inline int end_position() const;
Steve Block1e0659c2011-05-24 12:43:12 +01007683 inline void set_end_position(int value);
7684
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007685 DECLARE_CAST(JSMessageObject)
Steve Block1e0659c2011-05-24 12:43:12 +01007686
7687 // Dispatched behavior.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007688 DECLARE_PRINTER(JSMessageObject)
7689 DECLARE_VERIFIER(JSMessageObject)
Steve Block1e0659c2011-05-24 12:43:12 +01007690
7691 // Layout description.
7692 static const int kTypeOffset = JSObject::kHeaderSize;
7693 static const int kArgumentsOffset = kTypeOffset + kPointerSize;
7694 static const int kScriptOffset = kArgumentsOffset + kPointerSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007695 static const int kStackFramesOffset = kScriptOffset + kPointerSize;
Steve Block1e0659c2011-05-24 12:43:12 +01007696 static const int kStartPositionOffset = kStackFramesOffset + kPointerSize;
7697 static const int kEndPositionOffset = kStartPositionOffset + kPointerSize;
7698 static const int kSize = kEndPositionOffset + kPointerSize;
7699
7700 typedef FixedBodyDescriptor<HeapObject::kMapOffset,
7701 kStackFramesOffset + kPointerSize,
7702 kSize> BodyDescriptor;
7703};
7704
7705
Steve Blocka7e24c12009-10-30 11:49:00 +00007706// Regular expressions
7707// The regular expression holds a single reference to a FixedArray in
7708// the kDataOffset field.
7709// The FixedArray contains the following data:
7710// - tag : type of regexp implementation (not compiled yet, atom or irregexp)
7711// - reference to the original source string
7712// - reference to the original flag string
7713// If it is an atom regexp
7714// - a reference to a literal string to search for
7715// If it is an irregexp regexp:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007716// - a reference to code for Latin1 inputs (bytecode or compiled), or a smi
Ben Murdoch257744e2011-11-30 15:57:28 +00007717// used for tracking the last usage (used for code flushing).
7718// - a reference to code for UC16 inputs (bytecode or compiled), or a smi
7719// used for tracking the last usage (used for code flushing)..
Steve Blocka7e24c12009-10-30 11:49:00 +00007720// - max number of registers used by irregexp implementations.
7721// - number of capture registers (output values) of the regexp.
7722class JSRegExp: public JSObject {
7723 public:
7724 // Meaning of Type:
7725 // NOT_COMPILED: Initial value. No data has been stored in the JSRegExp yet.
7726 // ATOM: A simple string to match against using an indexOf operation.
7727 // IRREGEXP: Compiled with Irregexp.
7728 // IRREGEXP_NATIVE: Compiled to native code with Irregexp.
7729 enum Type { NOT_COMPILED, ATOM, IRREGEXP };
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007730 enum Flag {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007731 kNone = 0,
7732 kGlobal = 1 << 0,
7733 kIgnoreCase = 1 << 1,
7734 kMultiline = 1 << 2,
7735 kSticky = 1 << 3,
7736 kUnicode = 1 << 4,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007737 };
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007738 typedef base::Flags<Flag> Flags;
Steve Blocka7e24c12009-10-30 11:49:00 +00007739
7740 DECL_ACCESSORS(data, Object)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007741 DECL_ACCESSORS(flags, Object)
7742 DECL_ACCESSORS(source, Object)
7743
7744 static MaybeHandle<JSRegExp> New(Handle<String> source, Flags flags);
7745 static MaybeHandle<JSRegExp> New(Handle<String> source, Handle<String> flags);
7746 static Handle<JSRegExp> Copy(Handle<JSRegExp> regexp);
7747
7748 static MaybeHandle<JSRegExp> Initialize(Handle<JSRegExp> regexp,
7749 Handle<String> source, Flags flags);
7750 static MaybeHandle<JSRegExp> Initialize(Handle<JSRegExp> regexp,
7751 Handle<String> source,
7752 Handle<String> flags_string);
Steve Blocka7e24c12009-10-30 11:49:00 +00007753
7754 inline Type TypeTag();
7755 inline int CaptureCount();
7756 inline Flags GetFlags();
7757 inline String* Pattern();
7758 inline Object* DataAt(int index);
7759 // Set implementation data after the object has been prepared.
7760 inline void SetDataAt(int index, Object* value);
Ben Murdoch257744e2011-11-30 15:57:28 +00007761
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007762 static int code_index(bool is_latin1) {
7763 if (is_latin1) {
7764 return kIrregexpLatin1CodeIndex;
Steve Blocka7e24c12009-10-30 11:49:00 +00007765 } else {
7766 return kIrregexpUC16CodeIndex;
7767 }
7768 }
7769
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007770 static int saved_code_index(bool is_latin1) {
7771 if (is_latin1) {
7772 return kIrregexpLatin1CodeSavedIndex;
Ben Murdoch257744e2011-11-30 15:57:28 +00007773 } else {
7774 return kIrregexpUC16CodeSavedIndex;
7775 }
7776 }
7777
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007778 DECLARE_CAST(JSRegExp)
Steve Blocka7e24c12009-10-30 11:49:00 +00007779
7780 // Dispatched behavior.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007781 DECLARE_PRINTER(JSRegExp)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007782 DECLARE_VERIFIER(JSRegExp)
Steve Blocka7e24c12009-10-30 11:49:00 +00007783
7784 static const int kDataOffset = JSObject::kHeaderSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007785 static const int kSourceOffset = kDataOffset + kPointerSize;
7786 static const int kFlagsOffset = kSourceOffset + kPointerSize;
7787 static const int kSize = kFlagsOffset + kPointerSize;
Steve Blocka7e24c12009-10-30 11:49:00 +00007788
7789 // Indices in the data array.
7790 static const int kTagIndex = 0;
7791 static const int kSourceIndex = kTagIndex + 1;
7792 static const int kFlagsIndex = kSourceIndex + 1;
7793 static const int kDataIndex = kFlagsIndex + 1;
7794 // The data fields are used in different ways depending on the
7795 // value of the tag.
7796 // Atom regexps (literal strings).
7797 static const int kAtomPatternIndex = kDataIndex;
7798
7799 static const int kAtomDataSize = kAtomPatternIndex + 1;
7800
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007801 // Irregexp compiled code or bytecode for Latin1. If compilation
Steve Blocka7e24c12009-10-30 11:49:00 +00007802 // fails, this fields hold an exception object that should be
7803 // thrown if the regexp is used again.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007804 static const int kIrregexpLatin1CodeIndex = kDataIndex;
Steve Blocka7e24c12009-10-30 11:49:00 +00007805 // Irregexp compiled code or bytecode for UC16. If compilation
7806 // fails, this fields hold an exception object that should be
7807 // thrown if the regexp is used again.
7808 static const int kIrregexpUC16CodeIndex = kDataIndex + 1;
Ben Murdoch257744e2011-11-30 15:57:28 +00007809
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007810 // Saved instance of Irregexp compiled code or bytecode for Latin1 that
Ben Murdoch257744e2011-11-30 15:57:28 +00007811 // is a potential candidate for flushing.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007812 static const int kIrregexpLatin1CodeSavedIndex = kDataIndex + 2;
Ben Murdoch257744e2011-11-30 15:57:28 +00007813 // Saved instance of Irregexp compiled code or bytecode for UC16 that is
7814 // a potential candidate for flushing.
7815 static const int kIrregexpUC16CodeSavedIndex = kDataIndex + 3;
7816
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007817 // Maximal number of registers used by either Latin1 or UC16.
Steve Blocka7e24c12009-10-30 11:49:00 +00007818 // Only used to check that there is enough stack space
Ben Murdoch257744e2011-11-30 15:57:28 +00007819 static const int kIrregexpMaxRegisterCountIndex = kDataIndex + 4;
Steve Blocka7e24c12009-10-30 11:49:00 +00007820 // Number of captures in the compiled regexp.
Ben Murdoch257744e2011-11-30 15:57:28 +00007821 static const int kIrregexpCaptureCountIndex = kDataIndex + 5;
Steve Blocka7e24c12009-10-30 11:49:00 +00007822
7823 static const int kIrregexpDataSize = kIrregexpCaptureCountIndex + 1;
Leon Clarkee46be812010-01-19 14:06:41 +00007824
7825 // Offsets directly into the data fixed array.
7826 static const int kDataTagOffset =
7827 FixedArray::kHeaderSize + kTagIndex * kPointerSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007828 static const int kDataOneByteCodeOffset =
7829 FixedArray::kHeaderSize + kIrregexpLatin1CodeIndex * kPointerSize;
Leon Clarked91b9f72010-01-27 17:25:45 +00007830 static const int kDataUC16CodeOffset =
7831 FixedArray::kHeaderSize + kIrregexpUC16CodeIndex * kPointerSize;
Leon Clarkee46be812010-01-19 14:06:41 +00007832 static const int kIrregexpCaptureCountOffset =
7833 FixedArray::kHeaderSize + kIrregexpCaptureCountIndex * kPointerSize;
Steve Block6ded16b2010-05-10 14:33:55 +01007834
7835 // In-object fields.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007836 static const int kLastIndexFieldIndex = 0;
7837 static const int kInObjectFieldCount = 1;
Ben Murdoch257744e2011-11-30 15:57:28 +00007838
7839 // The uninitialized value for a regexp code object.
7840 static const int kUninitializedValue = -1;
7841
7842 // The compilation error value for the regexp code object. The real error
7843 // object is in the saved code field.
7844 static const int kCompilationErrorValue = -2;
7845
7846 // When we store the sweep generation at which we moved the code from the
7847 // code index to the saved code index we mask it of to be in the [0:255]
7848 // range.
7849 static const int kCodeAgeMask = 0xff;
Steve Blocka7e24c12009-10-30 11:49:00 +00007850};
7851
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007852DEFINE_OPERATORS_FOR_FLAGS(JSRegExp::Flags)
7853
Steve Blocka7e24c12009-10-30 11:49:00 +00007854
Ben Murdochc7cc0282012-03-05 14:35:55 +00007855class CompilationCacheShape : public BaseShape<HashTableKey*> {
Steve Blocka7e24c12009-10-30 11:49:00 +00007856 public:
7857 static inline bool IsMatch(HashTableKey* key, Object* value) {
7858 return key->IsMatch(value);
7859 }
7860
7861 static inline uint32_t Hash(HashTableKey* key) {
7862 return key->Hash();
7863 }
7864
7865 static inline uint32_t HashForObject(HashTableKey* key, Object* object) {
7866 return key->HashForObject(object);
7867 }
7868
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007869 static inline Handle<Object> AsHandle(Isolate* isolate, HashTableKey* key);
Steve Blocka7e24c12009-10-30 11:49:00 +00007870
7871 static const int kPrefixSize = 0;
7872 static const int kEntrySize = 2;
7873};
7874
Steve Block3ce2e202009-11-05 08:53:23 +00007875
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007876// This cache is used in two different variants. For regexp caching, it simply
7877// maps identifying info of the regexp to the cached regexp object. Scripts and
7878// eval code only gets cached after a second probe for the code object. To do
7879// so, on first "put" only a hash identifying the source is entered into the
7880// cache, mapping it to a lifetime count of the hash. On each call to Age all
7881// such lifetimes get reduced, and removed once they reach zero. If a second put
7882// is called while such a hash is live in the cache, the hash gets replaced by
7883// an actual cache entry. Age also removes stale live entries from the cache.
7884// Such entries are identified by SharedFunctionInfos pointing to either the
7885// recompilation stub, or to "old" code. This avoids memory leaks due to
7886// premature caching of scripts and eval strings that are never needed later.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007887class CompilationCacheTable: public HashTable<CompilationCacheTable,
7888 CompilationCacheShape,
Steve Blocka7e24c12009-10-30 11:49:00 +00007889 HashTableKey*> {
7890 public:
7891 // Find cached value for a string key, otherwise return null.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007892 Handle<Object> Lookup(
7893 Handle<String> src, Handle<Context> context, LanguageMode language_mode);
7894 Handle<Object> LookupEval(
7895 Handle<String> src, Handle<SharedFunctionInfo> shared,
7896 LanguageMode language_mode, int scope_position);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007897 Handle<Object> LookupRegExp(Handle<String> source, JSRegExp::Flags flags);
7898 static Handle<CompilationCacheTable> Put(
7899 Handle<CompilationCacheTable> cache, Handle<String> src,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007900 Handle<Context> context, LanguageMode language_mode,
7901 Handle<Object> value);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007902 static Handle<CompilationCacheTable> PutEval(
7903 Handle<CompilationCacheTable> cache, Handle<String> src,
7904 Handle<SharedFunctionInfo> context, Handle<SharedFunctionInfo> value,
7905 int scope_position);
7906 static Handle<CompilationCacheTable> PutRegExp(
7907 Handle<CompilationCacheTable> cache, Handle<String> src,
7908 JSRegExp::Flags flags, Handle<FixedArray> value);
Ben Murdochb0fe1622011-05-05 13:52:32 +01007909 void Remove(Object* value);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007910 void Age();
7911 static const int kHashGenerations = 10;
Ben Murdochb0fe1622011-05-05 13:52:32 +01007912
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007913 DECLARE_CAST(CompilationCacheTable)
Steve Blocka7e24c12009-10-30 11:49:00 +00007914
7915 private:
7916 DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationCacheTable);
7917};
7918
7919
Steve Block6ded16b2010-05-10 14:33:55 +01007920class CodeCache: public Struct {
7921 public:
7922 DECL_ACCESSORS(default_cache, FixedArray)
7923 DECL_ACCESSORS(normal_type_cache, Object)
7924
7925 // Add the code object to the cache.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007926 static void Update(
7927 Handle<CodeCache> cache, Handle<Name> name, Handle<Code> code);
Steve Block6ded16b2010-05-10 14:33:55 +01007928
7929 // Lookup code object in the cache. Returns code object if found and undefined
7930 // if not.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007931 Object* Lookup(Name* name, Code::Flags flags);
Steve Block6ded16b2010-05-10 14:33:55 +01007932
7933 // Get the internal index of a code object in the cache. Returns -1 if the
7934 // code object is not in that cache. This index can be used to later call
7935 // RemoveByIndex. The cache cannot be modified between a call to GetIndex and
7936 // RemoveByIndex.
7937 int GetIndex(Object* name, Code* code);
7938
7939 // Remove an object from the cache with the provided internal index.
7940 void RemoveByIndex(Object* name, Code* code, int index);
7941
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007942 DECLARE_CAST(CodeCache)
Steve Block6ded16b2010-05-10 14:33:55 +01007943
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007944 // Dispatched behavior.
7945 DECLARE_PRINTER(CodeCache)
7946 DECLARE_VERIFIER(CodeCache)
Steve Block6ded16b2010-05-10 14:33:55 +01007947
7948 static const int kDefaultCacheOffset = HeapObject::kHeaderSize;
7949 static const int kNormalTypeCacheOffset =
7950 kDefaultCacheOffset + kPointerSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007951 static const int kSize = kNormalTypeCacheOffset + kPointerSize;
Steve Block6ded16b2010-05-10 14:33:55 +01007952
7953 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007954 static void UpdateDefaultCache(
7955 Handle<CodeCache> code_cache, Handle<Name> name, Handle<Code> code);
7956 static void UpdateNormalTypeCache(
7957 Handle<CodeCache> code_cache, Handle<Name> name, Handle<Code> code);
7958 Object* LookupDefaultCache(Name* name, Code::Flags flags);
7959 Object* LookupNormalTypeCache(Name* name, Code::Flags flags);
Steve Block6ded16b2010-05-10 14:33:55 +01007960
7961 // Code cache layout of the default cache. Elements are alternating name and
7962 // code objects for non normal load/store/call IC's.
7963 static const int kCodeCacheEntrySize = 2;
7964 static const int kCodeCacheEntryNameOffset = 0;
7965 static const int kCodeCacheEntryCodeOffset = 1;
7966
7967 DISALLOW_IMPLICIT_CONSTRUCTORS(CodeCache);
7968};
7969
7970
Ben Murdochc7cc0282012-03-05 14:35:55 +00007971class CodeCacheHashTableShape : public BaseShape<HashTableKey*> {
Steve Block6ded16b2010-05-10 14:33:55 +01007972 public:
7973 static inline bool IsMatch(HashTableKey* key, Object* value) {
7974 return key->IsMatch(value);
7975 }
7976
7977 static inline uint32_t Hash(HashTableKey* key) {
7978 return key->Hash();
7979 }
7980
7981 static inline uint32_t HashForObject(HashTableKey* key, Object* object) {
7982 return key->HashForObject(object);
7983 }
7984
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007985 static inline Handle<Object> AsHandle(Isolate* isolate, HashTableKey* key);
Steve Block6ded16b2010-05-10 14:33:55 +01007986
7987 static const int kPrefixSize = 0;
7988 static const int kEntrySize = 2;
7989};
7990
7991
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007992class CodeCacheHashTable: public HashTable<CodeCacheHashTable,
7993 CodeCacheHashTableShape,
Steve Block6ded16b2010-05-10 14:33:55 +01007994 HashTableKey*> {
7995 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007996 Object* Lookup(Name* name, Code::Flags flags);
7997 static Handle<CodeCacheHashTable> Put(
7998 Handle<CodeCacheHashTable> table,
7999 Handle<Name> name,
8000 Handle<Code> code);
Steve Block6ded16b2010-05-10 14:33:55 +01008001
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008002 int GetIndex(Name* name, Code::Flags flags);
Steve Block6ded16b2010-05-10 14:33:55 +01008003 void RemoveByIndex(int index);
8004
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008005 DECLARE_CAST(CodeCacheHashTable)
Steve Block6ded16b2010-05-10 14:33:55 +01008006
8007 // Initial size of the fixed array backing the hash table.
8008 static const int kInitialSize = 64;
8009
8010 private:
8011 DISALLOW_IMPLICIT_CONSTRUCTORS(CodeCacheHashTable);
8012};
8013
8014
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00008015class PolymorphicCodeCache: public Struct {
8016 public:
8017 DECL_ACCESSORS(cache, Object)
8018
Ben Murdoch3ef787d2012-04-12 10:51:47 +01008019 static void Update(Handle<PolymorphicCodeCache> cache,
8020 MapHandleList* maps,
8021 Code::Flags flags,
8022 Handle<Code> code);
8023
Ben Murdoch3ef787d2012-04-12 10:51:47 +01008024
8025 // Returns an undefined value if the entry is not found.
8026 Handle<Object> Lookup(MapHandleList* maps, Code::Flags flags);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00008027
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008028 DECLARE_CAST(PolymorphicCodeCache)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00008029
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008030 // Dispatched behavior.
8031 DECLARE_PRINTER(PolymorphicCodeCache)
8032 DECLARE_VERIFIER(PolymorphicCodeCache)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00008033
8034 static const int kCacheOffset = HeapObject::kHeaderSize;
8035 static const int kSize = kCacheOffset + kPointerSize;
8036
8037 private:
8038 DISALLOW_IMPLICIT_CONSTRUCTORS(PolymorphicCodeCache);
8039};
8040
8041
8042class PolymorphicCodeCacheHashTable
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008043 : public HashTable<PolymorphicCodeCacheHashTable,
8044 CodeCacheHashTableShape,
8045 HashTableKey*> {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00008046 public:
Ben Murdoch3ef787d2012-04-12 10:51:47 +01008047 Object* Lookup(MapHandleList* maps, int code_kind);
8048
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008049 static Handle<PolymorphicCodeCacheHashTable> Put(
8050 Handle<PolymorphicCodeCacheHashTable> hash_table,
8051 MapHandleList* maps,
8052 int code_kind,
8053 Handle<Code> code);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00008054
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008055 DECLARE_CAST(PolymorphicCodeCacheHashTable)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00008056
8057 static const int kInitialSize = 64;
8058 private:
8059 DISALLOW_IMPLICIT_CONSTRUCTORS(PolymorphicCodeCacheHashTable);
8060};
8061
8062
Ben Murdoch3ef787d2012-04-12 10:51:47 +01008063class TypeFeedbackInfo: public Struct {
8064 public:
8065 inline int ic_total_count();
8066 inline void set_ic_total_count(int count);
8067
Ben Murdoch8f9999f2012-04-23 10:39:17 +01008068 inline int ic_with_type_info_count();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008069 inline void change_ic_with_type_info_count(int delta);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01008070
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008071 inline int ic_generic_count();
8072 inline void change_ic_generic_count(int delta);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01008073
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008074 inline void initialize_storage();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01008075
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008076 inline void change_own_type_change_checksum();
8077 inline int own_type_change_checksum();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01008078
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008079 inline void set_inlined_type_change_checksum(int checksum);
8080 inline bool matches_inlined_type_change_checksum(int checksum);
8081
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008082 DECLARE_CAST(TypeFeedbackInfo)
8083
8084 // Dispatched behavior.
8085 DECLARE_PRINTER(TypeFeedbackInfo)
8086 DECLARE_VERIFIER(TypeFeedbackInfo)
8087
8088 static const int kStorage1Offset = HeapObject::kHeaderSize;
8089 static const int kStorage2Offset = kStorage1Offset + kPointerSize;
8090 static const int kStorage3Offset = kStorage2Offset + kPointerSize;
8091 static const int kSize = kStorage3Offset + kPointerSize;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01008092
8093 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008094 static const int kTypeChangeChecksumBits = 7;
8095
8096 class ICTotalCountField: public BitField<int, 0,
8097 kSmiValueSize - kTypeChangeChecksumBits> {}; // NOLINT
8098 class OwnTypeChangeChecksum: public BitField<int,
8099 kSmiValueSize - kTypeChangeChecksumBits,
8100 kTypeChangeChecksumBits> {}; // NOLINT
8101 class ICsWithTypeInfoCountField: public BitField<int, 0,
8102 kSmiValueSize - kTypeChangeChecksumBits> {}; // NOLINT
8103 class InlinedTypeChangeChecksum: public BitField<int,
8104 kSmiValueSize - kTypeChangeChecksumBits,
8105 kTypeChangeChecksumBits> {}; // NOLINT
8106
Ben Murdoch3ef787d2012-04-12 10:51:47 +01008107 DISALLOW_IMPLICIT_CONSTRUCTORS(TypeFeedbackInfo);
8108};
8109
8110
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008111enum AllocationSiteMode {
8112 DONT_TRACK_ALLOCATION_SITE,
8113 TRACK_ALLOCATION_SITE,
8114 LAST_ALLOCATION_SITE_MODE = TRACK_ALLOCATION_SITE
8115};
8116
8117
8118class AllocationSite: public Struct {
8119 public:
8120 static const uint32_t kMaximumArrayBytesToPretransition = 8 * 1024;
8121 static const double kPretenureRatio;
8122 static const int kPretenureMinimumCreated = 100;
8123
8124 // Values for pretenure decision field.
8125 enum PretenureDecision {
8126 kUndecided = 0,
8127 kDontTenure = 1,
8128 kMaybeTenure = 2,
8129 kTenure = 3,
8130 kZombie = 4,
8131 kLastPretenureDecisionValue = kZombie
8132 };
8133
8134 const char* PretenureDecisionName(PretenureDecision decision);
8135
8136 DECL_ACCESSORS(transition_info, Object)
8137 // nested_site threads a list of sites that represent nested literals
8138 // walked in a particular order. So [[1, 2], 1, 2] will have one
8139 // nested_site, but [[1, 2], 3, [4]] will have a list of two.
8140 DECL_ACCESSORS(nested_site, Object)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008141 DECL_INT_ACCESSORS(pretenure_data)
8142 DECL_INT_ACCESSORS(pretenure_create_count)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008143 DECL_ACCESSORS(dependent_code, DependentCode)
8144 DECL_ACCESSORS(weak_next, Object)
8145
8146 inline void Initialize();
8147
8148 // This method is expensive, it should only be called for reporting.
8149 bool IsNestedSite();
8150
8151 // transition_info bitfields, for constructed array transition info.
8152 class ElementsKindBits: public BitField<ElementsKind, 0, 15> {};
8153 class UnusedBits: public BitField<int, 15, 14> {};
8154 class DoNotInlineBit: public BitField<bool, 29, 1> {};
8155
8156 // Bitfields for pretenure_data
8157 class MementoFoundCountBits: public BitField<int, 0, 26> {};
8158 class PretenureDecisionBits: public BitField<PretenureDecision, 26, 3> {};
8159 class DeoptDependentCodeBit: public BitField<bool, 29, 1> {};
8160 STATIC_ASSERT(PretenureDecisionBits::kMax >= kLastPretenureDecisionValue);
8161
8162 // Increments the mementos found counter and returns true when the first
8163 // memento was found for a given allocation site.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008164 inline bool IncrementMementoFoundCount(int increment = 1);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008165
8166 inline void IncrementMementoCreateCount();
8167
8168 PretenureFlag GetPretenureMode();
8169
8170 void ResetPretenureDecision();
8171
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008172 inline PretenureDecision pretenure_decision();
8173 inline void set_pretenure_decision(PretenureDecision decision);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008174
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008175 inline bool deopt_dependent_code();
8176 inline void set_deopt_dependent_code(bool deopt);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008177
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008178 inline int memento_found_count();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008179 inline void set_memento_found_count(int count);
8180
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008181 inline int memento_create_count();
8182 inline void set_memento_create_count(int count);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008183
8184 // The pretenuring decision is made during gc, and the zombie state allows
8185 // us to recognize when an allocation site is just being kept alive because
8186 // a later traversal of new space may discover AllocationMementos that point
8187 // to this AllocationSite.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008188 inline bool IsZombie();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008189
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008190 inline bool IsMaybeTenure();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008191
8192 inline void MarkZombie();
8193
8194 inline bool MakePretenureDecision(PretenureDecision current_decision,
8195 double ratio,
8196 bool maximum_size_scavenge);
8197
8198 inline bool DigestPretenuringFeedback(bool maximum_size_scavenge);
8199
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008200 inline ElementsKind GetElementsKind();
8201 inline void SetElementsKind(ElementsKind kind);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008202
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008203 inline bool CanInlineCall();
8204 inline void SetDoNotInlineCall();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008205
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008206 inline bool SitePointsToLiteral();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008207
8208 static void DigestTransitionFeedback(Handle<AllocationSite> site,
8209 ElementsKind to_kind);
8210
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008211 DECLARE_PRINTER(AllocationSite)
8212 DECLARE_VERIFIER(AllocationSite)
8213
8214 DECLARE_CAST(AllocationSite)
8215 static inline AllocationSiteMode GetMode(
8216 ElementsKind boilerplate_elements_kind);
8217 static inline AllocationSiteMode GetMode(ElementsKind from, ElementsKind to);
8218 static inline bool CanTrack(InstanceType type);
8219
8220 static const int kTransitionInfoOffset = HeapObject::kHeaderSize;
8221 static const int kNestedSiteOffset = kTransitionInfoOffset + kPointerSize;
8222 static const int kPretenureDataOffset = kNestedSiteOffset + kPointerSize;
8223 static const int kPretenureCreateCountOffset =
8224 kPretenureDataOffset + kPointerSize;
8225 static const int kDependentCodeOffset =
8226 kPretenureCreateCountOffset + kPointerSize;
8227 static const int kWeakNextOffset = kDependentCodeOffset + kPointerSize;
8228 static const int kSize = kWeakNextOffset + kPointerSize;
8229
8230 // During mark compact we need to take special care for the dependent code
8231 // field.
8232 static const int kPointerFieldsBeginOffset = kTransitionInfoOffset;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008233 static const int kPointerFieldsEndOffset = kWeakNextOffset;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008234
8235 // For other visitors, use the fixed body descriptor below.
8236 typedef FixedBodyDescriptor<HeapObject::kHeaderSize,
8237 kDependentCodeOffset + kPointerSize,
8238 kSize> BodyDescriptor;
8239
8240 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008241 inline bool PretenuringDecisionMade();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008242
8243 DISALLOW_IMPLICIT_CONSTRUCTORS(AllocationSite);
8244};
8245
8246
8247class AllocationMemento: public Struct {
8248 public:
8249 static const int kAllocationSiteOffset = HeapObject::kHeaderSize;
8250 static const int kSize = kAllocationSiteOffset + kPointerSize;
8251
8252 DECL_ACCESSORS(allocation_site, Object)
8253
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008254 inline bool IsValid();
8255 inline AllocationSite* GetAllocationSite();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008256
8257 DECLARE_PRINTER(AllocationMemento)
8258 DECLARE_VERIFIER(AllocationMemento)
8259
8260 DECLARE_CAST(AllocationMemento)
8261
8262 private:
8263 DISALLOW_IMPLICIT_CONSTRUCTORS(AllocationMemento);
8264};
8265
8266
8267// Representation of a slow alias as part of a sloppy arguments objects.
8268// For fast aliases (if HasSloppyArgumentsElements()):
Ben Murdoch3ef787d2012-04-12 10:51:47 +01008269// - the parameter map contains an index into the context
8270// - all attributes of the element have default values
8271// For slow aliases (if HasDictionaryArgumentsElements()):
8272// - the parameter map contains no fast alias mapping (i.e. the hole)
8273// - this struct (in the slow backing store) contains an index into the context
8274// - all attributes are available as part if the property details
8275class AliasedArgumentsEntry: public Struct {
8276 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008277 inline int aliased_context_slot() const;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01008278 inline void set_aliased_context_slot(int count);
8279
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008280 DECLARE_CAST(AliasedArgumentsEntry)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01008281
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008282 // Dispatched behavior.
8283 DECLARE_PRINTER(AliasedArgumentsEntry)
8284 DECLARE_VERIFIER(AliasedArgumentsEntry)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01008285
8286 static const int kAliasedContextSlot = HeapObject::kHeaderSize;
8287 static const int kSize = kAliasedContextSlot + kPointerSize;
8288
8289 private:
8290 DISALLOW_IMPLICIT_CONSTRUCTORS(AliasedArgumentsEntry);
8291};
8292
8293
Steve Blocka7e24c12009-10-30 11:49:00 +00008294enum AllowNullsFlag {ALLOW_NULLS, DISALLOW_NULLS};
8295enum RobustnessFlag {ROBUST_STRING_TRAVERSAL, FAST_STRING_TRAVERSAL};
8296
8297
8298class StringHasher {
8299 public:
Ben Murdochc7cc0282012-03-05 14:35:55 +00008300 explicit inline StringHasher(int length, uint32_t seed);
Steve Blocka7e24c12009-10-30 11:49:00 +00008301
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008302 template <typename schar>
8303 static inline uint32_t HashSequentialString(const schar* chars,
8304 int length,
8305 uint32_t seed);
Steve Blocka7e24c12009-10-30 11:49:00 +00008306
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008307 // Reads all the data, even for long strings and computes the utf16 length.
8308 static uint32_t ComputeUtf8Hash(Vector<const char> chars,
8309 uint32_t seed,
8310 int* utf16_length_out);
Steve Blocka7e24c12009-10-30 11:49:00 +00008311
Kristian Monsen80d68ea2010-09-08 11:05:35 +01008312 // Calculated hash value for a string consisting of 1 to
8313 // String::kMaxArrayIndexSize digits with no leading zeros (except "0").
8314 // value is represented decimal value.
Iain Merrick9ac36c92010-09-13 15:29:50 +01008315 static uint32_t MakeArrayIndexHash(uint32_t value, int length);
Kristian Monsen80d68ea2010-09-08 11:05:35 +01008316
Ben Murdochc7cc0282012-03-05 14:35:55 +00008317 // No string is allowed to have a hash of zero. That value is reserved
8318 // for internal properties. If the hash calculation yields zero then we
8319 // use 27 instead.
8320 static const int kZeroHash = 27;
8321
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008322 // Reusable parts of the hashing algorithm.
8323 INLINE(static uint32_t AddCharacterCore(uint32_t running_hash, uint16_t c));
8324 INLINE(static uint32_t GetHashCore(uint32_t running_hash));
Emily Bernierd0a1eb72015-03-24 16:35:39 -04008325 INLINE(static uint32_t ComputeRunningHash(uint32_t running_hash,
8326 const uc16* chars, int length));
8327 INLINE(static uint32_t ComputeRunningHashOneByte(uint32_t running_hash,
8328 const char* chars,
8329 int length));
Steve Blocka7e24c12009-10-30 11:49:00 +00008330
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008331 protected:
8332 // Returns the value to store in the hash field of a string with
8333 // the given length and contents.
8334 uint32_t GetHashField();
8335 // Returns true if the hash of this string can be computed without
8336 // looking at the contents.
8337 inline bool has_trivial_hash();
8338 // Adds a block of characters to the hash.
8339 template<typename Char>
8340 inline void AddCharacters(const Char* chars, int len);
8341
8342 private:
8343 // Add a character to the hash.
8344 inline void AddCharacter(uint16_t c);
8345 // Update index. Returns true if string is still an index.
8346 inline bool UpdateIndex(uint16_t c);
Steve Blocka7e24c12009-10-30 11:49:00 +00008347
8348 int length_;
8349 uint32_t raw_running_hash_;
8350 uint32_t array_index_;
8351 bool is_array_index_;
8352 bool is_first_char_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008353 DISALLOW_COPY_AND_ASSIGN(StringHasher);
Steve Blocka7e24c12009-10-30 11:49:00 +00008354};
8355
8356
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008357class IteratingStringHasher : public StringHasher {
8358 public:
8359 static inline uint32_t Hash(String* string, uint32_t seed);
8360 inline void VisitOneByteString(const uint8_t* chars, int length);
8361 inline void VisitTwoByteString(const uint16_t* chars, int length);
8362
8363 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008364 inline IteratingStringHasher(int len, uint32_t seed);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04008365 void VisitConsString(ConsString* cons_string);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008366 DISALLOW_COPY_AND_ASSIGN(IteratingStringHasher);
8367};
Steve Block44f0eee2011-05-26 01:26:41 +01008368
8369
Steve Blocka7e24c12009-10-30 11:49:00 +00008370// The characteristics of a string are stored in its map. Retrieving these
8371// few bits of information is moderately expensive, involving two memory
8372// loads where the second is dependent on the first. To improve efficiency
8373// the shape of the string is given its own class so that it can be retrieved
8374// once and used for several string operations. A StringShape is small enough
8375// to be passed by value and is immutable, but be aware that flattening a
8376// string can potentially alter its shape. Also be aware that a GC caused by
8377// something else can alter the shape of a string due to ConsString
8378// shortcutting. Keeping these restrictions in mind has proven to be error-
8379// prone and so we no longer put StringShapes in variables unless there is a
8380// concrete performance benefit at that particular point in the code.
8381class StringShape BASE_EMBEDDED {
8382 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008383 inline explicit StringShape(const String* s);
Steve Blocka7e24c12009-10-30 11:49:00 +00008384 inline explicit StringShape(Map* s);
8385 inline explicit StringShape(InstanceType t);
8386 inline bool IsSequential();
8387 inline bool IsExternal();
8388 inline bool IsCons();
Ben Murdoch69a99ed2011-11-30 16:03:39 +00008389 inline bool IsSliced();
8390 inline bool IsIndirect();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008391 inline bool IsExternalOneByte();
Steve Blocka7e24c12009-10-30 11:49:00 +00008392 inline bool IsExternalTwoByte();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008393 inline bool IsSequentialOneByte();
Steve Blocka7e24c12009-10-30 11:49:00 +00008394 inline bool IsSequentialTwoByte();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008395 inline bool IsInternalized();
Steve Blocka7e24c12009-10-30 11:49:00 +00008396 inline StringRepresentationTag representation_tag();
Ben Murdoch69a99ed2011-11-30 16:03:39 +00008397 inline uint32_t encoding_tag();
Steve Blocka7e24c12009-10-30 11:49:00 +00008398 inline uint32_t full_representation_tag();
8399 inline uint32_t size_tag();
8400#ifdef DEBUG
8401 inline uint32_t type() { return type_; }
8402 inline void invalidate() { valid_ = false; }
8403 inline bool valid() { return valid_; }
8404#else
8405 inline void invalidate() { }
8406#endif
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00008407
Steve Blocka7e24c12009-10-30 11:49:00 +00008408 private:
8409 uint32_t type_;
8410#ifdef DEBUG
8411 inline void set_valid() { valid_ = true; }
8412 bool valid_;
8413#else
8414 inline void set_valid() { }
8415#endif
8416};
8417
8418
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008419// The Name abstract class captures anything that can be used as a property
8420// name, i.e., strings and symbols. All names store a hash value.
8421class Name: public HeapObject {
8422 public:
8423 // Get and set the hash field of the name.
8424 inline uint32_t hash_field();
8425 inline void set_hash_field(uint32_t value);
8426
8427 // Tells whether the hash code has been computed.
8428 inline bool HasHashCode();
8429
8430 // Returns a hash value used for the property table
8431 inline uint32_t Hash();
8432
8433 // Equality operations.
8434 inline bool Equals(Name* other);
8435 inline static bool Equals(Handle<Name> one, Handle<Name> two);
8436
8437 // Conversion.
8438 inline bool AsArrayIndex(uint32_t* index);
8439
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008440 // If the name is private, it can only name own properties.
8441 inline bool IsPrivate();
8442
8443 // If the name is a non-flat string, this method returns a flat version of the
8444 // string. Otherwise it'll just return the input.
8445 static inline Handle<Name> Flatten(Handle<Name> name,
8446 PretenureFlag pretenure = NOT_TENURED);
8447
8448 // Return a string version of this name that is converted according to the
8449 // rules described in ES6 section 9.2.11.
8450 MUST_USE_RESULT static MaybeHandle<String> ToFunctionName(Handle<Name> name);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008451
8452 DECLARE_CAST(Name)
8453
8454 DECLARE_PRINTER(Name)
Emily Bernierd0a1eb72015-03-24 16:35:39 -04008455#if TRACE_MAPS
8456 void NameShortPrint();
8457 int NameShortPrint(Vector<char> str);
8458#endif
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008459
8460 // Layout description.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04008461 static const int kHashFieldSlot = HeapObject::kHeaderSize;
8462#if V8_TARGET_LITTLE_ENDIAN || !V8_HOST_ARCH_64_BIT
8463 static const int kHashFieldOffset = kHashFieldSlot;
8464#else
8465 static const int kHashFieldOffset = kHashFieldSlot + kIntSize;
8466#endif
8467 static const int kSize = kHashFieldSlot + kPointerSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008468
8469 // Mask constant for checking if a name has a computed hash code
8470 // and if it is a string that is an array index. The least significant bit
8471 // indicates whether a hash code has been computed. If the hash code has
8472 // been computed the 2nd bit tells whether the string can be used as an
8473 // array index.
8474 static const int kHashNotComputedMask = 1;
8475 static const int kIsNotArrayIndexMask = 1 << 1;
8476 static const int kNofHashBitFields = 2;
8477
8478 // Shift constant retrieving hash code from hash field.
8479 static const int kHashShift = kNofHashBitFields;
8480
8481 // Only these bits are relevant in the hash, since the top two are shifted
8482 // out.
8483 static const uint32_t kHashBitMask = 0xffffffffu >> kHashShift;
8484
8485 // Array index strings this short can keep their index in the hash field.
8486 static const int kMaxCachedArrayIndexLength = 7;
8487
8488 // For strings which are array indexes the hash value has the string length
8489 // mixed into the hash, mainly to avoid a hash value of zero which would be
8490 // the case for the string '0'. 24 bits are used for the array index value.
8491 static const int kArrayIndexValueBits = 24;
8492 static const int kArrayIndexLengthBits =
8493 kBitsPerInt - kArrayIndexValueBits - kNofHashBitFields;
8494
8495 STATIC_ASSERT((kArrayIndexLengthBits > 0));
8496
8497 class ArrayIndexValueBits : public BitField<unsigned int, kNofHashBitFields,
8498 kArrayIndexValueBits> {}; // NOLINT
8499 class ArrayIndexLengthBits : public BitField<unsigned int,
8500 kNofHashBitFields + kArrayIndexValueBits,
8501 kArrayIndexLengthBits> {}; // NOLINT
8502
8503 // Check that kMaxCachedArrayIndexLength + 1 is a power of two so we
8504 // could use a mask to test if the length of string is less than or equal to
8505 // kMaxCachedArrayIndexLength.
8506 STATIC_ASSERT(IS_POWER_OF_TWO(kMaxCachedArrayIndexLength + 1));
8507
8508 static const unsigned int kContainsCachedArrayIndexMask =
8509 (~static_cast<unsigned>(kMaxCachedArrayIndexLength)
8510 << ArrayIndexLengthBits::kShift) |
8511 kIsNotArrayIndexMask;
8512
8513 // Value of empty hash field indicating that the hash is not computed.
8514 static const int kEmptyHashField =
8515 kIsNotArrayIndexMask | kHashNotComputedMask;
8516
8517 protected:
8518 static inline bool IsHashFieldComputed(uint32_t field);
8519
8520 private:
8521 DISALLOW_IMPLICIT_CONSTRUCTORS(Name);
8522};
8523
8524
8525// ES6 symbols.
8526class Symbol: public Name {
8527 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008528 // [name]: The print name of a symbol, or undefined if none.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008529 DECL_ACCESSORS(name, Object)
8530
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008531 DECL_INT_ACCESSORS(flags)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008532
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008533 // [is_private]: Whether this is a private symbol. Private symbols can only
8534 // be used to designate own properties of objects.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008535 DECL_BOOLEAN_ACCESSORS(is_private)
8536
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008537 // [is_well_known_symbol]: Whether this is a spec-defined well-known symbol,
8538 // or not. Well-known symbols do not throw when an access check fails during
8539 // a load.
8540 DECL_BOOLEAN_ACCESSORS(is_well_known_symbol)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008541
8542 DECLARE_CAST(Symbol)
8543
8544 // Dispatched behavior.
8545 DECLARE_PRINTER(Symbol)
8546 DECLARE_VERIFIER(Symbol)
8547
8548 // Layout description.
8549 static const int kNameOffset = Name::kSize;
8550 static const int kFlagsOffset = kNameOffset + kPointerSize;
8551 static const int kSize = kFlagsOffset + kPointerSize;
8552
8553 typedef FixedBodyDescriptor<kNameOffset, kFlagsOffset, kSize> BodyDescriptor;
8554
Emily Bernierd0a1eb72015-03-24 16:35:39 -04008555 void SymbolShortPrint(std::ostream& os);
8556
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008557 private:
8558 static const int kPrivateBit = 0;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008559 static const int kWellKnownSymbolBit = 1;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008560
Emily Bernierd0a1eb72015-03-24 16:35:39 -04008561 const char* PrivateSymbolToName() const;
8562
8563#if TRACE_MAPS
8564 friend class Name; // For PrivateSymbolToName.
8565#endif
8566
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008567 DISALLOW_IMPLICIT_CONSTRUCTORS(Symbol);
8568};
8569
8570
8571class ConsString;
8572
Steve Blocka7e24c12009-10-30 11:49:00 +00008573// The String abstract class captures JavaScript string values:
8574//
8575// Ecma-262:
8576// 4.3.16 String Value
8577// A string value is a member of the type String and is a finite
8578// ordered sequence of zero or more 16-bit unsigned integer values.
8579//
8580// All string values have a length field.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008581class String: public Name {
Steve Blocka7e24c12009-10-30 11:49:00 +00008582 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008583 enum Encoding { ONE_BYTE_ENCODING, TWO_BYTE_ENCODING };
8584
8585 // Array index strings this short can keep their index in the hash field.
8586 static const int kMaxCachedArrayIndexLength = 7;
8587
8588 // For strings which are array indexes the hash value has the string length
8589 // mixed into the hash, mainly to avoid a hash value of zero which would be
8590 // the case for the string '0'. 24 bits are used for the array index value.
8591 static const int kArrayIndexValueBits = 24;
8592 static const int kArrayIndexLengthBits =
8593 kBitsPerInt - kArrayIndexValueBits - kNofHashBitFields;
8594
8595 STATIC_ASSERT((kArrayIndexLengthBits > 0));
8596
8597 class ArrayIndexValueBits : public BitField<unsigned int, kNofHashBitFields,
8598 kArrayIndexValueBits> {}; // NOLINT
8599 class ArrayIndexLengthBits : public BitField<unsigned int,
8600 kNofHashBitFields + kArrayIndexValueBits,
8601 kArrayIndexLengthBits> {}; // NOLINT
8602
8603 // Check that kMaxCachedArrayIndexLength + 1 is a power of two so we
8604 // could use a mask to test if the length of string is less than or equal to
8605 // kMaxCachedArrayIndexLength.
8606 STATIC_ASSERT(IS_POWER_OF_TWO(kMaxCachedArrayIndexLength + 1));
8607
8608 static const unsigned int kContainsCachedArrayIndexMask =
8609 (~static_cast<unsigned>(kMaxCachedArrayIndexLength)
8610 << ArrayIndexLengthBits::kShift) |
8611 kIsNotArrayIndexMask;
8612
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008613 class SubStringRange {
8614 public:
8615 explicit inline SubStringRange(String* string, int first = 0,
8616 int length = -1);
8617 class iterator;
8618 inline iterator begin();
8619 inline iterator end();
8620
8621 private:
8622 String* string_;
8623 int first_;
8624 int length_;
8625 };
8626
Ben Murdoch69a99ed2011-11-30 16:03:39 +00008627 // Representation of the flat content of a String.
8628 // A non-flat string doesn't have flat content.
8629 // A flat string has content that's encoded as a sequence of either
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008630 // one-byte chars or two-byte UC16.
Ben Murdoch69a99ed2011-11-30 16:03:39 +00008631 // Returned by String::GetFlatContent().
8632 class FlatContent {
8633 public:
8634 // Returns true if the string is flat and this structure contains content.
8635 bool IsFlat() { return state_ != NON_FLAT; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008636 // Returns true if the structure contains one-byte content.
8637 bool IsOneByte() { return state_ == ONE_BYTE; }
Ben Murdoch69a99ed2011-11-30 16:03:39 +00008638 // Returns true if the structure contains two-byte content.
8639 bool IsTwoByte() { return state_ == TWO_BYTE; }
8640
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008641 // Return the one byte content of the string. Only use if IsOneByte()
8642 // returns true.
8643 Vector<const uint8_t> ToOneByteVector() {
8644 DCHECK_EQ(ONE_BYTE, state_);
8645 return Vector<const uint8_t>(onebyte_start, length_);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00008646 }
8647 // Return the two-byte content of the string. Only use if IsTwoByte()
8648 // returns true.
8649 Vector<const uc16> ToUC16Vector() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008650 DCHECK_EQ(TWO_BYTE, state_);
8651 return Vector<const uc16>(twobyte_start, length_);
8652 }
8653
8654 uc16 Get(int i) {
8655 DCHECK(i < length_);
8656 DCHECK(state_ != NON_FLAT);
8657 if (state_ == ONE_BYTE) return onebyte_start[i];
8658 return twobyte_start[i];
Ben Murdoch69a99ed2011-11-30 16:03:39 +00008659 }
8660
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008661 bool UsesSameString(const FlatContent& other) const {
8662 return onebyte_start == other.onebyte_start;
8663 }
8664
Ben Murdoch69a99ed2011-11-30 16:03:39 +00008665 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008666 enum State { NON_FLAT, ONE_BYTE, TWO_BYTE };
Ben Murdoch69a99ed2011-11-30 16:03:39 +00008667
8668 // Constructors only used by String::GetFlatContent().
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008669 explicit FlatContent(const uint8_t* start, int length)
8670 : onebyte_start(start), length_(length), state_(ONE_BYTE) {}
8671 explicit FlatContent(const uc16* start, int length)
8672 : twobyte_start(start), length_(length), state_(TWO_BYTE) { }
8673 FlatContent() : onebyte_start(NULL), length_(0), state_(NON_FLAT) { }
Ben Murdoch69a99ed2011-11-30 16:03:39 +00008674
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008675 union {
8676 const uint8_t* onebyte_start;
8677 const uc16* twobyte_start;
8678 };
8679 int length_;
Ben Murdoch69a99ed2011-11-30 16:03:39 +00008680 State state_;
8681
8682 friend class String;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008683 friend class IterableSubString;
Ben Murdoch69a99ed2011-11-30 16:03:39 +00008684 };
8685
Emily Bernierd0a1eb72015-03-24 16:35:39 -04008686 template <typename Char>
8687 INLINE(Vector<const Char> GetCharVector());
8688
Steve Blocka7e24c12009-10-30 11:49:00 +00008689 // Get and set the length of the string.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008690 inline int length() const;
Steve Blocka7e24c12009-10-30 11:49:00 +00008691 inline void set_length(int value);
8692
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008693 // Get and set the length of the string using acquire loads and release
8694 // stores.
8695 inline int synchronized_length() const;
8696 inline void synchronized_set_length(int value);
Steve Blocka7e24c12009-10-30 11:49:00 +00008697
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008698 // Returns whether this string has only one-byte chars, i.e. all of them can
8699 // be one-byte encoded. This might be the case even if the string is
Ben Murdoch69a99ed2011-11-30 16:03:39 +00008700 // two-byte. Such strings may appear when the embedder prefers
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008701 // two-byte external representations even for one-byte data.
8702 inline bool IsOneByteRepresentation() const;
8703 inline bool IsTwoByteRepresentation() const;
Steve Blocka7e24c12009-10-30 11:49:00 +00008704
Ben Murdoch69a99ed2011-11-30 16:03:39 +00008705 // Cons and slices have an encoding flag that may not represent the actual
8706 // encoding of the underlying string. This is taken into account here.
8707 // Requires: this->IsFlat()
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008708 inline bool IsOneByteRepresentationUnderneath();
Ben Murdoch69a99ed2011-11-30 16:03:39 +00008709 inline bool IsTwoByteRepresentationUnderneath();
8710
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01008711 // NOTE: this should be considered only a hint. False negatives are
8712 // possible.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008713 inline bool HasOnlyOneByteChars();
Steve Block6ded16b2010-05-10 14:33:55 +01008714
Steve Blocka7e24c12009-10-30 11:49:00 +00008715 // Get and set individual two byte chars in the string.
8716 inline void Set(int index, uint16_t value);
8717 // Get individual two byte char in the string. Repeated calls
8718 // to this method are not efficient unless the string is flat.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008719 INLINE(uint16_t Get(int index));
Steve Blocka7e24c12009-10-30 11:49:00 +00008720
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008721 // ES6 section 7.1.3.1 ToNumber Applied to the String Type
8722 static Handle<Object> ToNumber(Handle<String> subject);
8723
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008724 // Flattens the string. Checks first inline to see if it is
Leon Clarkef7060e22010-06-03 12:02:55 +01008725 // necessary. Does nothing if the string is not a cons string.
8726 // Flattening allocates a sequential string with the same data as
8727 // the given string and mutates the cons string to a degenerate
8728 // form, where the first component is the new sequential string and
8729 // the second component is the empty string. If allocation fails,
8730 // this function returns a failure. If flattening succeeds, this
8731 // function returns the sequential string that is now the first
8732 // component of the cons string.
8733 //
8734 // Degenerate cons strings are handled specially by the garbage
8735 // collector (see IsShortcutCandidate).
Steve Blocka7e24c12009-10-30 11:49:00 +00008736
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008737 static inline Handle<String> Flatten(Handle<String> string,
8738 PretenureFlag pretenure = NOT_TENURED);
Leon Clarkef7060e22010-06-03 12:02:55 +01008739
Ben Murdoch69a99ed2011-11-30 16:03:39 +00008740 // Tries to return the content of a flat string as a structure holding either
8741 // a flat vector of char or of uc16.
8742 // If the string isn't flat, and therefore doesn't have flat content, the
8743 // returned structure will report so, and can't provide a vector of either
8744 // kind.
8745 FlatContent GetFlatContent();
8746
8747 // Returns the parent of a sliced string or first part of a flat cons string.
8748 // Requires: StringShape(this).IsIndirect() && this->IsFlat()
8749 inline String* GetUnderlying();
Steve Blocka7e24c12009-10-30 11:49:00 +00008750
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008751 // String relational comparison, implemented according to ES6 section 7.2.11
8752 // Abstract Relational Comparison (step 5): The comparison of Strings uses a
8753 // simple lexicographic ordering on sequences of code unit values. There is no
8754 // attempt to use the more complex, semantically oriented definitions of
8755 // character or string equality and collating order defined in the Unicode
8756 // specification. Therefore String values that are canonically equal according
8757 // to the Unicode standard could test as unequal. In effect this algorithm
8758 // assumes that both Strings are already in normalized form. Also, note that
8759 // for strings containing supplementary characters, lexicographic ordering on
8760 // sequences of UTF-16 code unit values differs from that on sequences of code
8761 // point values.
8762 MUST_USE_RESULT static ComparisonResult Compare(Handle<String> x,
8763 Handle<String> y);
Steve Blocka7e24c12009-10-30 11:49:00 +00008764
Steve Blocka7e24c12009-10-30 11:49:00 +00008765 // String equality operations.
8766 inline bool Equals(String* other);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008767 inline static bool Equals(Handle<String> one, Handle<String> two);
8768 bool IsUtf8EqualTo(Vector<const char> str, bool allow_prefix_match = false);
8769 bool IsOneByteEqualTo(Vector<const uint8_t> str);
Steve Block9fac8402011-05-12 15:51:54 +01008770 bool IsTwoByteEqualTo(Vector<const uc16> str);
Steve Blocka7e24c12009-10-30 11:49:00 +00008771
8772 // Return a UTF8 representation of the string. The string is null
8773 // terminated but may optionally contain nulls. Length is returned
8774 // in length_output if length_output is not a null pointer The string
8775 // should be nearly flat, otherwise the performance of this method may
8776 // be very slow (quadratic in the length). Setting robustness_flag to
8777 // ROBUST_STRING_TRAVERSAL invokes behaviour that is robust This means it
8778 // handles unexpected data without causing assert failures and it does not
8779 // do any heap allocations. This is useful when printing stack traces.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008780 base::SmartArrayPointer<char> ToCString(AllowNullsFlag allow_nulls,
8781 RobustnessFlag robustness_flag,
8782 int offset, int length,
8783 int* length_output = 0);
8784 base::SmartArrayPointer<char> ToCString(
Steve Blocka7e24c12009-10-30 11:49:00 +00008785 AllowNullsFlag allow_nulls = DISALLOW_NULLS,
8786 RobustnessFlag robustness_flag = FAST_STRING_TRAVERSAL,
8787 int* length_output = 0);
8788
Steve Blocka7e24c12009-10-30 11:49:00 +00008789 // Return a 16 bit Unicode representation of the string.
8790 // The string should be nearly flat, otherwise the performance of
8791 // of this method may be very bad. Setting robustness_flag to
8792 // ROBUST_STRING_TRAVERSAL invokes behaviour that is robust This means it
8793 // handles unexpected data without causing assert failures and it does not
8794 // do any heap allocations. This is useful when printing stack traces.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008795 base::SmartArrayPointer<uc16> ToWideCString(
Steve Blocka7e24c12009-10-30 11:49:00 +00008796 RobustnessFlag robustness_flag = FAST_STRING_TRAVERSAL);
8797
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008798 bool ComputeArrayIndex(uint32_t* index);
Steve Blocka7e24c12009-10-30 11:49:00 +00008799
8800 // Externalization.
8801 bool MakeExternal(v8::String::ExternalStringResource* resource);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008802 bool MakeExternal(v8::String::ExternalOneByteStringResource* resource);
Steve Blocka7e24c12009-10-30 11:49:00 +00008803
8804 // Conversion.
8805 inline bool AsArrayIndex(uint32_t* index);
8806
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008807 DECLARE_CAST(String)
Steve Blocka7e24c12009-10-30 11:49:00 +00008808
8809 void PrintOn(FILE* out);
8810
8811 // For use during stack traces. Performs rudimentary sanity check.
8812 bool LooksValid();
8813
8814 // Dispatched behavior.
8815 void StringShortPrint(StringStream* accumulator);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04008816 void PrintUC16(std::ostream& os, int start = 0, int end = -1); // NOLINT
8817#if defined(DEBUG) || defined(OBJECT_PRINT)
Ben Murdoch69a99ed2011-11-30 16:03:39 +00008818 char* ToAsciiArray();
Ben Murdochb0fe1622011-05-05 13:52:32 +01008819#endif
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008820 DECLARE_PRINTER(String)
8821 DECLARE_VERIFIER(String)
8822
Steve Blocka7e24c12009-10-30 11:49:00 +00008823 inline bool IsFlat();
8824
8825 // Layout description.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008826 static const int kLengthOffset = Name::kSize;
8827 static const int kSize = kLengthOffset + kPointerSize;
Steve Blocka7e24c12009-10-30 11:49:00 +00008828
Steve Blockd0582a62009-12-15 09:54:21 +00008829 // Maximum number of characters to consider when trying to convert a string
8830 // value into an array index.
Steve Blocka7e24c12009-10-30 11:49:00 +00008831 static const int kMaxArrayIndexSize = 10;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008832 STATIC_ASSERT(kMaxArrayIndexSize < (1 << kArrayIndexLengthBits));
Steve Blocka7e24c12009-10-30 11:49:00 +00008833
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008834 // Max char codes.
8835 static const int32_t kMaxOneByteCharCode = unibrow::Latin1::kMaxChar;
8836 static const uint32_t kMaxOneByteCharCodeU = unibrow::Latin1::kMaxChar;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01008837 static const int kMaxUtf16CodeUnit = 0xffff;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008838 static const uint32_t kMaxUtf16CodeUnitU = kMaxUtf16CodeUnit;
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01008839
8840 // Value of hash field containing computed hash equal to zero.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008841 static const int kEmptyStringHash = kIsNotArrayIndexMask;
Steve Blockd0582a62009-12-15 09:54:21 +00008842
8843 // Maximal string length.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008844 static const int kMaxLength = (1 << 28) - 16;
Steve Blockd0582a62009-12-15 09:54:21 +00008845
8846 // Max length for computing hash. For strings longer than this limit the
8847 // string length is used as the hash value.
8848 static const int kMaxHashCalcLength = 16383;
Steve Blocka7e24c12009-10-30 11:49:00 +00008849
8850 // Limit for truncation in short printing.
8851 static const int kMaxShortPrintLength = 1024;
8852
8853 // Support for regular expressions.
Steve Blocka7e24c12009-10-30 11:49:00 +00008854 const uc16* GetTwoByteData(unsigned start);
8855
Steve Blocka7e24c12009-10-30 11:49:00 +00008856 // Helper function for flattening strings.
8857 template <typename sinkchar>
8858 static void WriteToFlat(String* source,
8859 sinkchar* sink,
8860 int from,
8861 int to);
8862
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008863 // The return value may point to the first aligned word containing the first
8864 // non-one-byte character, rather than directly to the non-one-byte character.
8865 // If the return value is >= the passed length, the entire string was
8866 // one-byte.
8867 static inline int NonAsciiStart(const char* chars, int length) {
8868 const char* start = chars;
Steve Block9fac8402011-05-12 15:51:54 +01008869 const char* limit = chars + length;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008870
8871 if (length >= kIntptrSize) {
8872 // Check unaligned bytes.
8873 while (!IsAligned(reinterpret_cast<intptr_t>(chars), sizeof(uintptr_t))) {
8874 if (static_cast<uint8_t>(*chars) > unibrow::Utf8::kMaxOneByteChar) {
8875 return static_cast<int>(chars - start);
8876 }
8877 ++chars;
Steve Block9fac8402011-05-12 15:51:54 +01008878 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008879 // Check aligned words.
8880 DCHECK(unibrow::Utf8::kMaxOneByteChar == 0x7F);
8881 const uintptr_t non_one_byte_mask = kUintptrAllBitsSet / 0xFF * 0x80;
8882 while (chars + sizeof(uintptr_t) <= limit) {
8883 if (*reinterpret_cast<const uintptr_t*>(chars) & non_one_byte_mask) {
8884 return static_cast<int>(chars - start);
8885 }
8886 chars += sizeof(uintptr_t);
8887 }
Steve Block9fac8402011-05-12 15:51:54 +01008888 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008889 // Check remaining unaligned bytes.
Steve Block9fac8402011-05-12 15:51:54 +01008890 while (chars < limit) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008891 if (static_cast<uint8_t>(*chars) > unibrow::Utf8::kMaxOneByteChar) {
8892 return static_cast<int>(chars - start);
8893 }
Steve Block9fac8402011-05-12 15:51:54 +01008894 ++chars;
8895 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008896
8897 return static_cast<int>(chars - start);
Steve Block9fac8402011-05-12 15:51:54 +01008898 }
8899
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008900 static inline bool IsAscii(const char* chars, int length) {
8901 return NonAsciiStart(chars, length) >= length;
8902 }
8903
8904 static inline bool IsAscii(const uint8_t* chars, int length) {
8905 return
8906 NonAsciiStart(reinterpret_cast<const char*>(chars), length) >= length;
8907 }
8908
8909 static inline int NonOneByteStart(const uc16* chars, int length) {
Steve Block9fac8402011-05-12 15:51:54 +01008910 const uc16* limit = chars + length;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008911 const uc16* start = chars;
Steve Block9fac8402011-05-12 15:51:54 +01008912 while (chars < limit) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008913 if (*chars > kMaxOneByteCharCodeU) return static_cast<int>(chars - start);
Steve Block9fac8402011-05-12 15:51:54 +01008914 ++chars;
8915 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008916 return static_cast<int>(chars - start);
Steve Block9fac8402011-05-12 15:51:54 +01008917 }
8918
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008919 static inline bool IsOneByte(const uc16* chars, int length) {
8920 return NonOneByteStart(chars, length) >= length;
8921 }
Steve Blocka7e24c12009-10-30 11:49:00 +00008922
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008923 template<class Visitor>
8924 static inline ConsString* VisitFlat(Visitor* visitor,
8925 String* string,
8926 int offset = 0);
8927
8928 static Handle<FixedArray> CalculateLineEnds(Handle<String> string,
8929 bool include_ending_line);
8930
8931 // Use the hash field to forward to the canonical internalized string
8932 // when deserializing an internalized string.
8933 inline void SetForwardedInternalizedString(String* string);
8934 inline String* GetForwardedInternalizedString();
Steve Blocka7e24c12009-10-30 11:49:00 +00008935
8936 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008937 friend class Name;
8938 friend class StringTableInsertionKey;
Leon Clarkef7060e22010-06-03 12:02:55 +01008939
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008940 static Handle<String> SlowFlatten(Handle<ConsString> cons,
8941 PretenureFlag tenure);
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01008942
Steve Blocka7e24c12009-10-30 11:49:00 +00008943 // Slow case of String::Equals. This implementation works on any strings
8944 // but it is most efficient on strings that are almost flat.
8945 bool SlowEquals(String* other);
8946
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008947 static bool SlowEquals(Handle<String> one, Handle<String> two);
8948
Steve Blocka7e24c12009-10-30 11:49:00 +00008949 // Slow case of AsArrayIndex.
8950 bool SlowAsArrayIndex(uint32_t* index);
8951
8952 // Compute and set the hash code.
8953 uint32_t ComputeAndSetHash();
8954
8955 DISALLOW_IMPLICIT_CONSTRUCTORS(String);
8956};
8957
8958
8959// The SeqString abstract class captures sequential string values.
8960class SeqString: public String {
8961 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008962 DECLARE_CAST(SeqString)
Steve Blocka7e24c12009-10-30 11:49:00 +00008963
Ben Murdoch3ef787d2012-04-12 10:51:47 +01008964 // Layout description.
8965 static const int kHeaderSize = String::kSize;
8966
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008967 // Truncate the string in-place if possible and return the result.
8968 // In case of new_length == 0, the empty string is returned without
8969 // truncating the original string.
8970 MUST_USE_RESULT static Handle<String> Truncate(Handle<SeqString> string,
8971 int new_length);
Steve Blocka7e24c12009-10-30 11:49:00 +00008972 private:
8973 DISALLOW_IMPLICIT_CONSTRUCTORS(SeqString);
8974};
8975
8976
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008977// The OneByteString class captures sequential one-byte string objects.
8978// Each character in the OneByteString is an one-byte character.
8979class SeqOneByteString: public SeqString {
Steve Blocka7e24c12009-10-30 11:49:00 +00008980 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008981 static const bool kHasOneByteEncoding = true;
Leon Clarkeac952652010-07-15 11:15:24 +01008982
Steve Blocka7e24c12009-10-30 11:49:00 +00008983 // Dispatched behavior.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008984 inline uint16_t SeqOneByteStringGet(int index);
8985 inline void SeqOneByteStringSet(int index, uint16_t value);
Steve Blocka7e24c12009-10-30 11:49:00 +00008986
8987 // Get the address of the characters in this string.
8988 inline Address GetCharsAddress();
8989
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008990 inline uint8_t* GetChars();
Steve Blocka7e24c12009-10-30 11:49:00 +00008991
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008992 DECLARE_CAST(SeqOneByteString)
Steve Blocka7e24c12009-10-30 11:49:00 +00008993
8994 // Garbage collection support. This method is called by the
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008995 // garbage collector to compute the actual size of an OneByteString
Steve Blocka7e24c12009-10-30 11:49:00 +00008996 // instance.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008997 inline int SeqOneByteStringSize(InstanceType instance_type);
Steve Blocka7e24c12009-10-30 11:49:00 +00008998
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008999 // Computes the size for an OneByteString instance of a given length.
Steve Blocka7e24c12009-10-30 11:49:00 +00009000 static int SizeFor(int length) {
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01009001 return OBJECT_POINTER_ALIGN(kHeaderSize + length * kCharSize);
Steve Blocka7e24c12009-10-30 11:49:00 +00009002 }
9003
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009004 // Maximal memory usage for a single sequential one-byte string.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01009005 static const int kMaxSize = 512 * MB - 1;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009006 STATIC_ASSERT((kMaxSize - kHeaderSize) >= String::kMaxLength);
Steve Blocka7e24c12009-10-30 11:49:00 +00009007
9008 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009009 DISALLOW_IMPLICIT_CONSTRUCTORS(SeqOneByteString);
Steve Blocka7e24c12009-10-30 11:49:00 +00009010};
9011
9012
9013// The TwoByteString class captures sequential unicode string objects.
9014// Each character in the TwoByteString is a two-byte uint16_t.
9015class SeqTwoByteString: public SeqString {
9016 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009017 static const bool kHasOneByteEncoding = false;
Leon Clarkeac952652010-07-15 11:15:24 +01009018
Steve Blocka7e24c12009-10-30 11:49:00 +00009019 // Dispatched behavior.
9020 inline uint16_t SeqTwoByteStringGet(int index);
9021 inline void SeqTwoByteStringSet(int index, uint16_t value);
9022
9023 // Get the address of the characters in this string.
9024 inline Address GetCharsAddress();
9025
9026 inline uc16* GetChars();
9027
9028 // For regexp code.
9029 const uint16_t* SeqTwoByteStringGetData(unsigned start);
9030
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009031 DECLARE_CAST(SeqTwoByteString)
Steve Blocka7e24c12009-10-30 11:49:00 +00009032
9033 // Garbage collection support. This method is called by the
9034 // garbage collector to compute the actual size of a TwoByteString
9035 // instance.
9036 inline int SeqTwoByteStringSize(InstanceType instance_type);
9037
9038 // Computes the size for a TwoByteString instance of a given length.
9039 static int SizeFor(int length) {
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01009040 return OBJECT_POINTER_ALIGN(kHeaderSize + length * kShortSize);
Steve Blocka7e24c12009-10-30 11:49:00 +00009041 }
9042
Leon Clarkee46be812010-01-19 14:06:41 +00009043 // Maximal memory usage for a single sequential two-byte string.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01009044 static const int kMaxSize = 512 * MB - 1;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009045 STATIC_ASSERT(static_cast<int>((kMaxSize - kHeaderSize)/sizeof(uint16_t)) >=
9046 String::kMaxLength);
Steve Blocka7e24c12009-10-30 11:49:00 +00009047
9048 private:
9049 DISALLOW_IMPLICIT_CONSTRUCTORS(SeqTwoByteString);
9050};
9051
9052
9053// The ConsString class describes string values built by using the
9054// addition operator on strings. A ConsString is a pair where the
9055// first and second components are pointers to other string values.
9056// One or both components of a ConsString can be pointers to other
9057// ConsStrings, creating a binary tree of ConsStrings where the leaves
9058// are non-ConsString string values. The string value represented by
9059// a ConsString can be obtained by concatenating the leaf string
9060// values in a left-to-right depth-first traversal of the tree.
9061class ConsString: public String {
9062 public:
9063 // First string of the cons cell.
9064 inline String* first();
9065 // Doesn't check that the result is a string, even in debug mode. This is
9066 // useful during GC where the mark bits confuse the checks.
9067 inline Object* unchecked_first();
9068 inline void set_first(String* first,
9069 WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
9070
9071 // Second string of the cons cell.
9072 inline String* second();
9073 // Doesn't check that the result is a string, even in debug mode. This is
9074 // useful during GC where the mark bits confuse the checks.
9075 inline Object* unchecked_second();
9076 inline void set_second(String* second,
9077 WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
9078
9079 // Dispatched behavior.
9080 uint16_t ConsStringGet(int index);
9081
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009082 DECLARE_CAST(ConsString)
Steve Blocka7e24c12009-10-30 11:49:00 +00009083
Steve Blocka7e24c12009-10-30 11:49:00 +00009084 // Layout description.
9085 static const int kFirstOffset = POINTER_SIZE_ALIGN(String::kSize);
9086 static const int kSecondOffset = kFirstOffset + kPointerSize;
9087 static const int kSize = kSecondOffset + kPointerSize;
9088
Steve Blocka7e24c12009-10-30 11:49:00 +00009089 // Minimum length for a cons string.
9090 static const int kMinLength = 13;
9091
Iain Merrick75681382010-08-19 15:07:18 +01009092 typedef FixedBodyDescriptor<kFirstOffset, kSecondOffset + kPointerSize, kSize>
9093 BodyDescriptor;
9094
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009095 DECLARE_VERIFIER(ConsString)
Ben Murdoch69a99ed2011-11-30 16:03:39 +00009096
Steve Blocka7e24c12009-10-30 11:49:00 +00009097 private:
9098 DISALLOW_IMPLICIT_CONSTRUCTORS(ConsString);
9099};
9100
9101
Ben Murdoch69a99ed2011-11-30 16:03:39 +00009102// The Sliced String class describes strings that are substrings of another
9103// sequential string. The motivation is to save time and memory when creating
9104// a substring. A Sliced String is described as a pointer to the parent,
9105// the offset from the start of the parent string and the length. Using
9106// a Sliced String therefore requires unpacking of the parent string and
9107// adding the offset to the start address. A substring of a Sliced String
9108// are not nested since the double indirection is simplified when creating
9109// such a substring.
9110// Currently missing features are:
9111// - handling externalized parent strings
9112// - external strings as parent
9113// - truncating sliced string to enable otherwise unneeded parent to be GC'ed.
9114class SlicedString: public String {
9115 public:
Ben Murdoch69a99ed2011-11-30 16:03:39 +00009116 inline String* parent();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009117 inline void set_parent(String* parent,
9118 WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
9119 inline int offset() const;
Ben Murdoch69a99ed2011-11-30 16:03:39 +00009120 inline void set_offset(int offset);
9121
9122 // Dispatched behavior.
9123 uint16_t SlicedStringGet(int index);
9124
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009125 DECLARE_CAST(SlicedString)
Ben Murdoch69a99ed2011-11-30 16:03:39 +00009126
9127 // Layout description.
9128 static const int kParentOffset = POINTER_SIZE_ALIGN(String::kSize);
9129 static const int kOffsetOffset = kParentOffset + kPointerSize;
9130 static const int kSize = kOffsetOffset + kPointerSize;
9131
Ben Murdoch69a99ed2011-11-30 16:03:39 +00009132 // Minimum length for a sliced string.
9133 static const int kMinLength = 13;
9134
9135 typedef FixedBodyDescriptor<kParentOffset,
9136 kOffsetOffset + kPointerSize, kSize>
9137 BodyDescriptor;
9138
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009139 DECLARE_VERIFIER(SlicedString)
Ben Murdoch69a99ed2011-11-30 16:03:39 +00009140
9141 private:
9142 DISALLOW_IMPLICIT_CONSTRUCTORS(SlicedString);
9143};
9144
9145
Steve Blocka7e24c12009-10-30 11:49:00 +00009146// The ExternalString class describes string values that are backed by
9147// a string resource that lies outside the V8 heap. ExternalStrings
9148// consist of the length field common to all strings, a pointer to the
9149// external resource. It is important to ensure (externally) that the
9150// resource is not deallocated while the ExternalString is live in the
9151// V8 heap.
9152//
9153// The API expects that all ExternalStrings are created through the
9154// API. Therefore, ExternalStrings should not be used internally.
9155class ExternalString: public String {
9156 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009157 DECLARE_CAST(ExternalString)
Steve Blocka7e24c12009-10-30 11:49:00 +00009158
9159 // Layout description.
9160 static const int kResourceOffset = POINTER_SIZE_ALIGN(String::kSize);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01009161 static const int kShortSize = kResourceOffset + kPointerSize;
9162 static const int kResourceDataOffset = kResourceOffset + kPointerSize;
9163 static const int kSize = kResourceDataOffset + kPointerSize;
9164
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009165 static const int kMaxShortLength =
9166 (kShortSize - SeqString::kHeaderSize) / kCharSize;
9167
Ben Murdoch3ef787d2012-04-12 10:51:47 +01009168 // Return whether external string is short (data pointer is not cached).
9169 inline bool is_short();
Steve Blocka7e24c12009-10-30 11:49:00 +00009170
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009171 STATIC_ASSERT(kResourceOffset == Internals::kStringResourceOffset);
Steve Blocka7e24c12009-10-30 11:49:00 +00009172
9173 private:
9174 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalString);
9175};
9176
9177
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009178// The ExternalOneByteString class is an external string backed by an
9179// one-byte string.
9180class ExternalOneByteString : public ExternalString {
Steve Blocka7e24c12009-10-30 11:49:00 +00009181 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009182 static const bool kHasOneByteEncoding = true;
Leon Clarkeac952652010-07-15 11:15:24 +01009183
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009184 typedef v8::String::ExternalOneByteStringResource Resource;
Steve Blocka7e24c12009-10-30 11:49:00 +00009185
9186 // The underlying resource.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01009187 inline const Resource* resource();
9188 inline void set_resource(const Resource* buffer);
9189
9190 // Update the pointer cache to the external character array.
9191 // The cached pointer is always valid, as the external character array does =
9192 // not move during lifetime. Deserialization is the only exception, after
9193 // which the pointer cache has to be refreshed.
9194 inline void update_data_cache();
9195
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009196 inline const uint8_t* GetChars();
Steve Blocka7e24c12009-10-30 11:49:00 +00009197
9198 // Dispatched behavior.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009199 inline uint16_t ExternalOneByteStringGet(int index);
Steve Blocka7e24c12009-10-30 11:49:00 +00009200
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009201 DECLARE_CAST(ExternalOneByteString)
Steve Blocka7e24c12009-10-30 11:49:00 +00009202
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009203 class BodyDescriptor;
Steve Blocka7e24c12009-10-30 11:49:00 +00009204
Steve Blocka7e24c12009-10-30 11:49:00 +00009205 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009206 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalOneByteString);
Steve Blocka7e24c12009-10-30 11:49:00 +00009207};
9208
9209
9210// The ExternalTwoByteString class is an external string backed by a UTF-16
9211// encoded string.
9212class ExternalTwoByteString: public ExternalString {
9213 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009214 static const bool kHasOneByteEncoding = false;
Leon Clarkeac952652010-07-15 11:15:24 +01009215
Steve Blocka7e24c12009-10-30 11:49:00 +00009216 typedef v8::String::ExternalStringResource Resource;
9217
9218 // The underlying string resource.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01009219 inline const Resource* resource();
9220 inline void set_resource(const Resource* buffer);
9221
9222 // Update the pointer cache to the external character array.
9223 // The cached pointer is always valid, as the external character array does =
9224 // not move during lifetime. Deserialization is the only exception, after
9225 // which the pointer cache has to be refreshed.
9226 inline void update_data_cache();
9227
9228 inline const uint16_t* GetChars();
Steve Blocka7e24c12009-10-30 11:49:00 +00009229
9230 // Dispatched behavior.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01009231 inline uint16_t ExternalTwoByteStringGet(int index);
Steve Blocka7e24c12009-10-30 11:49:00 +00009232
9233 // For regexp code.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01009234 inline const uint16_t* ExternalTwoByteStringGetData(unsigned start);
Steve Blocka7e24c12009-10-30 11:49:00 +00009235
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009236 DECLARE_CAST(ExternalTwoByteString)
Steve Blocka7e24c12009-10-30 11:49:00 +00009237
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009238 class BodyDescriptor;
Iain Merrick75681382010-08-19 15:07:18 +01009239
Steve Blocka7e24c12009-10-30 11:49:00 +00009240 private:
9241 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalTwoByteString);
9242};
9243
9244
9245// Utility superclass for stack-allocated objects that must be updated
9246// on gc. It provides two ways for the gc to update instances, either
9247// iterating or updating after gc.
9248class Relocatable BASE_EMBEDDED {
9249 public:
Steve Block44f0eee2011-05-26 01:26:41 +01009250 explicit inline Relocatable(Isolate* isolate);
9251 inline virtual ~Relocatable();
Steve Blocka7e24c12009-10-30 11:49:00 +00009252 virtual void IterateInstance(ObjectVisitor* v) { }
9253 virtual void PostGarbageCollection() { }
9254
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009255 static void PostGarbageCollectionProcessing(Isolate* isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00009256 static int ArchiveSpacePerThread();
Ben Murdoch257744e2011-11-30 15:57:28 +00009257 static char* ArchiveState(Isolate* isolate, char* to);
9258 static char* RestoreState(Isolate* isolate, char* from);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009259 static void Iterate(Isolate* isolate, ObjectVisitor* v);
Steve Blocka7e24c12009-10-30 11:49:00 +00009260 static void Iterate(ObjectVisitor* v, Relocatable* top);
9261 static char* Iterate(ObjectVisitor* v, char* t);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009262
Steve Blocka7e24c12009-10-30 11:49:00 +00009263 private:
Steve Block44f0eee2011-05-26 01:26:41 +01009264 Isolate* isolate_;
Steve Blocka7e24c12009-10-30 11:49:00 +00009265 Relocatable* prev_;
9266};
9267
9268
9269// A flat string reader provides random access to the contents of a
9270// string independent of the character width of the string. The handle
9271// must be valid as long as the reader is being used.
9272class FlatStringReader : public Relocatable {
9273 public:
Steve Block44f0eee2011-05-26 01:26:41 +01009274 FlatStringReader(Isolate* isolate, Handle<String> str);
9275 FlatStringReader(Isolate* isolate, Vector<const char> input);
Steve Blocka7e24c12009-10-30 11:49:00 +00009276 void PostGarbageCollection();
9277 inline uc32 Get(int index);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04009278 template <typename Char>
9279 inline Char Get(int index);
Steve Blocka7e24c12009-10-30 11:49:00 +00009280 int length() { return length_; }
9281 private:
9282 String** str_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009283 bool is_one_byte_;
Steve Blocka7e24c12009-10-30 11:49:00 +00009284 int length_;
9285 const void* start_;
9286};
9287
9288
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009289// This maintains an off-stack representation of the stack frames required
9290// to traverse a ConsString, allowing an entirely iterative and restartable
9291// traversal of the entire string
Emily Bernierd0a1eb72015-03-24 16:35:39 -04009292class ConsStringIterator {
Steve Blocka7e24c12009-10-30 11:49:00 +00009293 public:
Emily Bernierd0a1eb72015-03-24 16:35:39 -04009294 inline ConsStringIterator() {}
9295 inline explicit ConsStringIterator(ConsString* cons_string, int offset = 0) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009296 Reset(cons_string, offset);
9297 }
9298 inline void Reset(ConsString* cons_string, int offset = 0) {
9299 depth_ = 0;
9300 // Next will always return NULL.
9301 if (cons_string == NULL) return;
9302 Initialize(cons_string, offset);
9303 }
9304 // Returns NULL when complete.
9305 inline String* Next(int* offset_out) {
9306 *offset_out = 0;
9307 if (depth_ == 0) return NULL;
9308 return Continue(offset_out);
9309 }
9310
9311 private:
9312 static const int kStackSize = 32;
9313 // Use a mask instead of doing modulo operations for stack wrapping.
9314 static const int kDepthMask = kStackSize-1;
9315 STATIC_ASSERT(IS_POWER_OF_TWO(kStackSize));
9316 static inline int OffsetForDepth(int depth);
9317
9318 inline void PushLeft(ConsString* string);
9319 inline void PushRight(ConsString* string);
9320 inline void AdjustMaximumDepth();
9321 inline void Pop();
9322 inline bool StackBlown() { return maximum_depth_ - depth_ == kStackSize; }
9323 void Initialize(ConsString* cons_string, int offset);
9324 String* Continue(int* offset_out);
9325 String* NextLeaf(bool* blew_stack);
9326 String* Search(int* offset_out);
9327
9328 // Stack must always contain only frames for which right traversal
9329 // has not yet been performed.
9330 ConsString* frames_[kStackSize];
9331 ConsString* root_;
9332 int depth_;
9333 int maximum_depth_;
9334 int consumed_;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04009335 DISALLOW_COPY_AND_ASSIGN(ConsStringIterator);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009336};
9337
9338
9339class StringCharacterStream {
9340 public:
9341 inline StringCharacterStream(String* string,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009342 int offset = 0);
9343 inline uint16_t GetNext();
9344 inline bool HasMore();
9345 inline void Reset(String* string, int offset = 0);
9346 inline void VisitOneByteString(const uint8_t* chars, int length);
9347 inline void VisitTwoByteString(const uint16_t* chars, int length);
9348
9349 private:
Emily Bernierd0a1eb72015-03-24 16:35:39 -04009350 ConsStringIterator iter_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009351 bool is_one_byte_;
9352 union {
9353 const uint8_t* buffer8_;
9354 const uint16_t* buffer16_;
9355 };
9356 const uint8_t* end_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009357 DISALLOW_COPY_AND_ASSIGN(StringCharacterStream);
Steve Blocka7e24c12009-10-30 11:49:00 +00009358};
9359
9360
9361template <typename T>
9362class VectorIterator {
9363 public:
9364 VectorIterator(T* d, int l) : data_(Vector<const T>(d, l)), index_(0) { }
9365 explicit VectorIterator(Vector<const T> data) : data_(data), index_(0) { }
9366 T GetNext() { return data_[index_++]; }
9367 bool has_more() { return index_ < data_.length(); }
9368 private:
9369 Vector<const T> data_;
9370 int index_;
9371};
9372
9373
9374// The Oddball describes objects null, undefined, true, and false.
9375class Oddball: public HeapObject {
9376 public:
9377 // [to_string]: Cached to_string computed at startup.
9378 DECL_ACCESSORS(to_string, String)
9379
9380 // [to_number]: Cached to_number computed at startup.
9381 DECL_ACCESSORS(to_number, Object)
9382
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009383 // [typeof]: Cached type_of computed at startup.
9384 DECL_ACCESSORS(type_of, String)
9385
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009386 inline byte kind() const;
Steve Block44f0eee2011-05-26 01:26:41 +01009387 inline void set_kind(byte kind);
9388
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009389 // ES6 section 7.1.3 ToNumber for Boolean, Null, Undefined.
9390 MUST_USE_RESULT static inline Handle<Object> ToNumber(Handle<Oddball> input);
9391
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009392 DECLARE_CAST(Oddball)
Steve Blocka7e24c12009-10-30 11:49:00 +00009393
9394 // Dispatched behavior.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009395 DECLARE_VERIFIER(Oddball)
Steve Blocka7e24c12009-10-30 11:49:00 +00009396
9397 // Initialize the fields.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009398 static void Initialize(Isolate* isolate, Handle<Oddball> oddball,
9399 const char* to_string, Handle<Object> to_number,
9400 const char* type_of, byte kind);
Steve Blocka7e24c12009-10-30 11:49:00 +00009401
9402 // Layout description.
9403 static const int kToStringOffset = HeapObject::kHeaderSize;
9404 static const int kToNumberOffset = kToStringOffset + kPointerSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009405 static const int kTypeOfOffset = kToNumberOffset + kPointerSize;
9406 static const int kKindOffset = kTypeOfOffset + kPointerSize;
Steve Block44f0eee2011-05-26 01:26:41 +01009407 static const int kSize = kKindOffset + kPointerSize;
9408
9409 static const byte kFalse = 0;
9410 static const byte kTrue = 1;
9411 static const byte kNotBooleanMask = ~1;
9412 static const byte kTheHole = 2;
9413 static const byte kNull = 3;
9414 static const byte kArgumentMarker = 4;
9415 static const byte kUndefined = 5;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009416 static const byte kUninitialized = 6;
9417 static const byte kOther = 7;
9418 static const byte kException = 8;
Steve Blocka7e24c12009-10-30 11:49:00 +00009419
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009420 typedef FixedBodyDescriptor<kToStringOffset, kTypeOfOffset + kPointerSize,
Iain Merrick75681382010-08-19 15:07:18 +01009421 kSize> BodyDescriptor;
9422
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009423 STATIC_ASSERT(kKindOffset == Internals::kOddballKindOffset);
9424 STATIC_ASSERT(kNull == Internals::kNullOddballKind);
9425 STATIC_ASSERT(kUndefined == Internals::kUndefinedOddballKind);
9426
Steve Blocka7e24c12009-10-30 11:49:00 +00009427 private:
9428 DISALLOW_IMPLICIT_CONSTRUCTORS(Oddball);
9429};
9430
9431
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009432class Cell: public HeapObject {
Steve Blocka7e24c12009-10-30 11:49:00 +00009433 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009434 // [value]: value of the cell.
Steve Blocka7e24c12009-10-30 11:49:00 +00009435 DECL_ACCESSORS(value, Object)
9436
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009437 DECLARE_CAST(Cell)
Steve Blocka7e24c12009-10-30 11:49:00 +00009438
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009439 static inline Cell* FromValueAddress(Address value) {
9440 Object* result = FromAddress(value - kValueOffset);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009441 return static_cast<Cell*>(result);
Ben Murdochb0fe1622011-05-05 13:52:32 +01009442 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009443
9444 inline Address ValueAddress() {
9445 return address() + kValueOffset;
9446 }
9447
9448 // Dispatched behavior.
9449 DECLARE_PRINTER(Cell)
9450 DECLARE_VERIFIER(Cell)
Steve Blocka7e24c12009-10-30 11:49:00 +00009451
9452 // Layout description.
9453 static const int kValueOffset = HeapObject::kHeaderSize;
9454 static const int kSize = kValueOffset + kPointerSize;
9455
Iain Merrick75681382010-08-19 15:07:18 +01009456 typedef FixedBodyDescriptor<kValueOffset,
9457 kValueOffset + kPointerSize,
9458 kSize> BodyDescriptor;
9459
Steve Blocka7e24c12009-10-30 11:49:00 +00009460 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009461 DISALLOW_IMPLICIT_CONSTRUCTORS(Cell);
9462};
9463
9464
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009465class PropertyCell : public HeapObject {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009466 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009467 // [property_details]: details of the global property.
9468 DECL_ACCESSORS(property_details_raw, Object)
9469 // [value]: value of the global property.
9470 DECL_ACCESSORS(value, Object)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009471 // [dependent_code]: dependent code that depends on the type of the global
9472 // property.
9473 DECL_ACCESSORS(dependent_code, DependentCode)
9474
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009475 inline PropertyDetails property_details();
9476 inline void set_property_details(PropertyDetails details);
9477
9478 PropertyCellConstantType GetConstantType();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009479
9480 // Computes the new type of the cell's contents for the given value, but
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009481 // without actually modifying the details.
9482 static PropertyCellType UpdatedType(Handle<PropertyCell> cell,
9483 Handle<Object> value,
9484 PropertyDetails details);
9485 static void UpdateCell(Handle<GlobalDictionary> dictionary, int entry,
9486 Handle<Object> value, PropertyDetails details);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009487
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009488 static Handle<PropertyCell> InvalidateEntry(
9489 Handle<GlobalDictionary> dictionary, int entry);
9490
9491 static void SetValueWithInvalidation(Handle<PropertyCell> cell,
9492 Handle<Object> new_value);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009493
9494 DECLARE_CAST(PropertyCell)
9495
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009496 // Dispatched behavior.
9497 DECLARE_PRINTER(PropertyCell)
9498 DECLARE_VERIFIER(PropertyCell)
9499
9500 // Layout description.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009501 static const int kDetailsOffset = HeapObject::kHeaderSize;
9502 static const int kValueOffset = kDetailsOffset + kPointerSize;
9503 static const int kDependentCodeOffset = kValueOffset + kPointerSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009504 static const int kSize = kDependentCodeOffset + kPointerSize;
9505
9506 static const int kPointerFieldsBeginOffset = kValueOffset;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009507 static const int kPointerFieldsEndOffset = kSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009508
9509 typedef FixedBodyDescriptor<kValueOffset,
9510 kSize,
9511 kSize> BodyDescriptor;
9512
9513 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009514 DISALLOW_IMPLICIT_CONSTRUCTORS(PropertyCell);
Steve Blocka7e24c12009-10-30 11:49:00 +00009515};
9516
9517
Emily Bernierd0a1eb72015-03-24 16:35:39 -04009518class WeakCell : public HeapObject {
9519 public:
9520 inline Object* value() const;
9521
9522 // This should not be called by anyone except GC.
9523 inline void clear();
9524
9525 // This should not be called by anyone except allocator.
9526 inline void initialize(HeapObject* value);
9527
9528 inline bool cleared() const;
9529
9530 DECL_ACCESSORS(next, Object)
9531
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009532 inline void clear_next(Object* the_hole_value);
9533
9534 inline bool next_cleared();
9535
Emily Bernierd0a1eb72015-03-24 16:35:39 -04009536 DECLARE_CAST(WeakCell)
9537
9538 DECLARE_PRINTER(WeakCell)
9539 DECLARE_VERIFIER(WeakCell)
9540
9541 // Layout description.
9542 static const int kValueOffset = HeapObject::kHeaderSize;
9543 static const int kNextOffset = kValueOffset + kPointerSize;
9544 static const int kSize = kNextOffset + kPointerSize;
9545
9546 typedef FixedBodyDescriptor<kValueOffset, kSize, kSize> BodyDescriptor;
9547
9548 private:
9549 DISALLOW_IMPLICIT_CONSTRUCTORS(WeakCell);
9550};
9551
9552
Ben Murdoch257744e2011-11-30 15:57:28 +00009553// The JSProxy describes EcmaScript Harmony proxies
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00009554class JSProxy: public JSReceiver {
Steve Blocka7e24c12009-10-30 11:49:00 +00009555 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009556 MUST_USE_RESULT static MaybeHandle<JSProxy> New(Isolate* isolate,
9557 Handle<Object>,
9558 Handle<Object>);
9559
Ben Murdoch257744e2011-11-30 15:57:28 +00009560 // [handler]: The handler property.
9561 DECL_ACCESSORS(handler, Object)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009562 // [target]: The target property.
9563 DECL_ACCESSORS(target, JSReceiver)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01009564 // [hash]: The hash code property (undefined if not initialized yet).
9565 DECL_ACCESSORS(hash, Object)
9566
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009567 static MaybeHandle<Context> GetFunctionRealm(Handle<JSProxy> proxy);
9568
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009569 DECLARE_CAST(JSProxy)
Steve Blocka7e24c12009-10-30 11:49:00 +00009570
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009571 INLINE(bool IsRevoked() const);
9572 static void Revoke(Handle<JSProxy> proxy);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00009573
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009574 // ES6 9.5.1
9575 static MaybeHandle<Object> GetPrototype(Handle<JSProxy> receiver);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01009576
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009577 // ES6 9.5.2
9578 MUST_USE_RESULT static Maybe<bool> SetPrototype(Handle<JSProxy> proxy,
9579 Handle<Object> value,
9580 bool from_javascript,
9581 ShouldThrow should_throw);
9582 // ES6 9.5.3
9583 MUST_USE_RESULT static Maybe<bool> IsExtensible(Handle<JSProxy> proxy);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00009584
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009585 // ES6 9.5.4 (when passed DONT_THROW)
9586 MUST_USE_RESULT static Maybe<bool> PreventExtensions(
9587 Handle<JSProxy> proxy, ShouldThrow should_throw);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00009588
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009589 // ES6 9.5.5
9590 MUST_USE_RESULT static Maybe<bool> GetOwnPropertyDescriptor(
9591 Isolate* isolate, Handle<JSProxy> proxy, Handle<Name> name,
9592 PropertyDescriptor* desc);
Ben Murdoch589d6972011-11-30 16:04:58 +00009593
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009594 // ES6 9.5.6
9595 MUST_USE_RESULT static Maybe<bool> DefineOwnProperty(
9596 Isolate* isolate, Handle<JSProxy> object, Handle<Object> key,
9597 PropertyDescriptor* desc, ShouldThrow should_throw);
9598
9599 // ES6 9.5.7
9600 MUST_USE_RESULT static Maybe<bool> HasProperty(Isolate* isolate,
9601 Handle<JSProxy> proxy,
9602 Handle<Name> name);
9603
9604 // ES6 9.5.8
9605 MUST_USE_RESULT static MaybeHandle<Object> GetProperty(
9606 Isolate* isolate, Handle<JSProxy> proxy, Handle<Name> name,
9607 Handle<Object> receiver, LanguageMode language_mode);
9608
9609 // ES6 9.5.9
9610 MUST_USE_RESULT static Maybe<bool> SetProperty(Handle<JSProxy> proxy,
9611 Handle<Name> name,
9612 Handle<Object> value,
9613 Handle<Object> receiver,
9614 LanguageMode language_mode);
9615
9616 // ES6 9.5.10 (when passed SLOPPY)
9617 MUST_USE_RESULT static Maybe<bool> DeletePropertyOrElement(
9618 Handle<JSProxy> proxy, Handle<Name> name, LanguageMode language_mode);
9619
9620 // ES6 9.5.11
9621 MUST_USE_RESULT static Maybe<bool> Enumerate(Isolate* isolate,
9622 Handle<JSReceiver> receiver,
9623 Handle<JSProxy> proxy,
9624 KeyAccumulator* accumulator);
9625
9626 // ES6 9.5.12
9627 MUST_USE_RESULT static Maybe<bool> OwnPropertyKeys(
9628 Isolate* isolate, Handle<JSReceiver> receiver, Handle<JSProxy> proxy,
9629 PropertyFilter filter, KeyAccumulator* accumulator);
9630
9631 MUST_USE_RESULT static Maybe<PropertyAttributes> GetPropertyAttributes(
9632 LookupIterator* it);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01009633
Steve Blocka7e24c12009-10-30 11:49:00 +00009634 // Dispatched behavior.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009635 DECLARE_PRINTER(JSProxy)
9636 DECLARE_VERIFIER(JSProxy)
Ben Murdoch257744e2011-11-30 15:57:28 +00009637
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009638 // Layout description.
9639 static const int kTargetOffset = JSReceiver::kHeaderSize;
9640 static const int kHandlerOffset = kTargetOffset + kPointerSize;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01009641 static const int kHashOffset = kHandlerOffset + kPointerSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009642 static const int kSize = kHashOffset + kPointerSize;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00009643
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009644 typedef FixedBodyDescriptor<JSReceiver::kPropertiesOffset, kSize, kSize>
9645 BodyDescriptor;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009646
9647 MUST_USE_RESULT Object* GetIdentityHash();
9648
9649 static Handle<Smi> GetOrCreateIdentityHash(Handle<JSProxy> proxy);
9650
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00009651 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009652 static Maybe<bool> AddPrivateProperty(Isolate* isolate, Handle<JSProxy> proxy,
9653 Handle<Symbol> private_name,
9654 PropertyDescriptor* desc,
9655 ShouldThrow should_throw);
9656
9657 DISALLOW_IMPLICIT_CONSTRUCTORS(JSProxy);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00009658};
9659
Ben Murdoch257744e2011-11-30 15:57:28 +00009660
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009661class JSCollection : public JSObject {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01009662 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009663 // [table]: the backing hash table
Ben Murdoch3ef787d2012-04-12 10:51:47 +01009664 DECL_ACCESSORS(table, Object)
9665
Ben Murdoch3ef787d2012-04-12 10:51:47 +01009666 static const int kTableOffset = JSObject::kHeaderSize;
9667 static const int kSize = kTableOffset + kPointerSize;
9668
9669 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009670 DISALLOW_IMPLICIT_CONSTRUCTORS(JSCollection);
9671};
9672
9673
9674// The JSSet describes EcmaScript Harmony sets
9675class JSSet : public JSCollection {
9676 public:
9677 DECLARE_CAST(JSSet)
9678
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009679 static void Initialize(Handle<JSSet> set, Isolate* isolate);
9680 static void Clear(Handle<JSSet> set);
9681
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009682 // Dispatched behavior.
9683 DECLARE_PRINTER(JSSet)
9684 DECLARE_VERIFIER(JSSet)
9685
9686 private:
Ben Murdoch3ef787d2012-04-12 10:51:47 +01009687 DISALLOW_IMPLICIT_CONSTRUCTORS(JSSet);
9688};
9689
9690
9691// The JSMap describes EcmaScript Harmony maps
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009692class JSMap : public JSCollection {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01009693 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009694 DECLARE_CAST(JSMap)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01009695
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009696 static void Initialize(Handle<JSMap> map, Isolate* isolate);
9697 static void Clear(Handle<JSMap> map);
9698
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009699 // Dispatched behavior.
9700 DECLARE_PRINTER(JSMap)
9701 DECLARE_VERIFIER(JSMap)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01009702
9703 private:
9704 DISALLOW_IMPLICIT_CONSTRUCTORS(JSMap);
9705};
9706
9707
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009708// OrderedHashTableIterator is an iterator that iterates over the keys and
9709// values of an OrderedHashTable.
9710//
9711// The iterator has a reference to the underlying OrderedHashTable data,
9712// [table], as well as the current [index] the iterator is at.
9713//
9714// When the OrderedHashTable is rehashed it adds a reference from the old table
9715// to the new table as well as storing enough data about the changes so that the
9716// iterator [index] can be adjusted accordingly.
9717//
9718// When the [Next] result from the iterator is requested, the iterator checks if
9719// there is a newer table that it needs to transition to.
9720template<class Derived, class TableType>
9721class OrderedHashTableIterator: public JSObject {
9722 public:
9723 // [table]: the backing hash table mapping keys to values.
9724 DECL_ACCESSORS(table, Object)
9725
9726 // [index]: The index into the data table.
9727 DECL_ACCESSORS(index, Object)
9728
9729 // [kind]: The kind of iteration this is. One of the [Kind] enum values.
9730 DECL_ACCESSORS(kind, Object)
9731
9732#ifdef OBJECT_PRINT
Emily Bernierd0a1eb72015-03-24 16:35:39 -04009733 void OrderedHashTableIteratorPrint(std::ostream& os); // NOLINT
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009734#endif
9735
9736 static const int kTableOffset = JSObject::kHeaderSize;
9737 static const int kIndexOffset = kTableOffset + kPointerSize;
9738 static const int kKindOffset = kIndexOffset + kPointerSize;
9739 static const int kSize = kKindOffset + kPointerSize;
9740
9741 enum Kind {
9742 kKindKeys = 1,
9743 kKindValues = 2,
9744 kKindEntries = 3
9745 };
9746
9747 // Whether the iterator has more elements. This needs to be called before
9748 // calling |CurrentKey| and/or |CurrentValue|.
9749 bool HasMore();
9750
9751 // Move the index forward one.
9752 void MoveNext() {
9753 set_index(Smi::FromInt(Smi::cast(index())->value() + 1));
9754 }
9755
9756 // Populates the array with the next key and value and then moves the iterator
9757 // forward.
9758 // This returns the |kind| or 0 if the iterator is already at the end.
9759 Smi* Next(JSArray* value_array);
9760
9761 // Returns the current key of the iterator. This should only be called when
9762 // |HasMore| returns true.
9763 inline Object* CurrentKey();
9764
9765 private:
9766 // Transitions the iterator to the non obsolete backing store. This is a NOP
9767 // if the [table] is not obsolete.
9768 void Transition();
9769
9770 DISALLOW_IMPLICIT_CONSTRUCTORS(OrderedHashTableIterator);
9771};
9772
9773
9774class JSSetIterator: public OrderedHashTableIterator<JSSetIterator,
9775 OrderedHashSet> {
9776 public:
9777 // Dispatched behavior.
9778 DECLARE_PRINTER(JSSetIterator)
9779 DECLARE_VERIFIER(JSSetIterator)
9780
9781 DECLARE_CAST(JSSetIterator)
9782
9783 // Called by |Next| to populate the array. This allows the subclasses to
9784 // populate the array differently.
9785 inline void PopulateValueArray(FixedArray* array);
9786
9787 private:
9788 DISALLOW_IMPLICIT_CONSTRUCTORS(JSSetIterator);
9789};
9790
9791
9792class JSMapIterator: public OrderedHashTableIterator<JSMapIterator,
9793 OrderedHashMap> {
9794 public:
9795 // Dispatched behavior.
9796 DECLARE_PRINTER(JSMapIterator)
9797 DECLARE_VERIFIER(JSMapIterator)
9798
9799 DECLARE_CAST(JSMapIterator)
9800
9801 // Called by |Next| to populate the array. This allows the subclasses to
9802 // populate the array differently.
9803 inline void PopulateValueArray(FixedArray* array);
9804
9805 private:
9806 // Returns the current value of the iterator. This should only be called when
9807 // |HasMore| returns true.
9808 inline Object* CurrentValue();
9809
9810 DISALLOW_IMPLICIT_CONSTRUCTORS(JSMapIterator);
9811};
9812
9813
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009814// ES6 section 25.1.1.3 The IteratorResult Interface
9815class JSIteratorResult final : public JSObject {
9816 public:
9817 // [done]: This is the result status of an iterator next method call. If the
9818 // end of the iterator was reached done is true. If the end was not reached
9819 // done is false and a [value] is available.
9820 DECL_ACCESSORS(done, Object)
9821
9822 // [value]: If [done] is false, this is the current iteration element value.
9823 // If [done] is true, this is the return value of the iterator, if it supplied
9824 // one. If the iterator does not have a return value, value is undefined.
9825 // In that case, the value property may be absent from the conforming object
9826 // if it does not inherit an explicit value property.
9827 DECL_ACCESSORS(value, Object)
9828
9829 // Dispatched behavior.
9830 DECLARE_PRINTER(JSIteratorResult)
9831 DECLARE_VERIFIER(JSIteratorResult)
9832
9833 DECLARE_CAST(JSIteratorResult)
9834
9835 static const int kValueOffset = JSObject::kHeaderSize;
9836 static const int kDoneOffset = kValueOffset + kPointerSize;
9837 static const int kSize = kDoneOffset + kPointerSize;
9838
9839 // Indices of in-object properties.
9840 static const int kValueIndex = 0;
9841 static const int kDoneIndex = 1;
9842
9843 private:
9844 DISALLOW_IMPLICIT_CONSTRUCTORS(JSIteratorResult);
9845};
9846
9847
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009848// Base class for both JSWeakMap and JSWeakSet
9849class JSWeakCollection: public JSObject {
Ben Murdoch69a99ed2011-11-30 16:03:39 +00009850 public:
9851 // [table]: the backing hash table mapping keys to values.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01009852 DECL_ACCESSORS(table, Object)
Ben Murdoch69a99ed2011-11-30 16:03:39 +00009853
9854 // [next]: linked list of encountered weak maps during GC.
9855 DECL_ACCESSORS(next, Object)
9856
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009857 static void Initialize(Handle<JSWeakCollection> collection, Isolate* isolate);
9858 static void Set(Handle<JSWeakCollection> collection, Handle<Object> key,
9859 Handle<Object> value, int32_t hash);
9860 static bool Delete(Handle<JSWeakCollection> collection, Handle<Object> key,
9861 int32_t hash);
9862
Ben Murdoch69a99ed2011-11-30 16:03:39 +00009863 static const int kTableOffset = JSObject::kHeaderSize;
9864 static const int kNextOffset = kTableOffset + kPointerSize;
9865 static const int kSize = kNextOffset + kPointerSize;
9866
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009867 // Visiting policy defines whether the table and next collection fields
9868 // should be visited or not.
9869 enum BodyVisitingPolicy { kVisitStrong, kVisitWeak };
9870
9871 // Iterates the function object according to the visiting policy.
9872 template <BodyVisitingPolicy>
9873 class BodyDescriptorImpl;
9874
9875 // Visit the whole object.
9876 typedef BodyDescriptorImpl<kVisitStrong> BodyDescriptor;
9877
9878 // Don't visit table and next collection fields.
9879 typedef BodyDescriptorImpl<kVisitWeak> BodyDescriptorWeak;
9880
Ben Murdoch69a99ed2011-11-30 16:03:39 +00009881 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009882 DISALLOW_IMPLICIT_CONSTRUCTORS(JSWeakCollection);
9883};
9884
9885
9886// The JSWeakMap describes EcmaScript Harmony weak maps
9887class JSWeakMap: public JSWeakCollection {
9888 public:
9889 DECLARE_CAST(JSWeakMap)
9890
9891 // Dispatched behavior.
9892 DECLARE_PRINTER(JSWeakMap)
9893 DECLARE_VERIFIER(JSWeakMap)
9894
9895 private:
Ben Murdoch69a99ed2011-11-30 16:03:39 +00009896 DISALLOW_IMPLICIT_CONSTRUCTORS(JSWeakMap);
9897};
9898
9899
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009900// The JSWeakSet describes EcmaScript Harmony weak sets
9901class JSWeakSet: public JSWeakCollection {
9902 public:
9903 DECLARE_CAST(JSWeakSet)
9904
9905 // Dispatched behavior.
9906 DECLARE_PRINTER(JSWeakSet)
9907 DECLARE_VERIFIER(JSWeakSet)
9908
9909 private:
9910 DISALLOW_IMPLICIT_CONSTRUCTORS(JSWeakSet);
9911};
9912
9913
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009914// Whether a JSArrayBuffer is a SharedArrayBuffer or not.
9915enum class SharedFlag { kNotShared, kShared };
9916
9917
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009918class JSArrayBuffer: public JSObject {
9919 public:
9920 // [backing_store]: backing memory for this array
9921 DECL_ACCESSORS(backing_store, void)
9922
9923 // [byte_length]: length in bytes
9924 DECL_ACCESSORS(byte_length, Object)
9925
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009926 inline uint32_t bit_field() const;
9927 inline void set_bit_field(uint32_t bits);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009928
9929 inline bool is_external();
9930 inline void set_is_external(bool value);
9931
Emily Bernierd0a1eb72015-03-24 16:35:39 -04009932 inline bool is_neuterable();
9933 inline void set_is_neuterable(bool value);
9934
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009935 inline bool was_neutered();
9936 inline void set_was_neutered(bool value);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009937
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009938 inline bool is_shared();
9939 inline void set_is_shared(bool value);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009940
9941 DECLARE_CAST(JSArrayBuffer)
9942
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009943 void Neuter();
9944
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009945 static void Setup(Handle<JSArrayBuffer> array_buffer, Isolate* isolate,
9946 bool is_external, void* data, size_t allocated_length,
9947 SharedFlag shared = SharedFlag::kNotShared);
9948
9949 static bool SetupAllocatingData(Handle<JSArrayBuffer> array_buffer,
9950 Isolate* isolate, size_t allocated_length,
9951 bool initialize = true,
9952 SharedFlag shared = SharedFlag::kNotShared);
9953
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009954 // Dispatched behavior.
9955 DECLARE_PRINTER(JSArrayBuffer)
9956 DECLARE_VERIFIER(JSArrayBuffer)
9957
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009958 static const int kByteLengthOffset = JSObject::kHeaderSize;
9959 static const int kBackingStoreOffset = kByteLengthOffset + kPointerSize;
9960 static const int kBitFieldSlot = kBackingStoreOffset + kPointerSize;
9961#if V8_TARGET_LITTLE_ENDIAN || !V8_HOST_ARCH_64_BIT
9962 static const int kBitFieldOffset = kBitFieldSlot;
9963#else
9964 static const int kBitFieldOffset = kBitFieldSlot + kIntSize;
9965#endif
9966 static const int kSize = kBitFieldSlot + kPointerSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009967
9968 static const int kSizeWithInternalFields =
9969 kSize + v8::ArrayBuffer::kInternalFieldCount * kPointerSize;
9970
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009971 // Iterates all fields in the object including internal ones except
9972 // kBackingStoreOffset and kBitFieldSlot.
9973 class BodyDescriptor;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009974
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009975 class IsExternal : public BitField<bool, 1, 1> {};
9976 class IsNeuterable : public BitField<bool, 2, 1> {};
9977 class WasNeutered : public BitField<bool, 3, 1> {};
9978 class IsShared : public BitField<bool, 4, 1> {};
9979
9980 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009981 DISALLOW_IMPLICIT_CONSTRUCTORS(JSArrayBuffer);
9982};
9983
9984
9985class JSArrayBufferView: public JSObject {
9986 public:
9987 // [buffer]: ArrayBuffer that this typed array views.
9988 DECL_ACCESSORS(buffer, Object)
9989
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009990 // [byte_offset]: offset of typed array in bytes.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009991 DECL_ACCESSORS(byte_offset, Object)
9992
9993 // [byte_length]: length of typed array in bytes.
9994 DECL_ACCESSORS(byte_length, Object)
9995
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009996 DECLARE_CAST(JSArrayBufferView)
9997
9998 DECLARE_VERIFIER(JSArrayBufferView)
9999
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010000 inline bool WasNeutered() const;
10001
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010002 static const int kBufferOffset = JSObject::kHeaderSize;
10003 static const int kByteOffsetOffset = kBufferOffset + kPointerSize;
10004 static const int kByteLengthOffset = kByteOffsetOffset + kPointerSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010005 static const int kViewSize = kByteLengthOffset + kPointerSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010006
10007 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010008#ifdef VERIFY_HEAP
10009 DECL_ACCESSORS(raw_byte_offset, Object)
10010 DECL_ACCESSORS(raw_byte_length, Object)
10011#endif
10012
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010013 DISALLOW_IMPLICIT_CONSTRUCTORS(JSArrayBufferView);
10014};
10015
10016
10017class JSTypedArray: public JSArrayBufferView {
10018 public:
10019 // [length]: length of typed array in elements.
10020 DECL_ACCESSORS(length, Object)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010021 inline uint32_t length_value() const;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010022
10023 DECLARE_CAST(JSTypedArray)
10024
10025 ExternalArrayType type();
10026 size_t element_size();
10027
10028 Handle<JSArrayBuffer> GetBuffer();
10029
10030 // Dispatched behavior.
10031 DECLARE_PRINTER(JSTypedArray)
10032 DECLARE_VERIFIER(JSTypedArray)
10033
10034 static const int kLengthOffset = kViewSize + kPointerSize;
10035 static const int kSize = kLengthOffset + kPointerSize;
10036
10037 static const int kSizeWithInternalFields =
10038 kSize + v8::ArrayBufferView::kInternalFieldCount * kPointerSize;
10039
10040 private:
10041 static Handle<JSArrayBuffer> MaterializeArrayBuffer(
10042 Handle<JSTypedArray> typed_array);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010043#ifdef VERIFY_HEAP
10044 DECL_ACCESSORS(raw_length, Object)
10045#endif
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010046
10047 DISALLOW_IMPLICIT_CONSTRUCTORS(JSTypedArray);
10048};
10049
10050
10051class JSDataView: public JSArrayBufferView {
10052 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010053 DECLARE_CAST(JSDataView)
10054
10055 // Dispatched behavior.
10056 DECLARE_PRINTER(JSDataView)
10057 DECLARE_VERIFIER(JSDataView)
10058
10059 static const int kSize = kViewSize;
10060
10061 static const int kSizeWithInternalFields =
10062 kSize + v8::ArrayBufferView::kInternalFieldCount * kPointerSize;
10063
10064 private:
10065 DISALLOW_IMPLICIT_CONSTRUCTORS(JSDataView);
10066};
10067
10068
Ben Murdoch257744e2011-11-30 15:57:28 +000010069// Foreign describes objects pointing from JavaScript to C structures.
Ben Murdoch257744e2011-11-30 15:57:28 +000010070class Foreign: public HeapObject {
10071 public:
10072 // [address]: field containing the address.
Ben Murdoch3ef787d2012-04-12 10:51:47 +010010073 inline Address foreign_address();
10074 inline void set_foreign_address(Address value);
Ben Murdoch257744e2011-11-30 15:57:28 +000010075
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010076 DECLARE_CAST(Foreign)
Ben Murdoch257744e2011-11-30 15:57:28 +000010077
10078 // Dispatched behavior.
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010079 DECLARE_PRINTER(Foreign)
10080 DECLARE_VERIFIER(Foreign)
Steve Blocka7e24c12009-10-30 11:49:00 +000010081
10082 // Layout description.
10083
Ben Murdoch3ef787d2012-04-12 10:51:47 +010010084 static const int kForeignAddressOffset = HeapObject::kHeaderSize;
10085 static const int kSize = kForeignAddressOffset + kPointerSize;
Steve Blocka7e24c12009-10-30 11:49:00 +000010086
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010087 STATIC_ASSERT(kForeignAddressOffset == Internals::kForeignAddressOffset);
Steve Blocka7e24c12009-10-30 11:49:00 +000010088
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010089 class BodyDescriptor;
10090
Steve Blocka7e24c12009-10-30 11:49:00 +000010091 private:
Ben Murdoch257744e2011-11-30 15:57:28 +000010092 DISALLOW_IMPLICIT_CONSTRUCTORS(Foreign);
Steve Blocka7e24c12009-10-30 11:49:00 +000010093};
10094
10095
10096// The JSArray describes JavaScript Arrays
10097// Such an array can be in one of two modes:
10098// - fast, backing storage is a FixedArray and length <= elements.length();
10099// Please note: push and pop can be used to grow and shrink the array.
10100// - slow, backing storage is a HashTable with numbers as keys.
10101class JSArray: public JSObject {
10102 public:
10103 // [length]: The length property.
10104 DECL_ACCESSORS(length, Object)
10105
Leon Clarke4515c472010-02-03 11:58:03 +000010106 // Overload the length setter to skip write barrier when the length
10107 // is set to a smi. This matches the set function on FixedArray.
10108 inline void set_length(Smi* length);
10109
Emily Bernierd0a1eb72015-03-24 16:35:39 -040010110 static bool HasReadOnlyLength(Handle<JSArray> array);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010111 static bool WouldChangeReadOnlyLength(Handle<JSArray> array, uint32_t index);
Emily Bernierd0a1eb72015-03-24 16:35:39 -040010112
Steve Blocka7e24c12009-10-30 11:49:00 +000010113 // Initialize the array with the given capacity. The function may
10114 // fail due to out-of-memory situations, but only if the requested
10115 // capacity is non-zero.
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010116 static void Initialize(Handle<JSArray> array, int capacity, int length = 0);
Steve Blocka7e24c12009-10-30 11:49:00 +000010117
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010118 // If the JSArray has fast elements, and new_length would result in
10119 // normalization, returns true.
10120 bool SetLengthWouldNormalize(uint32_t new_length);
10121 static inline bool SetLengthWouldNormalize(Heap* heap, uint32_t new_length);
10122
Ben Murdoch3ef787d2012-04-12 10:51:47 +010010123 // Initializes the array to a certain length.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010124 inline bool AllowsSetLength();
10125
10126 static void SetLength(Handle<JSArray> array, uint32_t length);
10127 // Same as above but will also queue splice records if |array| is observed.
10128 static MaybeHandle<Object> ObservableSetLength(Handle<JSArray> array,
10129 uint32_t length);
Ben Murdoch3ef787d2012-04-12 10:51:47 +010010130
Steve Blocka7e24c12009-10-30 11:49:00 +000010131 // Set the content of the array to the content of storage.
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010132 static inline void SetContent(Handle<JSArray> array,
10133 Handle<FixedArrayBase> storage);
Steve Blocka7e24c12009-10-30 11:49:00 +000010134
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010135 // ES6 9.4.2.1
10136 MUST_USE_RESULT static Maybe<bool> DefineOwnProperty(
10137 Isolate* isolate, Handle<JSArray> o, Handle<Object> name,
10138 PropertyDescriptor* desc, ShouldThrow should_throw);
10139
10140 static bool AnythingToArrayLength(Isolate* isolate,
10141 Handle<Object> length_object,
10142 uint32_t* output);
10143 MUST_USE_RESULT static Maybe<bool> ArraySetLength(Isolate* isolate,
10144 Handle<JSArray> a,
10145 PropertyDescriptor* desc,
10146 ShouldThrow should_throw);
10147
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010148 DECLARE_CAST(JSArray)
Steve Blocka7e24c12009-10-30 11:49:00 +000010149
Steve Blocka7e24c12009-10-30 11:49:00 +000010150 // Dispatched behavior.
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010151 DECLARE_PRINTER(JSArray)
10152 DECLARE_VERIFIER(JSArray)
Steve Blocka7e24c12009-10-30 11:49:00 +000010153
10154 // Number of element slots to pre-allocate for an empty array.
10155 static const int kPreallocatedArrayElements = 4;
10156
10157 // Layout description.
10158 static const int kLengthOffset = JSObject::kHeaderSize;
10159 static const int kSize = kLengthOffset + kPointerSize;
10160
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010161 // 600 * KB is the Page::kMaxRegularHeapObjectSize defined in spaces.h which
10162 // we do not want to include in objects.h
10163 // Note that Page::kMaxRegularHeapObjectSize has to be in sync with
10164 // kInitialMaxFastElementArray which is checked in a DCHECK in heap.cc.
10165 static const int kInitialMaxFastElementArray =
10166 (600 * KB - FixedArray::kHeaderSize - kSize - AllocationMemento::kSize) /
10167 kPointerSize;
10168
Steve Blocka7e24c12009-10-30 11:49:00 +000010169 private:
Steve Blocka7e24c12009-10-30 11:49:00 +000010170 DISALLOW_IMPLICIT_CONSTRUCTORS(JSArray);
10171};
10172
10173
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010174Handle<Object> CacheInitialJSArrayMaps(Handle<Context> native_context,
10175 Handle<Map> initial_map);
10176
10177
Steve Block6ded16b2010-05-10 14:33:55 +010010178// JSRegExpResult is just a JSArray with a specific initial map.
10179// This initial map adds in-object properties for "index" and "input"
10180// properties, as assigned by RegExp.prototype.exec, which allows
10181// faster creation of RegExp exec results.
10182// This class just holds constants used when creating the result.
10183// After creation the result must be treated as a JSArray in all regards.
10184class JSRegExpResult: public JSArray {
10185 public:
10186 // Offsets of object fields.
10187 static const int kIndexOffset = JSArray::kSize;
10188 static const int kInputOffset = kIndexOffset + kPointerSize;
10189 static const int kSize = kInputOffset + kPointerSize;
10190 // Indices of in-object properties.
10191 static const int kIndexIndex = 0;
10192 static const int kInputIndex = 1;
10193 private:
10194 DISALLOW_IMPLICIT_CONSTRUCTORS(JSRegExpResult);
10195};
10196
10197
Steve Blocka7e24c12009-10-30 11:49:00 +000010198class AccessorInfo: public Struct {
10199 public:
Steve Blocka7e24c12009-10-30 11:49:00 +000010200 DECL_ACCESSORS(name, Object)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010201 DECL_INT_ACCESSORS(flag)
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010202 DECL_ACCESSORS(expected_receiver_type, Object)
Steve Blocka7e24c12009-10-30 11:49:00 +000010203
10204 inline bool all_can_read();
10205 inline void set_all_can_read(bool value);
10206
10207 inline bool all_can_write();
10208 inline void set_all_can_write(bool value);
10209
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010210 inline bool is_special_data_property();
10211 inline void set_is_special_data_property(bool value);
10212
Steve Blocka7e24c12009-10-30 11:49:00 +000010213 inline PropertyAttributes property_attributes();
10214 inline void set_property_attributes(PropertyAttributes attributes);
10215
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010216 // Checks whether the given receiver is compatible with this accessor.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010217 static bool IsCompatibleReceiverMap(Isolate* isolate,
10218 Handle<AccessorInfo> info,
10219 Handle<Map> map);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010220 inline bool IsCompatibleReceiver(Object* receiver);
Steve Blocka7e24c12009-10-30 11:49:00 +000010221
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010222 DECLARE_CAST(AccessorInfo)
Steve Blocka7e24c12009-10-30 11:49:00 +000010223
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010224 // Dispatched behavior.
10225 DECLARE_VERIFIER(AccessorInfo)
10226
10227 // Append all descriptors to the array that are not already there.
10228 // Return number added.
10229 static int AppendUnique(Handle<Object> descriptors,
10230 Handle<FixedArray> array,
10231 int valid_descriptors);
10232
10233 static const int kNameOffset = HeapObject::kHeaderSize;
Steve Blocka7e24c12009-10-30 11:49:00 +000010234 static const int kFlagOffset = kNameOffset + kPointerSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010235 static const int kExpectedReceiverTypeOffset = kFlagOffset + kPointerSize;
10236 static const int kSize = kExpectedReceiverTypeOffset + kPointerSize;
Steve Blocka7e24c12009-10-30 11:49:00 +000010237
10238 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010239 inline bool HasExpectedReceiverType();
10240
Steve Blocka7e24c12009-10-30 11:49:00 +000010241 // Bit positions in flag.
10242 static const int kAllCanReadBit = 0;
10243 static const int kAllCanWriteBit = 1;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010244 static const int kSpecialDataProperty = 2;
10245 class AttributesField : public BitField<PropertyAttributes, 3, 3> {};
Steve Blocka7e24c12009-10-30 11:49:00 +000010246
10247 DISALLOW_IMPLICIT_CONSTRUCTORS(AccessorInfo);
10248};
10249
10250
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010251// An accessor must have a getter, but can have no setter.
10252//
10253// When setting a property, V8 searches accessors in prototypes.
10254// If an accessor was found and it does not have a setter,
10255// the request is ignored.
10256//
10257// If the accessor in the prototype has the READ_ONLY property attribute, then
10258// a new value is added to the derived object when the property is set.
10259// This shadows the accessor in the prototype.
10260class ExecutableAccessorInfo: public AccessorInfo {
10261 public:
10262 DECL_ACCESSORS(getter, Object)
10263 DECL_ACCESSORS(setter, Object)
10264 DECL_ACCESSORS(data, Object)
10265
10266 DECLARE_CAST(ExecutableAccessorInfo)
10267
10268 // Dispatched behavior.
10269 DECLARE_PRINTER(ExecutableAccessorInfo)
10270 DECLARE_VERIFIER(ExecutableAccessorInfo)
10271
10272 static const int kGetterOffset = AccessorInfo::kSize;
10273 static const int kSetterOffset = kGetterOffset + kPointerSize;
10274 static const int kDataOffset = kSetterOffset + kPointerSize;
10275 static const int kSize = kDataOffset + kPointerSize;
10276
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010277 static void ClearSetter(Handle<ExecutableAccessorInfo> info);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010278
10279 private:
10280 DISALLOW_IMPLICIT_CONSTRUCTORS(ExecutableAccessorInfo);
10281};
10282
10283
Ben Murdoch3ef787d2012-04-12 10:51:47 +010010284// Support for JavaScript accessors: A pair of a getter and a setter. Each
10285// accessor can either be
10286// * a pointer to a JavaScript function or proxy: a real accessor
10287// * undefined: considered an accessor by the spec, too, strangely enough
10288// * the hole: an accessor which has not been set
10289// * a pointer to a map: a transition used to ensure map sharing
10290class AccessorPair: public Struct {
10291 public:
10292 DECL_ACCESSORS(getter, Object)
10293 DECL_ACCESSORS(setter, Object)
10294
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010295 DECLARE_CAST(AccessorPair)
Ben Murdoch3ef787d2012-04-12 10:51:47 +010010296
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010297 static Handle<AccessorPair> Copy(Handle<AccessorPair> pair);
10298
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010299 inline Object* get(AccessorComponent component);
10300 inline void set(AccessorComponent component, Object* value);
Ben Murdoch3ef787d2012-04-12 10:51:47 +010010301
10302 // Note: Returns undefined instead in case of a hole.
10303 Object* GetComponent(AccessorComponent component);
10304
10305 // Set both components, skipping arguments which are a JavaScript null.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010306 inline void SetComponents(Object* getter, Object* setter);
Ben Murdoch3ef787d2012-04-12 10:51:47 +010010307
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010308 inline bool Equals(AccessorPair* pair);
10309 inline bool Equals(Object* getter_value, Object* setter_value);
10310
10311 inline bool ContainsAccessor();
Ben Murdoch3ef787d2012-04-12 10:51:47 +010010312
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010313 // Dispatched behavior.
10314 DECLARE_PRINTER(AccessorPair)
10315 DECLARE_VERIFIER(AccessorPair)
Ben Murdoch3ef787d2012-04-12 10:51:47 +010010316
10317 static const int kGetterOffset = HeapObject::kHeaderSize;
10318 static const int kSetterOffset = kGetterOffset + kPointerSize;
10319 static const int kSize = kSetterOffset + kPointerSize;
10320
10321 private:
10322 // Strangely enough, in addition to functions and harmony proxies, the spec
10323 // requires us to consider undefined as a kind of accessor, too:
10324 // var obj = {};
10325 // Object.defineProperty(obj, "foo", {get: undefined});
10326 // assertTrue("foo" in obj);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010327 inline bool IsJSAccessor(Object* obj);
Ben Murdoch3ef787d2012-04-12 10:51:47 +010010328
10329 DISALLOW_IMPLICIT_CONSTRUCTORS(AccessorPair);
10330};
10331
10332
Steve Blocka7e24c12009-10-30 11:49:00 +000010333class AccessCheckInfo: public Struct {
10334 public:
10335 DECL_ACCESSORS(named_callback, Object)
10336 DECL_ACCESSORS(indexed_callback, Object)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010337 DECL_ACCESSORS(callback, Object)
Steve Blocka7e24c12009-10-30 11:49:00 +000010338 DECL_ACCESSORS(data, Object)
10339
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010340 DECLARE_CAST(AccessCheckInfo)
Steve Blocka7e24c12009-10-30 11:49:00 +000010341
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010342 // Dispatched behavior.
10343 DECLARE_PRINTER(AccessCheckInfo)
10344 DECLARE_VERIFIER(AccessCheckInfo)
Steve Blocka7e24c12009-10-30 11:49:00 +000010345
10346 static const int kNamedCallbackOffset = HeapObject::kHeaderSize;
10347 static const int kIndexedCallbackOffset = kNamedCallbackOffset + kPointerSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010348 static const int kCallbackOffset = kIndexedCallbackOffset + kPointerSize;
10349 static const int kDataOffset = kCallbackOffset + kPointerSize;
Steve Blocka7e24c12009-10-30 11:49:00 +000010350 static const int kSize = kDataOffset + kPointerSize;
10351
10352 private:
10353 DISALLOW_IMPLICIT_CONSTRUCTORS(AccessCheckInfo);
10354};
10355
10356
10357class InterceptorInfo: public Struct {
10358 public:
10359 DECL_ACCESSORS(getter, Object)
10360 DECL_ACCESSORS(setter, Object)
10361 DECL_ACCESSORS(query, Object)
10362 DECL_ACCESSORS(deleter, Object)
10363 DECL_ACCESSORS(enumerator, Object)
10364 DECL_ACCESSORS(data, Object)
Emily Bernierd0a1eb72015-03-24 16:35:39 -040010365 DECL_BOOLEAN_ACCESSORS(can_intercept_symbols)
10366 DECL_BOOLEAN_ACCESSORS(all_can_read)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010367 DECL_BOOLEAN_ACCESSORS(non_masking)
Emily Bernierd0a1eb72015-03-24 16:35:39 -040010368
10369 inline int flags() const;
10370 inline void set_flags(int flags);
Steve Blocka7e24c12009-10-30 11:49:00 +000010371
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010372 DECLARE_CAST(InterceptorInfo)
Steve Blocka7e24c12009-10-30 11:49:00 +000010373
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010374 // Dispatched behavior.
10375 DECLARE_PRINTER(InterceptorInfo)
10376 DECLARE_VERIFIER(InterceptorInfo)
Steve Blocka7e24c12009-10-30 11:49:00 +000010377
10378 static const int kGetterOffset = HeapObject::kHeaderSize;
10379 static const int kSetterOffset = kGetterOffset + kPointerSize;
10380 static const int kQueryOffset = kSetterOffset + kPointerSize;
10381 static const int kDeleterOffset = kQueryOffset + kPointerSize;
10382 static const int kEnumeratorOffset = kDeleterOffset + kPointerSize;
10383 static const int kDataOffset = kEnumeratorOffset + kPointerSize;
Emily Bernierd0a1eb72015-03-24 16:35:39 -040010384 static const int kFlagsOffset = kDataOffset + kPointerSize;
10385 static const int kSize = kFlagsOffset + kPointerSize;
10386
10387 static const int kCanInterceptSymbolsBit = 0;
10388 static const int kAllCanReadBit = 1;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010389 static const int kNonMasking = 2;
Steve Blocka7e24c12009-10-30 11:49:00 +000010390
10391 private:
10392 DISALLOW_IMPLICIT_CONSTRUCTORS(InterceptorInfo);
10393};
10394
10395
10396class CallHandlerInfo: public Struct {
10397 public:
10398 DECL_ACCESSORS(callback, Object)
10399 DECL_ACCESSORS(data, Object)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010400 DECL_ACCESSORS(fast_handler, Object)
Steve Blocka7e24c12009-10-30 11:49:00 +000010401
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010402 DECLARE_CAST(CallHandlerInfo)
Steve Blocka7e24c12009-10-30 11:49:00 +000010403
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010404 // Dispatched behavior.
10405 DECLARE_PRINTER(CallHandlerInfo)
10406 DECLARE_VERIFIER(CallHandlerInfo)
Steve Blocka7e24c12009-10-30 11:49:00 +000010407
10408 static const int kCallbackOffset = HeapObject::kHeaderSize;
10409 static const int kDataOffset = kCallbackOffset + kPointerSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010410 static const int kFastHandlerOffset = kDataOffset + kPointerSize;
10411 static const int kSize = kFastHandlerOffset + kPointerSize;
Steve Blocka7e24c12009-10-30 11:49:00 +000010412
10413 private:
10414 DISALLOW_IMPLICIT_CONSTRUCTORS(CallHandlerInfo);
10415};
10416
10417
10418class TemplateInfo: public Struct {
10419 public:
10420 DECL_ACCESSORS(tag, Object)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010421 inline int number_of_properties() const;
10422 inline void set_number_of_properties(int value);
Steve Blocka7e24c12009-10-30 11:49:00 +000010423 DECL_ACCESSORS(property_list, Object)
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010424 DECL_ACCESSORS(property_accessors, Object)
Steve Blocka7e24c12009-10-30 11:49:00 +000010425
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010426 DECLARE_VERIFIER(TemplateInfo)
Steve Blocka7e24c12009-10-30 11:49:00 +000010427
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010428 static const int kTagOffset = HeapObject::kHeaderSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010429 static const int kNumberOfProperties = kTagOffset + kPointerSize;
10430 static const int kPropertyListOffset = kNumberOfProperties + kPointerSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010431 static const int kPropertyAccessorsOffset =
10432 kPropertyListOffset + kPointerSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010433 static const int kPropertyIntrinsicsOffset =
10434 kPropertyAccessorsOffset + kPointerSize;
10435 static const int kHeaderSize = kPropertyIntrinsicsOffset + kPointerSize;
Ben Murdoch3ef787d2012-04-12 10:51:47 +010010436
10437 private:
Steve Blocka7e24c12009-10-30 11:49:00 +000010438 DISALLOW_IMPLICIT_CONSTRUCTORS(TemplateInfo);
10439};
10440
10441
10442class FunctionTemplateInfo: public TemplateInfo {
10443 public:
10444 DECL_ACCESSORS(serial_number, Object)
10445 DECL_ACCESSORS(call_code, Object)
Steve Blocka7e24c12009-10-30 11:49:00 +000010446 DECL_ACCESSORS(prototype_template, Object)
10447 DECL_ACCESSORS(parent_template, Object)
10448 DECL_ACCESSORS(named_property_handler, Object)
10449 DECL_ACCESSORS(indexed_property_handler, Object)
10450 DECL_ACCESSORS(instance_template, Object)
10451 DECL_ACCESSORS(class_name, Object)
10452 DECL_ACCESSORS(signature, Object)
10453 DECL_ACCESSORS(instance_call_handler, Object)
10454 DECL_ACCESSORS(access_check_info, Object)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010455 DECL_INT_ACCESSORS(flag)
Steve Blocka7e24c12009-10-30 11:49:00 +000010456
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010457 inline int length() const;
10458 inline void set_length(int value);
10459
Steve Blocka7e24c12009-10-30 11:49:00 +000010460 // Following properties use flag bits.
10461 DECL_BOOLEAN_ACCESSORS(hidden_prototype)
10462 DECL_BOOLEAN_ACCESSORS(undetectable)
10463 // If the bit is set, object instances created by this function
10464 // requires access check.
10465 DECL_BOOLEAN_ACCESSORS(needs_access_check)
Ben Murdoch69a99ed2011-11-30 16:03:39 +000010466 DECL_BOOLEAN_ACCESSORS(read_only_prototype)
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010467 DECL_BOOLEAN_ACCESSORS(remove_prototype)
10468 DECL_BOOLEAN_ACCESSORS(do_not_cache)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010469 DECL_BOOLEAN_ACCESSORS(instantiated)
10470 DECL_BOOLEAN_ACCESSORS(accept_any_receiver)
Steve Blocka7e24c12009-10-30 11:49:00 +000010471
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010472 DECLARE_CAST(FunctionTemplateInfo)
Steve Blocka7e24c12009-10-30 11:49:00 +000010473
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010474 // Dispatched behavior.
10475 DECLARE_PRINTER(FunctionTemplateInfo)
10476 DECLARE_VERIFIER(FunctionTemplateInfo)
Steve Blocka7e24c12009-10-30 11:49:00 +000010477
10478 static const int kSerialNumberOffset = TemplateInfo::kHeaderSize;
10479 static const int kCallCodeOffset = kSerialNumberOffset + kPointerSize;
Steve Blocka7e24c12009-10-30 11:49:00 +000010480 static const int kPrototypeTemplateOffset =
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010481 kCallCodeOffset + kPointerSize;
Steve Blocka7e24c12009-10-30 11:49:00 +000010482 static const int kParentTemplateOffset =
10483 kPrototypeTemplateOffset + kPointerSize;
10484 static const int kNamedPropertyHandlerOffset =
10485 kParentTemplateOffset + kPointerSize;
10486 static const int kIndexedPropertyHandlerOffset =
10487 kNamedPropertyHandlerOffset + kPointerSize;
10488 static const int kInstanceTemplateOffset =
10489 kIndexedPropertyHandlerOffset + kPointerSize;
10490 static const int kClassNameOffset = kInstanceTemplateOffset + kPointerSize;
10491 static const int kSignatureOffset = kClassNameOffset + kPointerSize;
10492 static const int kInstanceCallHandlerOffset = kSignatureOffset + kPointerSize;
10493 static const int kAccessCheckInfoOffset =
10494 kInstanceCallHandlerOffset + kPointerSize;
10495 static const int kFlagOffset = kAccessCheckInfoOffset + kPointerSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010496 static const int kLengthOffset = kFlagOffset + kPointerSize;
10497 static const int kSize = kLengthOffset + kPointerSize;
10498
10499 // Returns true if |object| is an instance of this function template.
10500 bool IsTemplateFor(Object* object);
10501 bool IsTemplateFor(Map* map);
Steve Blocka7e24c12009-10-30 11:49:00 +000010502
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010503 // Returns the holder JSObject if the function can legally be called with this
10504 // receiver. Returns Heap::null_value() if the call is illegal.
10505 Object* GetCompatibleReceiver(Isolate* isolate, Object* receiver);
10506
Steve Blocka7e24c12009-10-30 11:49:00 +000010507 private:
10508 // Bit position in the flag, from least significant bit position.
10509 static const int kHiddenPrototypeBit = 0;
10510 static const int kUndetectableBit = 1;
10511 static const int kNeedsAccessCheckBit = 2;
Ben Murdoch69a99ed2011-11-30 16:03:39 +000010512 static const int kReadOnlyPrototypeBit = 3;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010513 static const int kRemovePrototypeBit = 4;
10514 static const int kDoNotCacheBit = 5;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010515 static const int kInstantiatedBit = 6;
10516 static const int kAcceptAnyReceiver = 7;
Steve Blocka7e24c12009-10-30 11:49:00 +000010517
10518 DISALLOW_IMPLICIT_CONSTRUCTORS(FunctionTemplateInfo);
10519};
10520
10521
10522class ObjectTemplateInfo: public TemplateInfo {
10523 public:
10524 DECL_ACCESSORS(constructor, Object)
10525 DECL_ACCESSORS(internal_field_count, Object)
10526
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010527 DECLARE_CAST(ObjectTemplateInfo)
Steve Blocka7e24c12009-10-30 11:49:00 +000010528
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010529 // Dispatched behavior.
10530 DECLARE_PRINTER(ObjectTemplateInfo)
10531 DECLARE_VERIFIER(ObjectTemplateInfo)
Steve Blocka7e24c12009-10-30 11:49:00 +000010532
10533 static const int kConstructorOffset = TemplateInfo::kHeaderSize;
10534 static const int kInternalFieldCountOffset =
10535 kConstructorOffset + kPointerSize;
10536 static const int kSize = kInternalFieldCountOffset + kPointerSize;
10537};
10538
10539
Steve Blocka7e24c12009-10-30 11:49:00 +000010540// The DebugInfo class holds additional information for a function being
10541// debugged.
10542class DebugInfo: public Struct {
10543 public:
10544 // The shared function info for the source being debugged.
10545 DECL_ACCESSORS(shared, SharedFunctionInfo)
Steve Blocka7e24c12009-10-30 11:49:00 +000010546 // Code object for the patched code. This code object is the code object
10547 // currently active for the function.
10548 DECL_ACCESSORS(code, Code)
10549 // Fixed array holding status information for each active break point.
10550 DECL_ACCESSORS(break_points, FixedArray)
10551
10552 // Check if there is a break point at a code position.
10553 bool HasBreakPoint(int code_position);
10554 // Get the break point info object for a code position.
10555 Object* GetBreakPointInfo(int code_position);
10556 // Clear a break point.
10557 static void ClearBreakPoint(Handle<DebugInfo> debug_info,
10558 int code_position,
10559 Handle<Object> break_point_object);
10560 // Set a break point.
10561 static void SetBreakPoint(Handle<DebugInfo> debug_info, int code_position,
10562 int source_position, int statement_position,
10563 Handle<Object> break_point_object);
10564 // Get the break point objects for a code position.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010565 Handle<Object> GetBreakPointObjects(int code_position);
Steve Blocka7e24c12009-10-30 11:49:00 +000010566 // Find the break point info holding this break point object.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010567 static Handle<Object> FindBreakPointInfo(Handle<DebugInfo> debug_info,
10568 Handle<Object> break_point_object);
Steve Blocka7e24c12009-10-30 11:49:00 +000010569 // Get the number of break points for this function.
10570 int GetBreakPointCount();
10571
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010572 DECLARE_CAST(DebugInfo)
Steve Blocka7e24c12009-10-30 11:49:00 +000010573
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010574 // Dispatched behavior.
10575 DECLARE_PRINTER(DebugInfo)
10576 DECLARE_VERIFIER(DebugInfo)
Steve Blocka7e24c12009-10-30 11:49:00 +000010577
10578 static const int kSharedFunctionInfoIndex = Struct::kHeaderSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010579 static const int kCodeIndex = kSharedFunctionInfoIndex + kPointerSize;
10580 static const int kBreakPointsStateIndex = kCodeIndex + kPointerSize;
Steve Blocka7e24c12009-10-30 11:49:00 +000010581 static const int kSize = kBreakPointsStateIndex + kPointerSize;
10582
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010583 static const int kEstimatedNofBreakPointsInFunction = 16;
10584
Steve Blocka7e24c12009-10-30 11:49:00 +000010585 private:
10586 static const int kNoBreakPointInfo = -1;
10587
10588 // Lookup the index in the break_points array for a code position.
10589 int GetBreakPointInfoIndex(int code_position);
10590
10591 DISALLOW_IMPLICIT_CONSTRUCTORS(DebugInfo);
10592};
10593
10594
10595// The BreakPointInfo class holds information for break points set in a
10596// function. The DebugInfo object holds a BreakPointInfo object for each code
10597// position with one or more break points.
10598class BreakPointInfo: public Struct {
10599 public:
10600 // The position in the code for the break point.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010601 DECL_INT_ACCESSORS(code_position)
Steve Blocka7e24c12009-10-30 11:49:00 +000010602 // The position in the source for the break position.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010603 DECL_INT_ACCESSORS(source_position)
Steve Blocka7e24c12009-10-30 11:49:00 +000010604 // The position in the source for the last statement before this break
10605 // position.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010606 DECL_INT_ACCESSORS(statement_position)
Steve Blocka7e24c12009-10-30 11:49:00 +000010607 // List of related JavaScript break points.
10608 DECL_ACCESSORS(break_point_objects, Object)
10609
10610 // Removes a break point.
10611 static void ClearBreakPoint(Handle<BreakPointInfo> info,
10612 Handle<Object> break_point_object);
10613 // Set a break point.
10614 static void SetBreakPoint(Handle<BreakPointInfo> info,
10615 Handle<Object> break_point_object);
10616 // Check if break point info has this break point object.
10617 static bool HasBreakPointObject(Handle<BreakPointInfo> info,
10618 Handle<Object> break_point_object);
10619 // Get the number of break points for this code position.
10620 int GetBreakPointCount();
10621
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010622 DECLARE_CAST(BreakPointInfo)
Steve Blocka7e24c12009-10-30 11:49:00 +000010623
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010624 // Dispatched behavior.
10625 DECLARE_PRINTER(BreakPointInfo)
10626 DECLARE_VERIFIER(BreakPointInfo)
Steve Blocka7e24c12009-10-30 11:49:00 +000010627
10628 static const int kCodePositionIndex = Struct::kHeaderSize;
10629 static const int kSourcePositionIndex = kCodePositionIndex + kPointerSize;
10630 static const int kStatementPositionIndex =
10631 kSourcePositionIndex + kPointerSize;
10632 static const int kBreakPointObjectsIndex =
10633 kStatementPositionIndex + kPointerSize;
10634 static const int kSize = kBreakPointObjectsIndex + kPointerSize;
10635
10636 private:
10637 DISALLOW_IMPLICIT_CONSTRUCTORS(BreakPointInfo);
10638};
Steve Blocka7e24c12009-10-30 11:49:00 +000010639
10640
10641#undef DECL_BOOLEAN_ACCESSORS
10642#undef DECL_ACCESSORS
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010643#undef DECLARE_CAST
10644#undef DECLARE_VERIFIER
Steve Blocka7e24c12009-10-30 11:49:00 +000010645
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010646#define VISITOR_SYNCHRONIZATION_TAGS_LIST(V) \
10647 V(kStringTable, "string_table", "(Internalized strings)") \
Ben Murdoch3ef787d2012-04-12 10:51:47 +010010648 V(kExternalStringsTable, "external_strings_table", "(External strings)") \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010649 V(kStrongRootList, "strong_root_list", "(Strong roots)") \
10650 V(kSmiRootList, "smi_root_list", "(Smi roots)") \
10651 V(kBootstrapper, "bootstrapper", "(Bootstrapper)") \
10652 V(kTop, "top", "(Isolate)") \
10653 V(kRelocatable, "relocatable", "(Relocatable)") \
10654 V(kDebug, "debug", "(Debugger)") \
10655 V(kCompilationCache, "compilationcache", "(Compilation cache)") \
10656 V(kHandleScope, "handlescope", "(Handle scope)") \
10657 V(kBuiltins, "builtins", "(Builtins)") \
10658 V(kGlobalHandles, "globalhandles", "(Global handles)") \
10659 V(kEternalHandles, "eternalhandles", "(Eternal handles)") \
10660 V(kThreadManager, "threadmanager", "(Thread manager)") \
10661 V(kStrongRoots, "strong roots", "(Strong roots)") \
Ben Murdoch3ef787d2012-04-12 10:51:47 +010010662 V(kExtensions, "Extensions", "(Extensions)")
10663
10664class VisitorSynchronization : public AllStatic {
10665 public:
10666#define DECLARE_ENUM(enum_item, ignore1, ignore2) enum_item,
10667 enum SyncTag {
10668 VISITOR_SYNCHRONIZATION_TAGS_LIST(DECLARE_ENUM)
10669 kNumberOfSyncTags
10670 };
10671#undef DECLARE_ENUM
10672
10673 static const char* const kTags[kNumberOfSyncTags];
10674 static const char* const kTagNames[kNumberOfSyncTags];
10675};
Steve Blocka7e24c12009-10-30 11:49:00 +000010676
10677// Abstract base class for visiting, and optionally modifying, the
10678// pointers contained in Objects. Used in GC and serialization/deserialization.
10679class ObjectVisitor BASE_EMBEDDED {
10680 public:
10681 virtual ~ObjectVisitor() {}
10682
10683 // Visits a contiguous arrays of pointers in the half-open range
10684 // [start, end). Any or all of the values may be modified on return.
10685 virtual void VisitPointers(Object** start, Object** end) = 0;
10686
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010687 // Handy shorthand for visiting a single pointer.
10688 virtual void VisitPointer(Object** p) { VisitPointers(p, p + 1); }
10689
10690 // Visit weak next_code_link in Code object.
10691 virtual void VisitNextCodeLink(Object** p) { VisitPointers(p, p + 1); }
10692
Steve Blocka7e24c12009-10-30 11:49:00 +000010693 // To allow lazy clearing of inline caches the visitor has
10694 // a rich interface for iterating over Code objects..
10695
10696 // Visits a code target in the instruction stream.
10697 virtual void VisitCodeTarget(RelocInfo* rinfo);
10698
Steve Block791712a2010-08-27 10:21:07 +010010699 // Visits a code entry in a JS function.
10700 virtual void VisitCodeEntry(Address entry_address);
10701
Ben Murdochb0fe1622011-05-05 13:52:32 +010010702 // Visits a global property cell reference in the instruction stream.
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010703 virtual void VisitCell(RelocInfo* rinfo);
Ben Murdochb0fe1622011-05-05 13:52:32 +010010704
Steve Blocka7e24c12009-10-30 11:49:00 +000010705 // Visits a runtime entry in the instruction stream.
10706 virtual void VisitRuntimeEntry(RelocInfo* rinfo) {}
10707
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010708 // Visits the resource of an one-byte or two-byte string.
10709 virtual void VisitExternalOneByteString(
10710 v8::String::ExternalOneByteStringResource** resource) {}
Steve Blockd0582a62009-12-15 09:54:21 +000010711 virtual void VisitExternalTwoByteString(
10712 v8::String::ExternalStringResource** resource) {}
10713
Steve Blocka7e24c12009-10-30 11:49:00 +000010714 // Visits a debug call target in the instruction stream.
10715 virtual void VisitDebugTarget(RelocInfo* rinfo);
10716
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010717 // Visits the byte sequence in a function's prologue that contains information
10718 // about the code's age.
10719 virtual void VisitCodeAgeSequence(RelocInfo* rinfo);
Steve Blocka7e24c12009-10-30 11:49:00 +000010720
Ben Murdoch3ef787d2012-04-12 10:51:47 +010010721 // Visit pointer embedded into a code object.
10722 virtual void VisitEmbeddedPointer(RelocInfo* rinfo);
10723
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010724 // Visits an external reference embedded into a code object.
Ben Murdoch3ef787d2012-04-12 10:51:47 +010010725 virtual void VisitExternalReference(RelocInfo* rinfo);
10726
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010727 // Visits an external reference.
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010728 virtual void VisitExternalReference(Address* p) {}
Steve Blocka7e24c12009-10-30 11:49:00 +000010729
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010730 // Visits an (encoded) internal reference.
10731 virtual void VisitInternalReference(RelocInfo* rinfo) {}
10732
Steve Block44f0eee2011-05-26 01:26:41 +010010733 // Visits a handle that has an embedder-assigned class ID.
10734 virtual void VisitEmbedderReference(Object** p, uint16_t class_id) {}
10735
Steve Blocka7e24c12009-10-30 11:49:00 +000010736 // Intended for serialization/deserialization checking: insert, or
10737 // check for the presence of, a tag at this position in the stream.
Ben Murdoch3ef787d2012-04-12 10:51:47 +010010738 // Also used for marking up GC roots in heap snapshots.
10739 virtual void Synchronize(VisitorSynchronization::SyncTag tag) {}
Steve Blocka7e24c12009-10-30 11:49:00 +000010740};
10741
10742
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010743// BooleanBit is a helper class for setting and getting a bit in an integer.
Steve Blocka7e24c12009-10-30 11:49:00 +000010744class BooleanBit : public AllStatic {
10745 public:
Steve Blocka7e24c12009-10-30 11:49:00 +000010746 static inline bool get(int value, int bit_position) {
10747 return (value & (1 << bit_position)) != 0;
10748 }
10749
Steve Blocka7e24c12009-10-30 11:49:00 +000010750 static inline int set(int value, int bit_position, bool v) {
10751 if (v) {
10752 value |= (1 << bit_position);
10753 } else {
10754 value &= ~(1 << bit_position);
10755 }
10756 return value;
10757 }
10758};
10759
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010760
10761} // NOLINT, false-positive due to second-order macros.
10762} // NOLINT, false-positive due to second-order macros.
Steve Blocka7e24c12009-10-30 11:49:00 +000010763
10764#endif // V8_OBJECTS_H_