1 // Copyright 2015 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef V8_OBJECTS_H_
6 #define V8_OBJECTS_H_
7
8 #include <iosfwd>
9
10 #include "src/assert-scope.h"
11 #include "src/bailout-reason.h"
12 #include "src/base/bits.h"
13 #include "src/base/flags.h"
14 #include "src/base/smart-pointers.h"
15 #include "src/builtins.h"
16 #include "src/checks.h"
17 #include "src/elements-kind.h"
18 #include "src/field-index.h"
19 #include "src/flags.h"
20 #include "src/list.h"
21 #include "src/property-details.h"
22 #include "src/unicode.h"
23 #include "src/unicode-decoder.h"
24 #include "src/zone.h"
25
26 #if V8_TARGET_ARCH_ARM
27 #include "src/arm/constants-arm.h" // NOLINT
28 #elif V8_TARGET_ARCH_ARM64
29 #include "src/arm64/constants-arm64.h" // NOLINT
30 #elif V8_TARGET_ARCH_MIPS
31 #include "src/mips/constants-mips.h" // NOLINT
32 #elif V8_TARGET_ARCH_MIPS64
33 #include "src/mips64/constants-mips64.h" // NOLINT
34 #elif V8_TARGET_ARCH_PPC
35 #include "src/ppc/constants-ppc.h" // NOLINT
36 #elif V8_TARGET_ARCH_S390
37 #include "src/s390/constants-s390.h" // NOLINT
38 #endif
39
40
41 //
42 // Most object types in the V8 JavaScript are described in this file.
43 //
44 // Inheritance hierarchy:
45 // - Object
46 // - Smi (immediate small integer)
47 // - HeapObject (superclass for everything allocated in the heap)
48 // - JSReceiver (suitable for property access)
49 // - JSObject
50 // - JSArray
51 // - JSArrayBuffer
52 // - JSArrayBufferView
53 // - JSTypedArray
54 // - JSDataView
55 // - JSBoundFunction
56 // - JSCollection
57 // - JSSet
58 // - JSMap
59 // - JSSetIterator
60 // - JSMapIterator
61 // - JSWeakCollection
62 // - JSWeakMap
63 // - JSWeakSet
64 // - JSRegExp
65 // - JSFunction
66 // - JSGeneratorObject
67 // - JSModule
68 // - JSGlobalObject
69 // - JSGlobalProxy
70 // - JSValue
71 // - JSDate
72 // - JSMessageObject
73 // - JSProxy
74 // - FixedArrayBase
75 // - ByteArray
76 // - BytecodeArray
77 // - FixedArray
78 // - DescriptorArray
79 // - LiteralsArray
80 // - HashTable
81 // - Dictionary
82 // - StringTable
83 // - StringSet
84 // - CompilationCacheTable
85 // - CodeCacheHashTable
86 // - MapCache
87 // - OrderedHashTable
88 // - OrderedHashSet
89 // - OrderedHashMap
90 // - Context
91 // - TypeFeedbackMetadata
92 // - TypeFeedbackVector
93 // - ScopeInfo
94 // - TransitionArray
95 // - ScriptContextTable
96 // - WeakFixedArray
97 // - FixedDoubleArray
98 // - Name
99 // - String
100 // - SeqString
101 // - SeqOneByteString
102 // - SeqTwoByteString
103 // - SlicedString
104 // - ConsString
105 // - ExternalString
106 // - ExternalOneByteString
107 // - ExternalTwoByteString
108 // - InternalizedString
109 // - SeqInternalizedString
110 // - SeqOneByteInternalizedString
111 // - SeqTwoByteInternalizedString
112 // - ConsInternalizedString
113 // - ExternalInternalizedString
114 // - ExternalOneByteInternalizedString
115 // - ExternalTwoByteInternalizedString
116 // - Symbol
117 // - HeapNumber
118 // - Simd128Value
119 // - Float32x4
120 // - Int32x4
121 // - Uint32x4
122 // - Bool32x4
123 // - Int16x8
124 // - Uint16x8
125 // - Bool16x8
126 // - Int8x16
127 // - Uint8x16
128 // - Bool8x16
129 // - Cell
130 // - PropertyCell
131 // - Code
132 // - AbstractCode, a wrapper around Code or BytecodeArray
133 // - Map
134 // - Oddball
135 // - Foreign
136 // - SharedFunctionInfo
137 // - Struct
138 // - Box
139 // - AccessorInfo
140 // - AccessorPair
141 // - AccessCheckInfo
142 // - InterceptorInfo
143 // - CallHandlerInfo
144 // - TemplateInfo
145 // - FunctionTemplateInfo
146 // - ObjectTemplateInfo
147 // - Script
148 // - DebugInfo
149 // - BreakPointInfo
150 // - CodeCache
151 // - PrototypeInfo
152 // - WeakCell
153 //
154 // Formats of Object*:
155 // Smi: [31 bit signed int] 0
156 // HeapObject: [32 bit direct pointer] (4 byte aligned) | 01
157
158 namespace v8 {
159 namespace internal {
160
161 enum KeyedAccessStoreMode {
162 STANDARD_STORE,
163 STORE_TRANSITION_TO_OBJECT,
164 STORE_TRANSITION_TO_DOUBLE,
165 STORE_AND_GROW_NO_TRANSITION,
166 STORE_AND_GROW_TRANSITION_TO_OBJECT,
167 STORE_AND_GROW_TRANSITION_TO_DOUBLE,
168 STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS,
169 STORE_NO_TRANSITION_HANDLE_COW
170 };
171
172
173 // Valid hints for the abstract operation ToPrimitive,
174 // implemented according to ES6, section 7.1.1.
175 enum class ToPrimitiveHint { kDefault, kNumber, kString };
176
177
178 // Valid hints for the abstract operation OrdinaryToPrimitive,
179 // implemented according to ES6, section 7.1.1.
180 enum class OrdinaryToPrimitiveHint { kNumber, kString };
181
182
183 enum TypeofMode : int { INSIDE_TYPEOF, NOT_INSIDE_TYPEOF };
184
185
186 enum MutableMode {
187 MUTABLE,
188 IMMUTABLE
189 };
190
191
192 enum ExternalArrayType {
193 kExternalInt8Array = 1,
194 kExternalUint8Array,
195 kExternalInt16Array,
196 kExternalUint16Array,
197 kExternalInt32Array,
198 kExternalUint32Array,
199 kExternalFloat32Array,
200 kExternalFloat64Array,
201 kExternalUint8ClampedArray,
202 };
203
204
IsTransitionStoreMode(KeyedAccessStoreMode store_mode)205 static inline bool IsTransitionStoreMode(KeyedAccessStoreMode store_mode) {
206 return store_mode == STORE_TRANSITION_TO_OBJECT ||
207 store_mode == STORE_TRANSITION_TO_DOUBLE ||
208 store_mode == STORE_AND_GROW_TRANSITION_TO_OBJECT ||
209 store_mode == STORE_AND_GROW_TRANSITION_TO_DOUBLE;
210 }
211
212
GetNonTransitioningStoreMode(KeyedAccessStoreMode store_mode)213 static inline KeyedAccessStoreMode GetNonTransitioningStoreMode(
214 KeyedAccessStoreMode store_mode) {
215 if (store_mode >= STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) {
216 return store_mode;
217 }
218 if (store_mode >= STORE_AND_GROW_NO_TRANSITION) {
219 return STORE_AND_GROW_NO_TRANSITION;
220 }
221 return STANDARD_STORE;
222 }
223
224
IsGrowStoreMode(KeyedAccessStoreMode store_mode)225 static inline bool IsGrowStoreMode(KeyedAccessStoreMode store_mode) {
226 return store_mode >= STORE_AND_GROW_NO_TRANSITION &&
227 store_mode <= STORE_AND_GROW_TRANSITION_TO_DOUBLE;
228 }
229
230
231 enum IcCheckType { ELEMENT, PROPERTY };
232
233
234 // SKIP_WRITE_BARRIER skips the write barrier.
235 // UPDATE_WEAK_WRITE_BARRIER skips the marking part of the write barrier and
236 // only performs the generational part.
237 // UPDATE_WRITE_BARRIER is doing the full barrier, marking and generational.
238 enum WriteBarrierMode {
239 SKIP_WRITE_BARRIER,
240 UPDATE_WEAK_WRITE_BARRIER,
241 UPDATE_WRITE_BARRIER
242 };
243
244
245 // Indicates whether a value can be loaded as a constant.
246 enum StoreMode { ALLOW_IN_DESCRIPTOR, FORCE_FIELD };
247
248
249 // PropertyNormalizationMode is used to specify whether to keep
250 // inobject properties when normalizing properties of a JSObject.
251 enum PropertyNormalizationMode {
252 CLEAR_INOBJECT_PROPERTIES,
253 KEEP_INOBJECT_PROPERTIES
254 };
255
256
257 // Indicates how aggressively the prototype should be optimized. FAST_PROTOTYPE
258 // will give the fastest result by tailoring the map to the prototype, but that
259 // will cause polymorphism with other objects. REGULAR_PROTOTYPE is to be used
260 // (at least for now) when dynamically modifying the prototype chain of an
261 // object using __proto__ or Object.setPrototypeOf.
262 enum PrototypeOptimizationMode { REGULAR_PROTOTYPE, FAST_PROTOTYPE };
263
264
265 // Indicates whether transitions can be added to a source map or not.
266 enum TransitionFlag {
267 INSERT_TRANSITION,
268 OMIT_TRANSITION
269 };
270
271
272 // Indicates whether the transition is simple: the target map of the transition
273 // either extends the current map with a new property, or it modifies the
274 // property that was added last to the current map.
275 enum SimpleTransitionFlag {
276 SIMPLE_PROPERTY_TRANSITION,
277 PROPERTY_TRANSITION,
278 SPECIAL_TRANSITION
279 };
280
281
282 // Indicates whether we are only interested in the descriptors of a particular
283 // map, or in all descriptors in the descriptor array.
284 enum DescriptorFlag {
285 ALL_DESCRIPTORS,
286 OWN_DESCRIPTORS
287 };
288
289 // The GC maintains a bit of information, the MarkingParity, which toggles
290 // from odd to even and back every time marking is completed. Incremental
291 // marking can visit an object twice during a marking phase, so algorithms that
292 // that piggy-back on marking can use the parity to ensure that they only
293 // perform an operation on an object once per marking phase: they record the
294 // MarkingParity when they visit an object, and only re-visit the object when it
295 // is marked again and the MarkingParity changes.
296 enum MarkingParity {
297 NO_MARKING_PARITY,
298 ODD_MARKING_PARITY,
299 EVEN_MARKING_PARITY
300 };
301
302 // ICs store extra state in a Code object. The default extra state is
303 // kNoExtraICState.
304 typedef int ExtraICState;
305 static const ExtraICState kNoExtraICState = 0;
306
307 // Instance size sentinel for objects of variable size.
308 const int kVariableSizeSentinel = 0;
309
310 // We may store the unsigned bit field as signed Smi value and do not
311 // use the sign bit.
312 const int kStubMajorKeyBits = 8;
313 const int kStubMinorKeyBits = kSmiValueSize - kStubMajorKeyBits - 1;
314
315 // All Maps have a field instance_type containing a InstanceType.
316 // It describes the type of the instances.
317 //
318 // As an example, a JavaScript object is a heap object and its map
319 // instance_type is JS_OBJECT_TYPE.
320 //
321 // The names of the string instance types are intended to systematically
322 // mirror their encoding in the instance_type field of the map. The default
323 // encoding is considered TWO_BYTE. It is not mentioned in the name. ONE_BYTE
324 // encoding is mentioned explicitly in the name. Likewise, the default
325 // representation is considered sequential. It is not mentioned in the
326 // name. The other representations (e.g. CONS, EXTERNAL) are explicitly
327 // mentioned. Finally, the string is either a STRING_TYPE (if it is a normal
328 // string) or a INTERNALIZED_STRING_TYPE (if it is a internalized string).
329 //
330 // NOTE: The following things are some that depend on the string types having
331 // instance_types that are less than those of all other types:
332 // HeapObject::Size, HeapObject::IterateBody, the typeof operator, and
333 // Object::IsString.
334 //
335 // NOTE: Everything following JS_VALUE_TYPE is considered a
336 // JSObject for GC purposes. The first four entries here have typeof
337 // 'object', whereas JS_FUNCTION_TYPE has typeof 'function'.
338 #define INSTANCE_TYPE_LIST(V) \
339 V(STRING_TYPE) \
340 V(ONE_BYTE_STRING_TYPE) \
341 V(CONS_STRING_TYPE) \
342 V(CONS_ONE_BYTE_STRING_TYPE) \
343 V(SLICED_STRING_TYPE) \
344 V(SLICED_ONE_BYTE_STRING_TYPE) \
345 V(EXTERNAL_STRING_TYPE) \
346 V(EXTERNAL_ONE_BYTE_STRING_TYPE) \
347 V(EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE) \
348 V(SHORT_EXTERNAL_STRING_TYPE) \
349 V(SHORT_EXTERNAL_ONE_BYTE_STRING_TYPE) \
350 V(SHORT_EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE) \
351 \
352 V(INTERNALIZED_STRING_TYPE) \
353 V(ONE_BYTE_INTERNALIZED_STRING_TYPE) \
354 V(EXTERNAL_INTERNALIZED_STRING_TYPE) \
355 V(EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE) \
356 V(EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE) \
357 V(SHORT_EXTERNAL_INTERNALIZED_STRING_TYPE) \
358 V(SHORT_EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE) \
359 V(SHORT_EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE) \
360 \
361 V(SYMBOL_TYPE) \
362 V(SIMD128_VALUE_TYPE) \
363 \
364 V(MAP_TYPE) \
365 V(CODE_TYPE) \
366 V(ODDBALL_TYPE) \
367 V(CELL_TYPE) \
368 V(PROPERTY_CELL_TYPE) \
369 \
370 V(HEAP_NUMBER_TYPE) \
371 V(MUTABLE_HEAP_NUMBER_TYPE) \
372 V(FOREIGN_TYPE) \
373 V(BYTE_ARRAY_TYPE) \
374 V(BYTECODE_ARRAY_TYPE) \
375 V(FREE_SPACE_TYPE) \
376 \
377 V(FIXED_INT8_ARRAY_TYPE) \
378 V(FIXED_UINT8_ARRAY_TYPE) \
379 V(FIXED_INT16_ARRAY_TYPE) \
380 V(FIXED_UINT16_ARRAY_TYPE) \
381 V(FIXED_INT32_ARRAY_TYPE) \
382 V(FIXED_UINT32_ARRAY_TYPE) \
383 V(FIXED_FLOAT32_ARRAY_TYPE) \
384 V(FIXED_FLOAT64_ARRAY_TYPE) \
385 V(FIXED_UINT8_CLAMPED_ARRAY_TYPE) \
386 \
387 V(FILLER_TYPE) \
388 \
389 V(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(TYPE_FEEDBACK_INFO_TYPE) \
402 V(ALIASED_ARGUMENTS_ENTRY_TYPE) \
403 V(BOX_TYPE) \
404 V(PROTOTYPE_INFO_TYPE) \
405 V(SLOPPY_BLOCK_WITH_EVAL_CONTEXT_EXTENSION_TYPE) \
406 \
407 V(FIXED_ARRAY_TYPE) \
408 V(FIXED_DOUBLE_ARRAY_TYPE) \
409 V(SHARED_FUNCTION_INFO_TYPE) \
410 V(WEAK_CELL_TYPE) \
411 V(TRANSITION_ARRAY_TYPE) \
412 \
413 V(JS_MESSAGE_OBJECT_TYPE) \
414 \
415 V(JS_VALUE_TYPE) \
416 V(JS_DATE_TYPE) \
417 V(JS_OBJECT_TYPE) \
418 V(JS_ARGUMENTS_TYPE) \
419 V(JS_CONTEXT_EXTENSION_OBJECT_TYPE) \
420 V(JS_GENERATOR_OBJECT_TYPE) \
421 V(JS_MODULE_TYPE) \
422 V(JS_GLOBAL_OBJECT_TYPE) \
423 V(JS_GLOBAL_PROXY_TYPE) \
424 V(JS_API_OBJECT_TYPE) \
425 V(JS_SPECIAL_API_OBJECT_TYPE) \
426 V(JS_ARRAY_TYPE) \
427 V(JS_ARRAY_BUFFER_TYPE) \
428 V(JS_TYPED_ARRAY_TYPE) \
429 V(JS_DATA_VIEW_TYPE) \
430 V(JS_PROXY_TYPE) \
431 V(JS_SET_TYPE) \
432 V(JS_MAP_TYPE) \
433 V(JS_SET_ITERATOR_TYPE) \
434 V(JS_MAP_ITERATOR_TYPE) \
435 V(JS_WEAK_MAP_TYPE) \
436 V(JS_WEAK_SET_TYPE) \
437 V(JS_PROMISE_TYPE) \
438 V(JS_REGEXP_TYPE) \
439 V(JS_ERROR_TYPE) \
440 \
441 V(JS_BOUND_FUNCTION_TYPE) \
442 V(JS_FUNCTION_TYPE) \
443 V(DEBUG_INFO_TYPE) \
444 V(BREAK_POINT_INFO_TYPE)
445
446 // Since string types are not consecutive, this macro is used to
447 // iterate over them.
448 #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)
496
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.
506 #define STRUCT_LIST(V) \
507 V(BOX, Box, box) \
508 V(ACCESSOR_INFO, AccessorInfo, accessor_info) \
509 V(ACCESSOR_PAIR, AccessorPair, accessor_pair) \
510 V(ACCESS_CHECK_INFO, AccessCheckInfo, access_check_info) \
511 V(INTERCEPTOR_INFO, InterceptorInfo, interceptor_info) \
512 V(CALL_HANDLER_INFO, CallHandlerInfo, call_handler_info) \
513 V(FUNCTION_TEMPLATE_INFO, FunctionTemplateInfo, function_template_info) \
514 V(OBJECT_TEMPLATE_INFO, ObjectTemplateInfo, object_template_info) \
515 V(SCRIPT, Script, script) \
516 V(ALLOCATION_SITE, AllocationSite, allocation_site) \
517 V(ALLOCATION_MEMENTO, AllocationMemento, allocation_memento) \
518 V(TYPE_FEEDBACK_INFO, TypeFeedbackInfo, type_feedback_info) \
519 V(ALIASED_ARGUMENTS_ENTRY, AliasedArgumentsEntry, aliased_arguments_entry) \
520 V(DEBUG_INFO, DebugInfo, debug_info) \
521 V(BREAK_POINT_INFO, BreakPointInfo, break_point_info) \
522 V(PROTOTYPE_INFO, PrototypeInfo, prototype_info) \
523 V(SLOPPY_BLOCK_WITH_EVAL_CONTEXT_EXTENSION, \
524 SloppyBlockWithEvalContextExtension, \
525 sloppy_block_with_eval_context_extension)
526
527 // We use the full 8 bits of the instance_type field to encode heap object
528 // instance types. The high-order bit (bit 7) is set if the object is not a
529 // string, and cleared if it is a string.
530 const uint32_t kIsNotStringMask = 0x80;
531 const uint32_t kStringTag = 0x0;
532 const uint32_t kNotStringTag = 0x80;
533
534 // Bit 6 indicates that the object is an internalized string (if set) or not.
535 // Bit 7 has to be clear as well.
536 const uint32_t kIsNotInternalizedMask = 0x40;
537 const uint32_t kNotInternalizedTag = 0x40;
538 const uint32_t kInternalizedTag = 0x0;
539
540 // If bit 7 is clear then bit 2 indicates whether the string consists of
541 // two-byte characters or one-byte characters.
542 const uint32_t kStringEncodingMask = 0x4;
543 const uint32_t kTwoByteStringTag = 0x0;
544 const uint32_t kOneByteStringTag = 0x4;
545
546 // If bit 7 is clear, the low-order 2 bits indicate the representation
547 // of the string.
548 const uint32_t kStringRepresentationMask = 0x03;
549 enum StringRepresentationTag {
550 kSeqStringTag = 0x0,
551 kConsStringTag = 0x1,
552 kExternalStringTag = 0x2,
553 kSlicedStringTag = 0x3
554 };
555 const uint32_t kIsIndirectStringMask = 0x1;
556 const uint32_t kIsIndirectStringTag = 0x1;
557 STATIC_ASSERT((kSeqStringTag & kIsIndirectStringMask) == 0); // NOLINT
558 STATIC_ASSERT((kExternalStringTag & kIsIndirectStringMask) == 0); // NOLINT
559 STATIC_ASSERT((kConsStringTag &
560 kIsIndirectStringMask) == kIsIndirectStringTag); // NOLINT
561 STATIC_ASSERT((kSlicedStringTag &
562 kIsIndirectStringMask) == kIsIndirectStringTag); // NOLINT
563
564 // Use this mask to distinguish between cons and slice only after making
565 // sure that the string is one of the two (an indirect string).
566 const uint32_t kSlicedNotConsMask = kSlicedStringTag & ~kConsStringTag;
567 STATIC_ASSERT(IS_POWER_OF_TWO(kSlicedNotConsMask));
568
569 // If bit 7 is clear, then bit 3 indicates whether this two-byte
570 // string actually contains one byte data.
571 const uint32_t kOneByteDataHintMask = 0x08;
572 const uint32_t kOneByteDataHintTag = 0x08;
573
574 // If bit 7 is clear and string representation indicates an external string,
575 // then bit 4 indicates whether the data pointer is cached.
576 const uint32_t kShortExternalStringMask = 0x10;
577 const uint32_t kShortExternalStringTag = 0x10;
578
579
580 // A ConsString with an empty string as the right side is a candidate
581 // for being shortcut by the garbage collector. We don't allocate any
582 // non-flat internalized strings, so we do not shortcut them thereby
583 // avoiding turning internalized strings into strings. The bit-masks
584 // below contain the internalized bit as additional safety.
585 // See heap.cc, mark-compact.cc and objects-visiting.cc.
586 const uint32_t kShortcutTypeMask =
587 kIsNotStringMask |
588 kIsNotInternalizedMask |
589 kStringRepresentationMask;
590 const uint32_t kShortcutTypeTag = kConsStringTag | kNotInternalizedTag;
591
IsShortcutCandidate(int type)592 static inline bool IsShortcutCandidate(int type) {
593 return ((type & kShortcutTypeMask) == kShortcutTypeTag);
594 }
595
596 enum InstanceType {
597 // String types.
598 INTERNALIZED_STRING_TYPE = kTwoByteStringTag | kSeqStringTag |
599 kInternalizedTag, // FIRST_PRIMITIVE_TYPE
600 ONE_BYTE_INTERNALIZED_STRING_TYPE =
601 kOneByteStringTag | kSeqStringTag | kInternalizedTag,
602 EXTERNAL_INTERNALIZED_STRING_TYPE =
603 kTwoByteStringTag | kExternalStringTag | kInternalizedTag,
604 EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE =
605 kOneByteStringTag | kExternalStringTag | kInternalizedTag,
606 EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE =
607 EXTERNAL_INTERNALIZED_STRING_TYPE | kOneByteDataHintTag |
608 kInternalizedTag,
609 SHORT_EXTERNAL_INTERNALIZED_STRING_TYPE = EXTERNAL_INTERNALIZED_STRING_TYPE |
610 kShortExternalStringTag |
611 kInternalizedTag,
612 SHORT_EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE =
613 EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE | kShortExternalStringTag |
614 kInternalizedTag,
615 SHORT_EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE =
616 EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE |
617 kShortExternalStringTag | kInternalizedTag,
618 STRING_TYPE = INTERNALIZED_STRING_TYPE | kNotInternalizedTag,
619 ONE_BYTE_STRING_TYPE =
620 ONE_BYTE_INTERNALIZED_STRING_TYPE | kNotInternalizedTag,
621 CONS_STRING_TYPE = kTwoByteStringTag | kConsStringTag | kNotInternalizedTag,
622 CONS_ONE_BYTE_STRING_TYPE =
623 kOneByteStringTag | kConsStringTag | kNotInternalizedTag,
624 SLICED_STRING_TYPE =
625 kTwoByteStringTag | kSlicedStringTag | kNotInternalizedTag,
626 SLICED_ONE_BYTE_STRING_TYPE =
627 kOneByteStringTag | kSlicedStringTag | kNotInternalizedTag,
628 EXTERNAL_STRING_TYPE =
629 EXTERNAL_INTERNALIZED_STRING_TYPE | kNotInternalizedTag,
630 EXTERNAL_ONE_BYTE_STRING_TYPE =
631 EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE | kNotInternalizedTag,
632 EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE =
633 EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE |
634 kNotInternalizedTag,
635 SHORT_EXTERNAL_STRING_TYPE =
636 SHORT_EXTERNAL_INTERNALIZED_STRING_TYPE | kNotInternalizedTag,
637 SHORT_EXTERNAL_ONE_BYTE_STRING_TYPE =
638 SHORT_EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE | kNotInternalizedTag,
639 SHORT_EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE =
640 SHORT_EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE |
641 kNotInternalizedTag,
642
643 // Non-string names
644 SYMBOL_TYPE = kNotStringTag, // FIRST_NONSTRING_TYPE, LAST_NAME_TYPE
645
646 // Other primitives (cannot contain non-map-word pointers to heap objects).
647 HEAP_NUMBER_TYPE,
648 SIMD128_VALUE_TYPE,
649 ODDBALL_TYPE, // LAST_PRIMITIVE_TYPE
650
651 // Objects allocated in their own spaces (never in new space).
652 MAP_TYPE,
653 CODE_TYPE,
654
655 // "Data", objects that cannot contain non-map-word pointers to heap
656 // objects.
657 MUTABLE_HEAP_NUMBER_TYPE,
658 FOREIGN_TYPE,
659 BYTE_ARRAY_TYPE,
660 BYTECODE_ARRAY_TYPE,
661 FREE_SPACE_TYPE,
662 FIXED_INT8_ARRAY_TYPE, // FIRST_FIXED_TYPED_ARRAY_TYPE
663 FIXED_UINT8_ARRAY_TYPE,
664 FIXED_INT16_ARRAY_TYPE,
665 FIXED_UINT16_ARRAY_TYPE,
666 FIXED_INT32_ARRAY_TYPE,
667 FIXED_UINT32_ARRAY_TYPE,
668 FIXED_FLOAT32_ARRAY_TYPE,
669 FIXED_FLOAT64_ARRAY_TYPE,
670 FIXED_UINT8_CLAMPED_ARRAY_TYPE, // LAST_FIXED_TYPED_ARRAY_TYPE
671 FIXED_DOUBLE_ARRAY_TYPE,
672 FILLER_TYPE, // LAST_DATA_TYPE
673
674 // Structs.
675 ACCESSOR_INFO_TYPE,
676 ACCESSOR_PAIR_TYPE,
677 ACCESS_CHECK_INFO_TYPE,
678 INTERCEPTOR_INFO_TYPE,
679 CALL_HANDLER_INFO_TYPE,
680 FUNCTION_TEMPLATE_INFO_TYPE,
681 OBJECT_TEMPLATE_INFO_TYPE,
682 SIGNATURE_INFO_TYPE,
683 TYPE_SWITCH_INFO_TYPE,
684 ALLOCATION_SITE_TYPE,
685 ALLOCATION_MEMENTO_TYPE,
686 SCRIPT_TYPE,
687 TYPE_FEEDBACK_INFO_TYPE,
688 ALIASED_ARGUMENTS_ENTRY_TYPE,
689 BOX_TYPE,
690 DEBUG_INFO_TYPE,
691 BREAK_POINT_INFO_TYPE,
692 FIXED_ARRAY_TYPE,
693 SHARED_FUNCTION_INFO_TYPE,
694 CELL_TYPE,
695 WEAK_CELL_TYPE,
696 TRANSITION_ARRAY_TYPE,
697 PROPERTY_CELL_TYPE,
698 PROTOTYPE_INFO_TYPE,
699 SLOPPY_BLOCK_WITH_EVAL_CONTEXT_EXTENSION_TYPE,
700
701 // All the following types are subtypes of JSReceiver, which corresponds to
702 // objects in the JS sense. The first and the last type in this range are
703 // the two forms of function. This organization enables using the same
704 // compares for checking the JS_RECEIVER and the NONCALLABLE_JS_OBJECT range.
705 JS_PROXY_TYPE, // FIRST_JS_RECEIVER_TYPE
706 JS_GLOBAL_OBJECT_TYPE, // FIRST_JS_OBJECT_TYPE
707 JS_GLOBAL_PROXY_TYPE,
708 // Like JS_API_OBJECT_TYPE, but requires access checks and/or has
709 // interceptors.
710 JS_SPECIAL_API_OBJECT_TYPE, // LAST_SPECIAL_RECEIVER_TYPE
711 JS_VALUE_TYPE, // LAST_CUSTOM_ELEMENTS_RECEIVER
712 JS_MESSAGE_OBJECT_TYPE,
713 JS_DATE_TYPE,
714 // Like JS_OBJECT_TYPE, but created from API function.
715 JS_API_OBJECT_TYPE,
716 JS_OBJECT_TYPE,
717 JS_ARGUMENTS_TYPE,
718 JS_CONTEXT_EXTENSION_OBJECT_TYPE,
719 JS_GENERATOR_OBJECT_TYPE,
720 JS_MODULE_TYPE,
721 JS_ARRAY_TYPE,
722 JS_ARRAY_BUFFER_TYPE,
723 JS_TYPED_ARRAY_TYPE,
724 JS_DATA_VIEW_TYPE,
725 JS_SET_TYPE,
726 JS_MAP_TYPE,
727 JS_SET_ITERATOR_TYPE,
728 JS_MAP_ITERATOR_TYPE,
729 JS_WEAK_MAP_TYPE,
730 JS_WEAK_SET_TYPE,
731 JS_PROMISE_TYPE,
732 JS_REGEXP_TYPE,
733 JS_ERROR_TYPE,
734 JS_BOUND_FUNCTION_TYPE,
735 JS_FUNCTION_TYPE, // LAST_JS_OBJECT_TYPE, LAST_JS_RECEIVER_TYPE
736
737 // Pseudo-types
738 FIRST_TYPE = 0x0,
739 LAST_TYPE = JS_FUNCTION_TYPE,
740 FIRST_NAME_TYPE = FIRST_TYPE,
741 LAST_NAME_TYPE = SYMBOL_TYPE,
742 FIRST_UNIQUE_NAME_TYPE = INTERNALIZED_STRING_TYPE,
743 LAST_UNIQUE_NAME_TYPE = SYMBOL_TYPE,
744 FIRST_NONSTRING_TYPE = SYMBOL_TYPE,
745 FIRST_PRIMITIVE_TYPE = FIRST_NAME_TYPE,
746 LAST_PRIMITIVE_TYPE = ODDBALL_TYPE,
747 FIRST_FUNCTION_TYPE = JS_BOUND_FUNCTION_TYPE,
748 LAST_FUNCTION_TYPE = JS_FUNCTION_TYPE,
749 // Boundaries for testing for a fixed typed array.
750 FIRST_FIXED_TYPED_ARRAY_TYPE = FIXED_INT8_ARRAY_TYPE,
751 LAST_FIXED_TYPED_ARRAY_TYPE = FIXED_UINT8_CLAMPED_ARRAY_TYPE,
752 // Boundary for promotion to old space.
753 LAST_DATA_TYPE = FILLER_TYPE,
754 // Boundary for objects represented as JSReceiver (i.e. JSObject or JSProxy).
755 // Note that there is no range for JSObject or JSProxy, since their subtypes
756 // are not continuous in this enum! The enum ranges instead reflect the
757 // external class names, where proxies are treated as either ordinary objects,
758 // or functions.
759 FIRST_JS_RECEIVER_TYPE = JS_PROXY_TYPE,
760 LAST_JS_RECEIVER_TYPE = LAST_TYPE,
761 // Boundaries for testing the types represented as JSObject
762 FIRST_JS_OBJECT_TYPE = JS_GLOBAL_OBJECT_TYPE,
763 LAST_JS_OBJECT_TYPE = LAST_TYPE,
764 // Boundary for testing JSReceivers that need special property lookup handling
765 LAST_SPECIAL_RECEIVER_TYPE = JS_SPECIAL_API_OBJECT_TYPE,
766 // Boundary case for testing JSReceivers that may have elements while having
767 // an empty fixed array as elements backing store. This is true for string
768 // wrappers.
769 LAST_CUSTOM_ELEMENTS_RECEIVER = JS_VALUE_TYPE,
770 };
771
772 STATIC_ASSERT(JS_OBJECT_TYPE == Internals::kJSObjectType);
773 STATIC_ASSERT(JS_API_OBJECT_TYPE == Internals::kJSApiObjectType);
774 STATIC_ASSERT(FIRST_NONSTRING_TYPE == Internals::kFirstNonstringType);
775 STATIC_ASSERT(ODDBALL_TYPE == Internals::kOddballType);
776 STATIC_ASSERT(FOREIGN_TYPE == Internals::kForeignType);
777
778
779 std::ostream& operator<<(std::ostream& os, InstanceType instance_type);
780
781
782 #define FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(V) \
783 V(FAST_ELEMENTS_SUB_TYPE) \
784 V(DICTIONARY_ELEMENTS_SUB_TYPE) \
785 V(FAST_PROPERTIES_SUB_TYPE) \
786 V(DICTIONARY_PROPERTIES_SUB_TYPE) \
787 V(MAP_CODE_CACHE_SUB_TYPE) \
788 V(SCOPE_INFO_SUB_TYPE) \
789 V(STRING_TABLE_SUB_TYPE) \
790 V(DESCRIPTOR_ARRAY_SUB_TYPE)
791
792 enum FixedArraySubInstanceType {
793 #define DEFINE_FIXED_ARRAY_SUB_INSTANCE_TYPE(name) name,
794 FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(DEFINE_FIXED_ARRAY_SUB_INSTANCE_TYPE)
795 #undef DEFINE_FIXED_ARRAY_SUB_INSTANCE_TYPE
796 LAST_FIXED_ARRAY_SUB_TYPE = DESCRIPTOR_ARRAY_SUB_TYPE
797 };
798
799
800 // TODO(bmeurer): Remove this in favor of the ComparisonResult below.
801 enum CompareResult {
802 LESS = -1,
803 EQUAL = 0,
804 GREATER = 1,
805
806 NOT_EQUAL = GREATER
807 };
808
809
810 // Result of an abstract relational comparison of x and y, implemented according
811 // to ES6 section 7.2.11 Abstract Relational Comparison.
812 enum class ComparisonResult {
813 kLessThan, // x < y
814 kEqual, // x = y
815 kGreaterThan, // x > y
816 kUndefined // at least one of x or y was undefined or NaN
817 };
818
819
820 #define DECL_BOOLEAN_ACCESSORS(name) \
821 inline bool name() const; \
822 inline void set_##name(bool value);
823
824 #define DECL_INT_ACCESSORS(name) \
825 inline int name() const; \
826 inline void set_##name(int value);
827
828
829 #define DECL_ACCESSORS(name, type) \
830 inline type* name() const; \
831 inline void set_##name(type* value, \
832 WriteBarrierMode mode = UPDATE_WRITE_BARRIER); \
833
834
835 #define DECLARE_CAST(type) \
836 INLINE(static type* cast(Object* object)); \
837 INLINE(static const type* cast(const Object* object));
838
839
840 class AccessorPair;
841 class AllocationSite;
842 class AllocationSiteCreationContext;
843 class AllocationSiteUsageContext;
844 class Cell;
845 class ConsString;
846 class ElementsAccessor;
847 class FixedArrayBase;
848 class FunctionLiteral;
849 class JSGlobalObject;
850 class KeyAccumulator;
851 class LayoutDescriptor;
852 class LiteralsArray;
853 class LookupIterator;
854 class FieldType;
855 class ObjectHashTable;
856 class ObjectVisitor;
857 class PropertyCell;
858 class PropertyDescriptor;
859 class SafepointEntry;
860 class SharedFunctionInfo;
861 class StringStream;
862 class TypeFeedbackInfo;
863 class TypeFeedbackMetadata;
864 class TypeFeedbackVector;
865 class WeakCell;
866 class TransitionArray;
867
868
869 // A template-ized version of the IsXXX functions.
870 template <class C> inline bool Is(Object* obj);
871
872 #ifdef VERIFY_HEAP
873 #define DECLARE_VERIFIER(Name) void Name##Verify();
874 #else
875 #define DECLARE_VERIFIER(Name)
876 #endif
877
878 #ifdef OBJECT_PRINT
879 #define DECLARE_PRINTER(Name) void Name##Print(std::ostream& os); // NOLINT
880 #else
881 #define DECLARE_PRINTER(Name)
882 #endif
883
884 #define OBJECT_TYPE_LIST(V) \
885 V(Smi) \
886 V(LayoutDescriptor) \
887 V(HeapObject) \
888 V(Primitive) \
889 V(Number)
890
891 #define HEAP_OBJECT_TYPE_LIST(V) \
892 V(HeapNumber) \
893 V(MutableHeapNumber) \
894 V(Simd128Value) \
895 V(Float32x4) \
896 V(Int32x4) \
897 V(Uint32x4) \
898 V(Bool32x4) \
899 V(Int16x8) \
900 V(Uint16x8) \
901 V(Bool16x8) \
902 V(Int8x16) \
903 V(Uint8x16) \
904 V(Bool8x16) \
905 V(Name) \
906 V(UniqueName) \
907 V(String) \
908 V(SeqString) \
909 V(ExternalString) \
910 V(ConsString) \
911 V(SlicedString) \
912 V(ExternalTwoByteString) \
913 V(ExternalOneByteString) \
914 V(SeqTwoByteString) \
915 V(SeqOneByteString) \
916 V(InternalizedString) \
917 V(Symbol) \
918 \
919 V(FixedTypedArrayBase) \
920 V(FixedUint8Array) \
921 V(FixedInt8Array) \
922 V(FixedUint16Array) \
923 V(FixedInt16Array) \
924 V(FixedUint32Array) \
925 V(FixedInt32Array) \
926 V(FixedFloat32Array) \
927 V(FixedFloat64Array) \
928 V(FixedUint8ClampedArray) \
929 V(ByteArray) \
930 V(BytecodeArray) \
931 V(FreeSpace) \
932 V(JSReceiver) \
933 V(JSObject) \
934 V(JSContextExtensionObject) \
935 V(JSGeneratorObject) \
936 V(JSModule) \
937 V(Map) \
938 V(DescriptorArray) \
939 V(TransitionArray) \
940 V(LiteralsArray) \
941 V(TypeFeedbackMetadata) \
942 V(TypeFeedbackVector) \
943 V(DeoptimizationInputData) \
944 V(DeoptimizationOutputData) \
945 V(DependentCode) \
946 V(HandlerTable) \
947 V(FixedArray) \
948 V(FixedDoubleArray) \
949 V(WeakFixedArray) \
950 V(ArrayList) \
951 V(Context) \
952 V(ScriptContextTable) \
953 V(NativeContext) \
954 V(ScopeInfo) \
955 V(JSBoundFunction) \
956 V(JSFunction) \
957 V(Code) \
958 V(AbstractCode) \
959 V(Oddball) \
960 V(SharedFunctionInfo) \
961 V(JSValue) \
962 V(JSDate) \
963 V(JSMessageObject) \
964 V(StringWrapper) \
965 V(Foreign) \
966 V(Boolean) \
967 V(JSArray) \
968 V(JSArrayBuffer) \
969 V(JSArrayBufferView) \
970 V(JSTypedArray) \
971 V(JSDataView) \
972 V(JSProxy) \
973 V(JSError) \
974 V(JSPromise) \
975 V(JSSet) \
976 V(JSMap) \
977 V(JSSetIterator) \
978 V(JSMapIterator) \
979 V(JSWeakCollection) \
980 V(JSWeakMap) \
981 V(JSWeakSet) \
982 V(JSRegExp) \
983 V(HashTable) \
984 V(Dictionary) \
985 V(StringTable) \
986 V(StringSet) \
987 V(NormalizedMapCache) \
988 V(CompilationCacheTable) \
989 V(CodeCacheHashTable) \
990 V(MapCache) \
991 V(JSGlobalObject) \
992 V(JSGlobalProxy) \
993 V(Undetectable) \
994 V(AccessCheckNeeded) \
995 V(Callable) \
996 V(Function) \
997 V(Constructor) \
998 V(TemplateInfo) \
999 V(Filler) \
1000 V(FixedArrayBase) \
1001 V(External) \
1002 V(Struct) \
1003 V(Cell) \
1004 V(PropertyCell) \
1005 V(WeakCell) \
1006 V(ObjectHashTable) \
1007 V(WeakHashTable) \
1008 V(OrderedHashTable)
1009
1010 #define ODDBALL_LIST(V) \
1011 V(Undefined, undefined_value) \
1012 V(Null, null_value) \
1013 V(TheHole, the_hole_value) \
1014 V(Exception, exception) \
1015 V(Uninitialized, uninitialized_value) \
1016 V(True, true_value) \
1017 V(False, false_value) \
1018 V(ArgumentsMarker, arguments_marker) \
1019 V(OptimizedOut, optimized_out) \
1020 V(StaleRegister, stale_register)
1021
1022 // The element types selection for CreateListFromArrayLike.
1023 enum class ElementTypes { kAll, kStringAndSymbol };
1024
1025 // Object is the abstract superclass for all classes in the
1026 // object hierarchy.
1027 // Object does not use any virtual functions to avoid the
1028 // allocation of the C++ vtable.
1029 // Since both Smi and HeapObject are subclasses of Object no
1030 // data members can be present in Object.
1031 class Object {
1032 public:
1033 // Type testing.
IsObject()1034 bool IsObject() const { return true; }
1035
1036 #define IS_TYPE_FUNCTION_DECL(Type) INLINE(bool Is##Type() const);
1037 OBJECT_TYPE_LIST(IS_TYPE_FUNCTION_DECL)
1038 HEAP_OBJECT_TYPE_LIST(IS_TYPE_FUNCTION_DECL)
1039 #undef IS_TYPE_FUNCTION_DECL
1040 #define IS_TYPE_FUNCTION_DECL(Type, Value) \
1041 INLINE(bool Is##Type(Isolate* isolate) const);
1042 ODDBALL_LIST(IS_TYPE_FUNCTION_DECL)
1043 #undef IS_TYPE_FUNCTION_DECL
1044
1045 // A non-keyed store is of the form a.x = foo or a["x"] = foo whereas
1046 // a keyed store is of the form a[expression] = foo.
1047 enum StoreFromKeyed {
1048 MAY_BE_STORE_FROM_KEYED,
1049 CERTAINLY_NOT_STORE_FROM_KEYED
1050 };
1051
1052 enum ShouldThrow { THROW_ON_ERROR, DONT_THROW };
1053
1054 #define RETURN_FAILURE(isolate, should_throw, call) \
1055 do { \
1056 if ((should_throw) == DONT_THROW) { \
1057 return Just(false); \
1058 } else { \
1059 isolate->Throw(*isolate->factory()->call); \
1060 return Nothing<bool>(); \
1061 } \
1062 } while (false)
1063
1064 #define MAYBE_RETURN(call, value) \
1065 do { \
1066 if ((call).IsNothing()) return value; \
1067 } while (false)
1068
1069 #define MAYBE_RETURN_NULL(call) MAYBE_RETURN(call, MaybeHandle<Object>())
1070
1071 #define DECLARE_STRUCT_PREDICATE(NAME, Name, name) \
1072 INLINE(bool Is##Name() const);
1073 STRUCT_LIST(DECLARE_STRUCT_PREDICATE)
1074 #undef DECLARE_STRUCT_PREDICATE
1075
1076 // ES6, section 7.2.2 IsArray. NOT to be confused with %_IsArray.
1077 MUST_USE_RESULT static Maybe<bool> IsArray(Handle<Object> object);
1078
1079 INLINE(bool IsNameDictionary() const);
1080 INLINE(bool IsGlobalDictionary() const);
1081 INLINE(bool IsSeededNumberDictionary() const);
1082 INLINE(bool IsUnseededNumberDictionary() const);
1083 INLINE(bool IsOrderedHashSet() const);
1084 INLINE(bool IsOrderedHashMap() const);
1085
1086 // Extract the number.
1087 inline double Number() const;
1088 INLINE(bool IsNaN() const);
1089 INLINE(bool IsMinusZero() const);
1090 bool ToInt32(int32_t* value);
1091 inline bool ToUint32(uint32_t* value);
1092
1093 inline Representation OptimalRepresentation();
1094
1095 inline ElementsKind OptimalElementsKind();
1096
1097 inline bool FitsRepresentation(Representation representation);
1098
1099 // Checks whether two valid primitive encodings of a property name resolve to
1100 // the same logical property. E.g., the smi 1, the string "1" and the double
1101 // 1 all refer to the same property, so this helper will return true.
1102 inline bool KeyEquals(Object* other);
1103
1104 inline bool FilterKey(PropertyFilter filter);
1105
1106 Handle<FieldType> OptimalType(Isolate* isolate,
1107 Representation representation);
1108
1109 inline static Handle<Object> NewStorageFor(Isolate* isolate,
1110 Handle<Object> object,
1111 Representation representation);
1112
1113 inline static Handle<Object> WrapForRead(Isolate* isolate,
1114 Handle<Object> object,
1115 Representation representation);
1116
1117 // Returns true if the object is of the correct type to be used as a
1118 // implementation of a JSObject's elements.
1119 inline bool HasValidElements();
1120
1121 inline bool HasSpecificClassOf(String* name);
1122
1123 bool BooleanValue(); // ECMA-262 9.2.
1124
1125 // ES6 section 7.2.11 Abstract Relational Comparison
1126 MUST_USE_RESULT static Maybe<ComparisonResult> Compare(Handle<Object> x,
1127 Handle<Object> y);
1128
1129 // ES6 section 7.2.12 Abstract Equality Comparison
1130 MUST_USE_RESULT static Maybe<bool> Equals(Handle<Object> x, Handle<Object> y);
1131
1132 // ES6 section 7.2.13 Strict Equality Comparison
1133 bool StrictEquals(Object* that);
1134
1135 // Convert to a JSObject if needed.
1136 // native_context is used when creating wrapper object.
1137 MUST_USE_RESULT static inline MaybeHandle<JSReceiver> ToObject(
1138 Isolate* isolate, Handle<Object> object);
1139 MUST_USE_RESULT static MaybeHandle<JSReceiver> ToObject(
1140 Isolate* isolate, Handle<Object> object, Handle<Context> context);
1141
1142 // ES6 section 9.2.1.2, OrdinaryCallBindThis for sloppy callee.
1143 MUST_USE_RESULT static MaybeHandle<JSReceiver> ConvertReceiver(
1144 Isolate* isolate, Handle<Object> object);
1145
1146 // ES6 section 7.1.14 ToPropertyKey
1147 MUST_USE_RESULT static inline MaybeHandle<Name> ToName(Isolate* isolate,
1148 Handle<Object> input);
1149
1150 // ES6 section 7.1.1 ToPrimitive
1151 MUST_USE_RESULT static inline MaybeHandle<Object> ToPrimitive(
1152 Handle<Object> input, ToPrimitiveHint hint = ToPrimitiveHint::kDefault);
1153
1154 // ES6 section 7.1.3 ToNumber
1155 MUST_USE_RESULT static MaybeHandle<Object> ToNumber(Handle<Object> input);
1156
1157 // ES6 section 7.1.4 ToInteger
1158 MUST_USE_RESULT static MaybeHandle<Object> ToInteger(Isolate* isolate,
1159 Handle<Object> input);
1160
1161 // ES6 section 7.1.5 ToInt32
1162 MUST_USE_RESULT static MaybeHandle<Object> ToInt32(Isolate* isolate,
1163 Handle<Object> input);
1164
1165 // ES6 section 7.1.6 ToUint32
1166 MUST_USE_RESULT static MaybeHandle<Object> ToUint32(Isolate* isolate,
1167 Handle<Object> input);
1168
1169 // ES6 section 7.1.12 ToString
1170 MUST_USE_RESULT static MaybeHandle<String> ToString(Isolate* isolate,
1171 Handle<Object> input);
1172
1173 // ES6 section 7.1.14 ToPropertyKey
1174 MUST_USE_RESULT static MaybeHandle<Object> ToPropertyKey(
1175 Isolate* isolate, Handle<Object> value);
1176
1177 // ES6 section 7.1.15 ToLength
1178 MUST_USE_RESULT static MaybeHandle<Object> ToLength(Isolate* isolate,
1179 Handle<Object> input);
1180
1181 // ES6 section 7.3.9 GetMethod
1182 MUST_USE_RESULT static MaybeHandle<Object> GetMethod(
1183 Handle<JSReceiver> receiver, Handle<Name> name);
1184
1185 // ES6 section 7.3.17 CreateListFromArrayLike
1186 MUST_USE_RESULT static MaybeHandle<FixedArray> CreateListFromArrayLike(
1187 Isolate* isolate, Handle<Object> object, ElementTypes element_types);
1188
1189 // Get length property and apply ToLength.
1190 MUST_USE_RESULT static MaybeHandle<Object> GetLengthFromArrayLike(
1191 Isolate* isolate, Handle<Object> object);
1192
1193 // ES6 section 12.5.6 The typeof Operator
1194 static Handle<String> TypeOf(Isolate* isolate, Handle<Object> object);
1195
1196 // ES6 section 12.6 Multiplicative Operators
1197 MUST_USE_RESULT static MaybeHandle<Object> Multiply(Isolate* isolate,
1198 Handle<Object> lhs,
1199 Handle<Object> rhs);
1200 MUST_USE_RESULT static MaybeHandle<Object> Divide(Isolate* isolate,
1201 Handle<Object> lhs,
1202 Handle<Object> rhs);
1203 MUST_USE_RESULT static MaybeHandle<Object> Modulus(Isolate* isolate,
1204 Handle<Object> lhs,
1205 Handle<Object> rhs);
1206
1207 // ES6 section 12.7 Additive Operators
1208 MUST_USE_RESULT static MaybeHandle<Object> Add(Isolate* isolate,
1209 Handle<Object> lhs,
1210 Handle<Object> rhs);
1211 MUST_USE_RESULT static MaybeHandle<Object> Subtract(Isolate* isolate,
1212 Handle<Object> lhs,
1213 Handle<Object> rhs);
1214
1215 // ES6 section 12.8 Bitwise Shift Operators
1216 MUST_USE_RESULT static MaybeHandle<Object> ShiftLeft(Isolate* isolate,
1217 Handle<Object> lhs,
1218 Handle<Object> rhs);
1219 MUST_USE_RESULT static MaybeHandle<Object> ShiftRight(Isolate* isolate,
1220 Handle<Object> lhs,
1221 Handle<Object> rhs);
1222 MUST_USE_RESULT static MaybeHandle<Object> ShiftRightLogical(
1223 Isolate* isolate, Handle<Object> lhs, Handle<Object> rhs);
1224
1225 // ES6 section 12.9 Relational Operators
1226 MUST_USE_RESULT static inline Maybe<bool> GreaterThan(Handle<Object> x,
1227 Handle<Object> y);
1228 MUST_USE_RESULT static inline Maybe<bool> GreaterThanOrEqual(
1229 Handle<Object> x, Handle<Object> y);
1230 MUST_USE_RESULT static inline Maybe<bool> LessThan(Handle<Object> x,
1231 Handle<Object> y);
1232 MUST_USE_RESULT static inline Maybe<bool> LessThanOrEqual(Handle<Object> x,
1233 Handle<Object> y);
1234
1235 // ES6 section 12.11 Binary Bitwise Operators
1236 MUST_USE_RESULT static MaybeHandle<Object> BitwiseAnd(Isolate* isolate,
1237 Handle<Object> lhs,
1238 Handle<Object> rhs);
1239 MUST_USE_RESULT static MaybeHandle<Object> BitwiseOr(Isolate* isolate,
1240 Handle<Object> lhs,
1241 Handle<Object> rhs);
1242 MUST_USE_RESULT static MaybeHandle<Object> BitwiseXor(Isolate* isolate,
1243 Handle<Object> lhs,
1244 Handle<Object> rhs);
1245
1246 // ES6 section 7.3.19 OrdinaryHasInstance (C, O).
1247 MUST_USE_RESULT static MaybeHandle<Object> OrdinaryHasInstance(
1248 Isolate* isolate, Handle<Object> callable, Handle<Object> object);
1249
1250 // ES6 section 12.10.4 Runtime Semantics: InstanceofOperator(O, C)
1251 MUST_USE_RESULT static MaybeHandle<Object> InstanceOf(
1252 Isolate* isolate, Handle<Object> object, Handle<Object> callable);
1253
1254 MUST_USE_RESULT static MaybeHandle<Object> GetProperty(LookupIterator* it);
1255
1256 // ES6 [[Set]] (when passed DONT_THROW)
1257 // Invariants for this and related functions (unless stated otherwise):
1258 // 1) When the result is Nothing, an exception is pending.
1259 // 2) When passed THROW_ON_ERROR, the result is never Just(false).
1260 // In some cases, an exception is thrown regardless of the ShouldThrow
1261 // argument. These cases are either in accordance with the spec or not
1262 // covered by it (eg., concerning API callbacks).
1263 MUST_USE_RESULT static Maybe<bool> SetProperty(LookupIterator* it,
1264 Handle<Object> value,
1265 LanguageMode language_mode,
1266 StoreFromKeyed store_mode);
1267 MUST_USE_RESULT static MaybeHandle<Object> SetProperty(
1268 Handle<Object> object, Handle<Name> name, Handle<Object> value,
1269 LanguageMode language_mode,
1270 StoreFromKeyed store_mode = MAY_BE_STORE_FROM_KEYED);
1271 MUST_USE_RESULT static inline MaybeHandle<Object> SetPropertyOrElement(
1272 Handle<Object> object, Handle<Name> name, Handle<Object> value,
1273 LanguageMode language_mode,
1274 StoreFromKeyed store_mode = MAY_BE_STORE_FROM_KEYED);
1275
1276 MUST_USE_RESULT static Maybe<bool> SetSuperProperty(
1277 LookupIterator* it, Handle<Object> value, LanguageMode language_mode,
1278 StoreFromKeyed store_mode);
1279
1280 MUST_USE_RESULT static MaybeHandle<Object> ReadAbsentProperty(
1281 LookupIterator* it);
1282 MUST_USE_RESULT static MaybeHandle<Object> ReadAbsentProperty(
1283 Isolate* isolate, Handle<Object> receiver, Handle<Object> name);
1284 MUST_USE_RESULT static Maybe<bool> CannotCreateProperty(
1285 Isolate* isolate, Handle<Object> receiver, Handle<Object> name,
1286 Handle<Object> value, ShouldThrow should_throw);
1287 MUST_USE_RESULT static Maybe<bool> WriteToReadOnlyProperty(
1288 LookupIterator* it, Handle<Object> value, ShouldThrow should_throw);
1289 MUST_USE_RESULT static Maybe<bool> WriteToReadOnlyProperty(
1290 Isolate* isolate, Handle<Object> receiver, Handle<Object> name,
1291 Handle<Object> value, ShouldThrow should_throw);
1292 MUST_USE_RESULT static Maybe<bool> RedefineIncompatibleProperty(
1293 Isolate* isolate, Handle<Object> name, Handle<Object> value,
1294 ShouldThrow should_throw);
1295 MUST_USE_RESULT static Maybe<bool> SetDataProperty(LookupIterator* it,
1296 Handle<Object> value);
1297 MUST_USE_RESULT static Maybe<bool> AddDataProperty(
1298 LookupIterator* it, Handle<Object> value, PropertyAttributes attributes,
1299 ShouldThrow should_throw, StoreFromKeyed store_mode);
1300 MUST_USE_RESULT static inline MaybeHandle<Object> GetPropertyOrElement(
1301 Handle<Object> object, Handle<Name> name);
1302 MUST_USE_RESULT static inline MaybeHandle<Object> GetPropertyOrElement(
1303 Handle<Object> receiver, Handle<Name> name, Handle<JSReceiver> holder);
1304 MUST_USE_RESULT static inline MaybeHandle<Object> GetProperty(
1305 Handle<Object> object, Handle<Name> name);
1306
1307 MUST_USE_RESULT static MaybeHandle<Object> GetPropertyWithAccessor(
1308 LookupIterator* it);
1309 MUST_USE_RESULT static Maybe<bool> SetPropertyWithAccessor(
1310 LookupIterator* it, Handle<Object> value, ShouldThrow should_throw);
1311
1312 MUST_USE_RESULT static MaybeHandle<Object> GetPropertyWithDefinedGetter(
1313 Handle<Object> receiver,
1314 Handle<JSReceiver> getter);
1315 MUST_USE_RESULT static Maybe<bool> SetPropertyWithDefinedSetter(
1316 Handle<Object> receiver, Handle<JSReceiver> setter, Handle<Object> value,
1317 ShouldThrow should_throw);
1318
1319 MUST_USE_RESULT static inline MaybeHandle<Object> GetElement(
1320 Isolate* isolate, Handle<Object> object, uint32_t index);
1321
1322 MUST_USE_RESULT static inline MaybeHandle<Object> SetElement(
1323 Isolate* isolate, Handle<Object> object, uint32_t index,
1324 Handle<Object> value, LanguageMode language_mode);
1325
1326 // Returns the permanent hash code associated with this object. May return
1327 // undefined if not yet created.
1328 Object* GetHash();
1329
1330 // Returns the permanent hash code associated with this object depending on
1331 // the actual object type. May create and store a hash code if needed and none
1332 // exists.
1333 static Smi* GetOrCreateHash(Isolate* isolate, Handle<Object> object);
1334
1335 // Checks whether this object has the same value as the given one. This
1336 // function is implemented according to ES5, section 9.12 and can be used
1337 // to implement the Harmony "egal" function.
1338 bool SameValue(Object* other);
1339
1340 // Checks whether this object has the same value as the given one.
1341 // +0 and -0 are treated equal. Everything else is the same as SameValue.
1342 // This function is implemented according to ES6, section 7.2.4 and is used
1343 // by ES6 Map and Set.
1344 bool SameValueZero(Object* other);
1345
1346 // ES6 section 9.4.2.3 ArraySpeciesCreate (part of it)
1347 MUST_USE_RESULT static MaybeHandle<Object> ArraySpeciesConstructor(
1348 Isolate* isolate, Handle<Object> original_array);
1349
1350 // Tries to convert an object to an array length. Returns true and sets the
1351 // output parameter if it succeeds.
1352 inline bool ToArrayLength(uint32_t* index);
1353
1354 // Tries to convert an object to an array index. Returns true and sets the
1355 // output parameter if it succeeds. Equivalent to ToArrayLength, but does not
1356 // allow kMaxUInt32.
1357 inline bool ToArrayIndex(uint32_t* index);
1358
1359 DECLARE_VERIFIER(Object)
1360 #ifdef VERIFY_HEAP
1361 // Verify a pointer is a valid object pointer.
1362 static void VerifyPointer(Object* p);
1363 #endif
1364
1365 inline void VerifyApiCallResultType();
1366
1367 // ES6 19.1.3.6 Object.prototype.toString
1368 MUST_USE_RESULT static MaybeHandle<String> ObjectProtoToString(
1369 Isolate* isolate, Handle<Object> object);
1370
1371 // Prints this object without details.
1372 void ShortPrint(FILE* out = stdout);
1373
1374 // Prints this object without details to a message accumulator.
1375 void ShortPrint(StringStream* accumulator);
1376
1377 void ShortPrint(std::ostream& os); // NOLINT
1378
1379 DECLARE_CAST(Object)
1380
1381 // Layout description.
1382 static const int kHeaderSize = 0; // Object does not take up any space.
1383
1384 #ifdef OBJECT_PRINT
1385 // For our gdb macros, we should perhaps change these in the future.
1386 void Print();
1387
1388 // Prints this object with details.
1389 void Print(std::ostream& os); // NOLINT
1390 #else
Print()1391 void Print() { ShortPrint(); }
Print(std::ostream & os)1392 void Print(std::ostream& os) { ShortPrint(os); } // NOLINT
1393 #endif
1394
1395 private:
1396 friend class LookupIterator;
1397 friend class StringStream;
1398
1399 // Return the map of the root of object's prototype chain.
1400 Map* GetRootMap(Isolate* isolate);
1401
1402 // Helper for SetProperty and SetSuperProperty.
1403 // Return value is only meaningful if [found] is set to true on return.
1404 MUST_USE_RESULT static Maybe<bool> SetPropertyInternal(
1405 LookupIterator* it, Handle<Object> value, LanguageMode language_mode,
1406 StoreFromKeyed store_mode, bool* found);
1407
1408 MUST_USE_RESULT static MaybeHandle<Name> ConvertToName(Isolate* isolate,
1409 Handle<Object> input);
1410
1411 DISALLOW_IMPLICIT_CONSTRUCTORS(Object);
1412 };
1413
1414
1415 // In objects.h to be usable without objects-inl.h inclusion.
IsSmi()1416 bool Object::IsSmi() const { return HAS_SMI_TAG(this); }
IsHeapObject()1417 bool Object::IsHeapObject() const { return Internals::HasHeapObjectTag(this); }
1418
1419
1420 struct Brief {
BriefBrief1421 explicit Brief(const Object* const v) : value(v) {}
1422 const Object* value;
1423 };
1424
1425
1426 std::ostream& operator<<(std::ostream& os, const Brief& v);
1427
1428
1429 // Smi represents integer Numbers that can be stored in 31 bits.
1430 // Smis are immediate which means they are NOT allocated in the heap.
1431 // The this pointer has the following format: [31 bit signed int] 0
1432 // For long smis it has the following format:
1433 // [32 bit signed int] [31 bits zero padding] 0
1434 // Smi stands for small integer.
1435 class Smi: public Object {
1436 public:
1437 // Returns the integer value.
value()1438 inline int value() const { return Internals::SmiValue(this); }
1439
1440 // Convert a value to a Smi object.
FromInt(int value)1441 static inline Smi* FromInt(int value) {
1442 DCHECK(Smi::IsValid(value));
1443 return reinterpret_cast<Smi*>(Internals::IntToSmi(value));
1444 }
1445
FromIntptr(intptr_t value)1446 static inline Smi* FromIntptr(intptr_t value) {
1447 DCHECK(Smi::IsValid(value));
1448 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
1449 return reinterpret_cast<Smi*>((value << smi_shift_bits) | kSmiTag);
1450 }
1451
1452 // Returns whether value can be represented in a Smi.
IsValid(intptr_t value)1453 static inline bool IsValid(intptr_t value) {
1454 bool result = Internals::IsValidSmi(value);
1455 DCHECK_EQ(result, value >= kMinValue && value <= kMaxValue);
1456 return result;
1457 }
1458
1459 DECLARE_CAST(Smi)
1460
1461 // Dispatched behavior.
1462 void SmiPrint(std::ostream& os) const; // NOLINT
1463 DECLARE_VERIFIER(Smi)
1464
1465 static const int kMinValue =
1466 (static_cast<unsigned int>(-1)) << (kSmiValueSize - 1);
1467 static const int kMaxValue = -(kMinValue + 1);
1468
1469 private:
1470 DISALLOW_IMPLICIT_CONSTRUCTORS(Smi);
1471 };
1472
1473
1474 // Heap objects typically have a map pointer in their first word. However,
1475 // during GC other data (e.g. mark bits, forwarding addresses) is sometimes
1476 // encoded in the first word. The class MapWord is an abstraction of the
1477 // value in a heap object's first word.
1478 class MapWord BASE_EMBEDDED {
1479 public:
1480 // Normal state: the map word contains a map pointer.
1481
1482 // Create a map word from a map pointer.
1483 static inline MapWord FromMap(const Map* map);
1484
1485 // View this map word as a map pointer.
1486 inline Map* ToMap();
1487
1488
1489 // Scavenge collection: the map word of live objects in the from space
1490 // contains a forwarding address (a heap object pointer in the to space).
1491
1492 // True if this map word is a forwarding address for a scavenge
1493 // collection. Only valid during a scavenge collection (specifically,
1494 // when all map words are heap object pointers, i.e. not during a full GC).
1495 inline bool IsForwardingAddress() const;
1496
1497 // Create a map word from a forwarding address.
1498 static inline MapWord FromForwardingAddress(HeapObject* object);
1499
1500 // View this map word as a forwarding address.
1501 inline HeapObject* ToForwardingAddress();
1502
FromRawValue(uintptr_t value)1503 static inline MapWord FromRawValue(uintptr_t value) {
1504 return MapWord(value);
1505 }
1506
ToRawValue()1507 inline uintptr_t ToRawValue() {
1508 return value_;
1509 }
1510
1511 private:
1512 // HeapObject calls the private constructor and directly reads the value.
1513 friend class HeapObject;
1514
MapWord(uintptr_t value)1515 explicit MapWord(uintptr_t value) : value_(value) {}
1516
1517 uintptr_t value_;
1518 };
1519
1520
1521 // HeapObject is the superclass for all classes describing heap allocated
1522 // objects.
1523 class HeapObject: public Object {
1524 public:
1525 // [map]: Contains a map which contains the object's reflective
1526 // information.
1527 inline Map* map() const;
1528 inline void set_map(Map* value);
1529 // The no-write-barrier version. This is OK if the object is white and in
1530 // new space, or if the value is an immortal immutable object, like the maps
1531 // of primitive (non-JS) objects like strings, heap numbers etc.
1532 inline void set_map_no_write_barrier(Map* value);
1533
1534 // Get the map using acquire load.
1535 inline Map* synchronized_map();
1536 inline MapWord synchronized_map_word() const;
1537
1538 // Set the map using release store
1539 inline void synchronized_set_map(Map* value);
1540 inline void synchronized_set_map_no_write_barrier(Map* value);
1541 inline void synchronized_set_map_word(MapWord map_word);
1542
1543 // During garbage collection, the map word of a heap object does not
1544 // necessarily contain a map pointer.
1545 inline MapWord map_word() const;
1546 inline void set_map_word(MapWord map_word);
1547
1548 // The Heap the object was allocated in. Used also to access Isolate.
1549 inline Heap* GetHeap() const;
1550
1551 // Convenience method to get current isolate.
1552 inline Isolate* GetIsolate() const;
1553
1554 #define IS_TYPE_FUNCTION_DECL(Type) INLINE(bool Is##Type() const);
1555 HEAP_OBJECT_TYPE_LIST(IS_TYPE_FUNCTION_DECL)
1556 #undef IS_TYPE_FUNCTION_DECL
1557
1558 #define IS_TYPE_FUNCTION_DECL(Type, Value) \
1559 INLINE(bool Is##Type(Isolate* isolate) const);
ODDBALL_LIST(IS_TYPE_FUNCTION_DECL)1560 ODDBALL_LIST(IS_TYPE_FUNCTION_DECL)
1561 #undef IS_TYPE_FUNCTION_DECL
1562
1563 #define DECLARE_STRUCT_PREDICATE(NAME, Name, name) \
1564 INLINE(bool Is##Name() const);
1565 STRUCT_LIST(DECLARE_STRUCT_PREDICATE)
1566 #undef DECLARE_STRUCT_PREDICATE
1567
1568 // Converts an address to a HeapObject pointer.
1569 static inline HeapObject* FromAddress(Address address) {
1570 DCHECK_TAG_ALIGNED(address);
1571 return reinterpret_cast<HeapObject*>(address + kHeapObjectTag);
1572 }
1573
1574 // Returns the address of this HeapObject.
address()1575 inline Address address() {
1576 return reinterpret_cast<Address>(this) - kHeapObjectTag;
1577 }
1578
1579 // Iterates over pointers contained in the object (including the Map).
1580 // If it's not performance critical iteration use the non-templatized
1581 // version.
1582 void Iterate(ObjectVisitor* v);
1583
1584 template <typename ObjectVisitor>
1585 inline void IterateFast(ObjectVisitor* v);
1586
1587 // Iterates over all pointers contained in the object except the
1588 // first map pointer. The object type is given in the first
1589 // parameter. This function does not access the map pointer in the
1590 // object, and so is safe to call while the map pointer is modified.
1591 // If it's not performance critical iteration use the non-templatized
1592 // version.
1593 void IterateBody(ObjectVisitor* v);
1594 void IterateBody(InstanceType type, int object_size, ObjectVisitor* v);
1595
1596 template <typename ObjectVisitor>
1597 inline void IterateBodyFast(ObjectVisitor* v);
1598
1599 template <typename ObjectVisitor>
1600 inline void IterateBodyFast(InstanceType type, int object_size,
1601 ObjectVisitor* v);
1602
1603 // Returns true if the object contains a tagged value at given offset.
1604 // It is used for invalid slots filtering. If the offset points outside
1605 // of the object or to the map word, the result is UNDEFINED (!!!).
1606 bool IsValidSlot(int offset);
1607
1608 // Returns the heap object's size in bytes
1609 inline int Size();
1610
1611 // Given a heap object's map pointer, returns the heap size in bytes
1612 // Useful when the map pointer field is used for other purposes.
1613 // GC internal.
1614 inline int SizeFromMap(Map* map);
1615
1616 // Returns the field at offset in obj, as a read/write Object* reference.
1617 // Does no checking, and is safe to use during GC, while maps are invalid.
1618 // Does not invoke write barrier, so should only be assigned to
1619 // during marking GC.
1620 static inline Object** RawField(HeapObject* obj, int offset);
1621
1622 // Adds the |code| object related to |name| to the code cache of this map. If
1623 // this map is a dictionary map that is shared, the map copied and installed
1624 // onto the object.
1625 static void UpdateMapCodeCache(Handle<HeapObject> object,
1626 Handle<Name> name,
1627 Handle<Code> code);
1628
1629 DECLARE_CAST(HeapObject)
1630
1631 // Return the write barrier mode for this. Callers of this function
1632 // must be able to present a reference to an DisallowHeapAllocation
1633 // object as a sign that they are not going to use this function
1634 // from code that allocates and thus invalidates the returned write
1635 // barrier mode.
1636 inline WriteBarrierMode GetWriteBarrierMode(
1637 const DisallowHeapAllocation& promise);
1638
1639 // Dispatched behavior.
1640 void HeapObjectShortPrint(std::ostream& os); // NOLINT
1641 #ifdef OBJECT_PRINT
1642 void PrintHeader(std::ostream& os, const char* id); // NOLINT
1643 #endif
1644 DECLARE_PRINTER(HeapObject)
1645 DECLARE_VERIFIER(HeapObject)
1646 #ifdef VERIFY_HEAP
1647 inline void VerifyObjectField(int offset);
1648 inline void VerifySmiField(int offset);
1649
1650 // Verify a pointer is a valid HeapObject pointer that points to object
1651 // areas in the heap.
1652 static void VerifyHeapPointer(Object* p);
1653 #endif
1654
1655 inline AllocationAlignment RequiredAlignment();
1656
1657 // Layout description.
1658 // First field in a heap object is map.
1659 static const int kMapOffset = Object::kHeaderSize;
1660 static const int kHeaderSize = kMapOffset + kPointerSize;
1661
1662 STATIC_ASSERT(kMapOffset == Internals::kHeapObjectMapOffset);
1663
1664 private:
1665 DISALLOW_IMPLICIT_CONSTRUCTORS(HeapObject);
1666 };
1667
1668
1669 template <int start_offset, int end_offset, int size>
1670 class FixedBodyDescriptor;
1671
1672
1673 template <int start_offset>
1674 class FlexibleBodyDescriptor;
1675
1676
1677 // The HeapNumber class describes heap allocated numbers that cannot be
1678 // represented in a Smi (small integer)
1679 class HeapNumber: public HeapObject {
1680 public:
1681 // [value]: number value.
1682 inline double value() const;
1683 inline void set_value(double value);
1684
1685 DECLARE_CAST(HeapNumber)
1686
1687 // Dispatched behavior.
1688 bool HeapNumberBooleanValue();
1689
1690 void HeapNumberPrint(std::ostream& os); // NOLINT
1691 DECLARE_VERIFIER(HeapNumber)
1692
1693 inline int get_exponent();
1694 inline int get_sign();
1695
1696 // Layout description.
1697 static const int kValueOffset = HeapObject::kHeaderSize;
1698 // IEEE doubles are two 32 bit words. The first is just mantissa, the second
1699 // is a mixture of sign, exponent and mantissa. The offsets of two 32 bit
1700 // words within double numbers are endian dependent and they are set
1701 // accordingly.
1702 #if defined(V8_TARGET_LITTLE_ENDIAN)
1703 static const int kMantissaOffset = kValueOffset;
1704 static const int kExponentOffset = kValueOffset + 4;
1705 #elif defined(V8_TARGET_BIG_ENDIAN)
1706 static const int kMantissaOffset = kValueOffset + 4;
1707 static const int kExponentOffset = kValueOffset;
1708 #else
1709 #error Unknown byte ordering
1710 #endif
1711
1712 static const int kSize = kValueOffset + kDoubleSize;
1713 static const uint32_t kSignMask = 0x80000000u;
1714 static const uint32_t kExponentMask = 0x7ff00000u;
1715 static const uint32_t kMantissaMask = 0xfffffu;
1716 static const int kMantissaBits = 52;
1717 static const int kExponentBits = 11;
1718 static const int kExponentBias = 1023;
1719 static const int kExponentShift = 20;
1720 static const int kInfinityOrNanExponent =
1721 (kExponentMask >> kExponentShift) - kExponentBias;
1722 static const int kMantissaBitsInTopWord = 20;
1723 static const int kNonMantissaBitsInTopWord = 12;
1724
1725 private:
1726 DISALLOW_IMPLICIT_CONSTRUCTORS(HeapNumber);
1727 };
1728
1729
1730 // The Simd128Value class describes heap allocated 128 bit SIMD values.
1731 class Simd128Value : public HeapObject {
1732 public:
1733 DECLARE_CAST(Simd128Value)
1734
1735 DECLARE_PRINTER(Simd128Value)
1736 DECLARE_VERIFIER(Simd128Value)
1737
1738 static Handle<String> ToString(Handle<Simd128Value> input);
1739
1740 // Equality operations.
1741 inline bool Equals(Simd128Value* that);
1742 static inline bool Equals(Handle<Simd128Value> one, Handle<Simd128Value> two);
1743
1744 // Checks that another instance is bit-wise equal.
1745 bool BitwiseEquals(const Simd128Value* other) const;
1746 // Computes a hash from the 128 bit value, viewed as 4 32-bit integers.
1747 uint32_t Hash() const;
1748 // Copies the 16 bytes of SIMD data to the destination address.
1749 void CopyBits(void* destination) const;
1750
1751 // Layout description.
1752 static const int kValueOffset = HeapObject::kHeaderSize;
1753 static const int kSize = kValueOffset + kSimd128Size;
1754
1755 private:
1756 DISALLOW_IMPLICIT_CONSTRUCTORS(Simd128Value);
1757 };
1758
1759
1760 // V has parameters (TYPE, Type, type, lane count, lane type)
1761 #define SIMD128_TYPES(V) \
1762 V(FLOAT32X4, Float32x4, float32x4, 4, float) \
1763 V(INT32X4, Int32x4, int32x4, 4, int32_t) \
1764 V(UINT32X4, Uint32x4, uint32x4, 4, uint32_t) \
1765 V(BOOL32X4, Bool32x4, bool32x4, 4, bool) \
1766 V(INT16X8, Int16x8, int16x8, 8, int16_t) \
1767 V(UINT16X8, Uint16x8, uint16x8, 8, uint16_t) \
1768 V(BOOL16X8, Bool16x8, bool16x8, 8, bool) \
1769 V(INT8X16, Int8x16, int8x16, 16, int8_t) \
1770 V(UINT8X16, Uint8x16, uint8x16, 16, uint8_t) \
1771 V(BOOL8X16, Bool8x16, bool8x16, 16, bool)
1772
1773 #define SIMD128_VALUE_CLASS(TYPE, Type, type, lane_count, lane_type) \
1774 class Type final : public Simd128Value { \
1775 public: \
1776 inline lane_type get_lane(int lane) const; \
1777 inline void set_lane(int lane, lane_type value); \
1778 \
1779 DECLARE_CAST(Type) \
1780 \
1781 DECLARE_PRINTER(Type) \
1782 \
1783 static Handle<String> ToString(Handle<Type> input); \
1784 \
1785 inline bool Equals(Type* that); \
1786 \
1787 private: \
1788 DISALLOW_IMPLICIT_CONSTRUCTORS(Type); \
1789 };
1790 SIMD128_TYPES(SIMD128_VALUE_CLASS)
1791 #undef SIMD128_VALUE_CLASS
1792
1793
1794 enum EnsureElementsMode {
1795 DONT_ALLOW_DOUBLE_ELEMENTS,
1796 ALLOW_COPIED_DOUBLE_ELEMENTS,
1797 ALLOW_CONVERTED_DOUBLE_ELEMENTS
1798 };
1799
1800
1801 // Indicator for one component of an AccessorPair.
1802 enum AccessorComponent {
1803 ACCESSOR_GETTER,
1804 ACCESSOR_SETTER
1805 };
1806
1807 enum class GetKeysConversion { kKeepNumbers, kConvertToString };
1808
1809 enum class KeyCollectionMode {
1810 kOwnOnly = static_cast<int>(v8::KeyCollectionMode::kOwnOnly),
1811 kIncludePrototypes =
1812 static_cast<int>(v8::KeyCollectionMode::kIncludePrototypes)
1813 };
1814
1815 // JSReceiver includes types on which properties can be defined, i.e.,
1816 // JSObject and JSProxy.
1817 class JSReceiver: public HeapObject {
1818 public:
1819 // [properties]: Backing storage for properties.
1820 // properties is a FixedArray in the fast case and a Dictionary in the
1821 // slow case.
1822 DECL_ACCESSORS(properties, FixedArray) // Get and set fast properties.
1823 inline void initialize_properties();
1824 inline bool HasFastProperties();
1825 // Gets slow properties for non-global objects.
1826 inline NameDictionary* property_dictionary();
1827
1828 // Deletes an existing named property in a normalized object.
1829 static void DeleteNormalizedProperty(Handle<JSReceiver> object,
1830 Handle<Name> name, int entry);
1831
1832 DECLARE_CAST(JSReceiver)
1833
1834 // ES6 section 7.1.1 ToPrimitive
1835 MUST_USE_RESULT static MaybeHandle<Object> ToPrimitive(
1836 Handle<JSReceiver> receiver,
1837 ToPrimitiveHint hint = ToPrimitiveHint::kDefault);
1838 MUST_USE_RESULT static MaybeHandle<Object> OrdinaryToPrimitive(
1839 Handle<JSReceiver> receiver, OrdinaryToPrimitiveHint hint);
1840
1841 static MaybeHandle<Context> GetFunctionRealm(Handle<JSReceiver> receiver);
1842
1843 // Get the first non-hidden prototype.
1844 static inline MaybeHandle<Object> GetPrototype(Isolate* isolate,
1845 Handle<JSReceiver> receiver);
1846
1847 MUST_USE_RESULT static Maybe<bool> HasInPrototypeChain(
1848 Isolate* isolate, Handle<JSReceiver> object, Handle<Object> proto);
1849
1850 // Implementation of [[HasProperty]], ECMA-262 5th edition, section 8.12.6.
1851 MUST_USE_RESULT static Maybe<bool> HasProperty(LookupIterator* it);
1852 MUST_USE_RESULT static inline Maybe<bool> HasProperty(
1853 Handle<JSReceiver> object, Handle<Name> name);
1854 MUST_USE_RESULT static inline Maybe<bool> HasElement(
1855 Handle<JSReceiver> object, uint32_t index);
1856
1857 MUST_USE_RESULT static inline Maybe<bool> HasOwnProperty(
1858 Handle<JSReceiver> object, Handle<Name> name);
1859 MUST_USE_RESULT static inline Maybe<bool> HasOwnProperty(
1860 Handle<JSReceiver> object, uint32_t index);
1861
1862 MUST_USE_RESULT static inline MaybeHandle<Object> GetProperty(
1863 Isolate* isolate, Handle<JSReceiver> receiver, const char* key);
1864 MUST_USE_RESULT static inline MaybeHandle<Object> GetProperty(
1865 Handle<JSReceiver> receiver, Handle<Name> name);
1866 MUST_USE_RESULT static inline MaybeHandle<Object> GetElement(
1867 Isolate* isolate, Handle<JSReceiver> receiver, uint32_t index);
1868
1869 // Implementation of ES6 [[Delete]]
1870 MUST_USE_RESULT static Maybe<bool> DeletePropertyOrElement(
1871 Handle<JSReceiver> object, Handle<Name> name,
1872 LanguageMode language_mode = SLOPPY);
1873 MUST_USE_RESULT static Maybe<bool> DeleteProperty(
1874 Handle<JSReceiver> object, Handle<Name> name,
1875 LanguageMode language_mode = SLOPPY);
1876 MUST_USE_RESULT static Maybe<bool> DeleteProperty(LookupIterator* it,
1877 LanguageMode language_mode);
1878 MUST_USE_RESULT static Maybe<bool> DeleteElement(
1879 Handle<JSReceiver> object, uint32_t index,
1880 LanguageMode language_mode = SLOPPY);
1881
1882 MUST_USE_RESULT static Object* DefineProperty(Isolate* isolate,
1883 Handle<Object> object,
1884 Handle<Object> name,
1885 Handle<Object> attributes);
1886 MUST_USE_RESULT static MaybeHandle<Object> DefineProperties(
1887 Isolate* isolate, Handle<Object> object, Handle<Object> properties);
1888
1889 // "virtual" dispatcher to the correct [[DefineOwnProperty]] implementation.
1890 MUST_USE_RESULT static Maybe<bool> DefineOwnProperty(
1891 Isolate* isolate, Handle<JSReceiver> object, Handle<Object> key,
1892 PropertyDescriptor* desc, ShouldThrow should_throw);
1893
1894 // ES6 7.3.4 (when passed DONT_THROW)
1895 MUST_USE_RESULT static Maybe<bool> CreateDataProperty(
1896 LookupIterator* it, Handle<Object> value, ShouldThrow should_throw);
1897
1898 // ES6 9.1.6.1
1899 MUST_USE_RESULT static Maybe<bool> OrdinaryDefineOwnProperty(
1900 Isolate* isolate, Handle<JSObject> object, Handle<Object> key,
1901 PropertyDescriptor* desc, ShouldThrow should_throw);
1902 MUST_USE_RESULT static Maybe<bool> OrdinaryDefineOwnProperty(
1903 LookupIterator* it, PropertyDescriptor* desc, ShouldThrow should_throw);
1904 // ES6 9.1.6.2
1905 MUST_USE_RESULT static Maybe<bool> IsCompatiblePropertyDescriptor(
1906 Isolate* isolate, bool extensible, PropertyDescriptor* desc,
1907 PropertyDescriptor* current, Handle<Name> property_name,
1908 ShouldThrow should_throw);
1909 // ES6 9.1.6.3
1910 // |it| can be NULL in cases where the ES spec passes |undefined| as the
1911 // receiver. Exactly one of |it| and |property_name| must be provided.
1912 MUST_USE_RESULT static Maybe<bool> ValidateAndApplyPropertyDescriptor(
1913 Isolate* isolate, LookupIterator* it, bool extensible,
1914 PropertyDescriptor* desc, PropertyDescriptor* current,
1915 ShouldThrow should_throw, Handle<Name> property_name = Handle<Name>());
1916
1917 MUST_USE_RESULT static Maybe<bool> GetOwnPropertyDescriptor(
1918 Isolate* isolate, Handle<JSReceiver> object, Handle<Object> key,
1919 PropertyDescriptor* desc);
1920 MUST_USE_RESULT static Maybe<bool> GetOwnPropertyDescriptor(
1921 LookupIterator* it, PropertyDescriptor* desc);
1922
1923 typedef PropertyAttributes IntegrityLevel;
1924
1925 // ES6 7.3.14 (when passed DONT_THROW)
1926 // 'level' must be SEALED or FROZEN.
1927 MUST_USE_RESULT static Maybe<bool> SetIntegrityLevel(
1928 Handle<JSReceiver> object, IntegrityLevel lvl, ShouldThrow should_throw);
1929
1930 // ES6 7.3.15
1931 // 'level' must be SEALED or FROZEN.
1932 MUST_USE_RESULT static Maybe<bool> TestIntegrityLevel(
1933 Handle<JSReceiver> object, IntegrityLevel lvl);
1934
1935 // ES6 [[PreventExtensions]] (when passed DONT_THROW)
1936 MUST_USE_RESULT static Maybe<bool> PreventExtensions(
1937 Handle<JSReceiver> object, ShouldThrow should_throw);
1938
1939 MUST_USE_RESULT static Maybe<bool> IsExtensible(Handle<JSReceiver> object);
1940
1941 // Returns the class name ([[Class]] property in the specification).
1942 String* class_name();
1943
1944 // Returns the constructor name (the name (possibly, inferred name) of the
1945 // function that was used to instantiate the object).
1946 static Handle<String> GetConstructorName(Handle<JSReceiver> receiver);
1947
1948 Context* GetCreationContext();
1949
1950 MUST_USE_RESULT static inline Maybe<PropertyAttributes> GetPropertyAttributes(
1951 Handle<JSReceiver> object, Handle<Name> name);
1952 MUST_USE_RESULT static inline Maybe<PropertyAttributes>
1953 GetOwnPropertyAttributes(Handle<JSReceiver> object, Handle<Name> name);
1954 MUST_USE_RESULT static inline Maybe<PropertyAttributes>
1955 GetOwnPropertyAttributes(Handle<JSReceiver> object, uint32_t index);
1956
1957 MUST_USE_RESULT static inline Maybe<PropertyAttributes> GetElementAttributes(
1958 Handle<JSReceiver> object, uint32_t index);
1959 MUST_USE_RESULT static inline Maybe<PropertyAttributes>
1960 GetOwnElementAttributes(Handle<JSReceiver> object, uint32_t index);
1961
1962 MUST_USE_RESULT static Maybe<PropertyAttributes> GetPropertyAttributes(
1963 LookupIterator* it);
1964
1965 // Set the object's prototype (only JSReceiver and null are allowed values).
1966 MUST_USE_RESULT static Maybe<bool> SetPrototype(Handle<JSReceiver> object,
1967 Handle<Object> value,
1968 bool from_javascript,
1969 ShouldThrow should_throw);
1970
1971 inline static Handle<Object> GetDataProperty(Handle<JSReceiver> object,
1972 Handle<Name> name);
1973 static Handle<Object> GetDataProperty(LookupIterator* it);
1974
1975
1976 // Retrieves a permanent object identity hash code. The undefined value might
1977 // be returned in case no hash was created yet.
1978 static inline Object* GetIdentityHash(Isolate* isolate,
1979 Handle<JSReceiver> object);
1980
1981 // Retrieves a permanent object identity hash code. May create and store a
1982 // hash code if needed and none exists.
1983 inline static Smi* GetOrCreateIdentityHash(Isolate* isolate,
1984 Handle<JSReceiver> object);
1985
1986 // ES6 [[OwnPropertyKeys]] (modulo return type)
1987 MUST_USE_RESULT static inline MaybeHandle<FixedArray> OwnPropertyKeys(
1988 Handle<JSReceiver> object);
1989
1990 MUST_USE_RESULT static MaybeHandle<FixedArray> GetOwnValues(
1991 Handle<JSReceiver> object, PropertyFilter filter);
1992
1993 MUST_USE_RESULT static MaybeHandle<FixedArray> GetOwnEntries(
1994 Handle<JSReceiver> object, PropertyFilter filter);
1995
1996 // Layout description.
1997 static const int kPropertiesOffset = HeapObject::kHeaderSize;
1998 static const int kHeaderSize = HeapObject::kHeaderSize + kPointerSize;
1999
2000 private:
2001 DISALLOW_IMPLICIT_CONSTRUCTORS(JSReceiver);
2002 };
2003
2004
2005 // The JSObject describes real heap allocated JavaScript objects with
2006 // properties.
2007 // Note that the map of JSObject changes during execution to enable inline
2008 // caching.
2009 class JSObject: public JSReceiver {
2010 public:
2011 static MUST_USE_RESULT MaybeHandle<JSObject> New(
2012 Handle<JSFunction> constructor, Handle<JSReceiver> new_target,
2013 Handle<AllocationSite> site = Handle<AllocationSite>::null());
2014
2015 // Gets global object properties.
2016 inline GlobalDictionary* global_dictionary();
2017
2018 static MaybeHandle<Context> GetFunctionRealm(Handle<JSObject> object);
2019
2020 // [elements]: The elements (properties with names that are integers).
2021 //
2022 // Elements can be in two general modes: fast and slow. Each mode
2023 // corrensponds to a set of object representations of elements that
2024 // have something in common.
2025 //
2026 // In the fast mode elements is a FixedArray and so each element can
2027 // be quickly accessed. This fact is used in the generated code. The
2028 // elements array can have one of three maps in this mode:
2029 // fixed_array_map, sloppy_arguments_elements_map or
2030 // fixed_cow_array_map (for copy-on-write arrays). In the latter case
2031 // the elements array may be shared by a few objects and so before
2032 // writing to any element the array must be copied. Use
2033 // EnsureWritableFastElements in this case.
2034 //
2035 // In the slow mode the elements is either a NumberDictionary, a
2036 // FixedArray parameter map for a (sloppy) arguments object.
2037 DECL_ACCESSORS(elements, FixedArrayBase)
2038 inline void initialize_elements();
2039 static void ResetElements(Handle<JSObject> object);
2040 static inline void SetMapAndElements(Handle<JSObject> object,
2041 Handle<Map> map,
2042 Handle<FixedArrayBase> elements);
2043 inline ElementsKind GetElementsKind();
2044 ElementsAccessor* GetElementsAccessor();
2045 // Returns true if an object has elements of FAST_SMI_ELEMENTS ElementsKind.
2046 inline bool HasFastSmiElements();
2047 // Returns true if an object has elements of FAST_ELEMENTS ElementsKind.
2048 inline bool HasFastObjectElements();
2049 // Returns true if an object has elements of FAST_ELEMENTS or
2050 // FAST_SMI_ONLY_ELEMENTS.
2051 inline bool HasFastSmiOrObjectElements();
2052 // Returns true if an object has any of the fast elements kinds.
2053 inline bool HasFastElements();
2054 // Returns true if an object has elements of FAST_DOUBLE_ELEMENTS
2055 // ElementsKind.
2056 inline bool HasFastDoubleElements();
2057 // Returns true if an object has elements of FAST_HOLEY_*_ELEMENTS
2058 // ElementsKind.
2059 inline bool HasFastHoleyElements();
2060 inline bool HasSloppyArgumentsElements();
2061 inline bool HasStringWrapperElements();
2062 inline bool HasDictionaryElements();
2063
2064 inline bool HasFixedTypedArrayElements();
2065
2066 inline bool HasFixedUint8ClampedElements();
2067 inline bool HasFixedArrayElements();
2068 inline bool HasFixedInt8Elements();
2069 inline bool HasFixedUint8Elements();
2070 inline bool HasFixedInt16Elements();
2071 inline bool HasFixedUint16Elements();
2072 inline bool HasFixedInt32Elements();
2073 inline bool HasFixedUint32Elements();
2074 inline bool HasFixedFloat32Elements();
2075 inline bool HasFixedFloat64Elements();
2076
2077 inline bool HasFastArgumentsElements();
2078 inline bool HasSlowArgumentsElements();
2079 inline bool HasFastStringWrapperElements();
2080 inline bool HasSlowStringWrapperElements();
2081 bool HasEnumerableElements();
2082
2083 inline SeededNumberDictionary* element_dictionary(); // Gets slow elements.
2084
2085 // Requires: HasFastElements().
2086 static void EnsureWritableFastElements(Handle<JSObject> object);
2087
2088 // Collects elements starting at index 0.
2089 // Undefined values are placed after non-undefined values.
2090 // Returns the number of non-undefined values.
2091 static Handle<Object> PrepareElementsForSort(Handle<JSObject> object,
2092 uint32_t limit);
2093 // As PrepareElementsForSort, but only on objects where elements is
2094 // a dictionary, and it will stay a dictionary. Collates undefined and
2095 // unexisting elements below limit from position zero of the elements.
2096 static Handle<Object> PrepareSlowElementsForSort(Handle<JSObject> object,
2097 uint32_t limit);
2098
2099 MUST_USE_RESULT static Maybe<bool> SetPropertyWithInterceptor(
2100 LookupIterator* it, ShouldThrow should_throw, Handle<Object> value);
2101
2102 // The API currently still wants DefineOwnPropertyIgnoreAttributes to convert
2103 // AccessorInfo objects to data fields. We allow FORCE_FIELD as an exception
2104 // to the default behavior that calls the setter.
2105 enum AccessorInfoHandling { FORCE_FIELD, DONT_FORCE_FIELD };
2106
2107 MUST_USE_RESULT static MaybeHandle<Object> DefineOwnPropertyIgnoreAttributes(
2108 LookupIterator* it, Handle<Object> value, PropertyAttributes attributes,
2109 AccessorInfoHandling handling = DONT_FORCE_FIELD);
2110
2111 MUST_USE_RESULT static Maybe<bool> DefineOwnPropertyIgnoreAttributes(
2112 LookupIterator* it, Handle<Object> value, PropertyAttributes attributes,
2113 ShouldThrow should_throw,
2114 AccessorInfoHandling handling = DONT_FORCE_FIELD);
2115
2116 MUST_USE_RESULT static MaybeHandle<Object> SetOwnPropertyIgnoreAttributes(
2117 Handle<JSObject> object, Handle<Name> name, Handle<Object> value,
2118 PropertyAttributes attributes);
2119
2120 MUST_USE_RESULT static MaybeHandle<Object> SetOwnElementIgnoreAttributes(
2121 Handle<JSObject> object, uint32_t index, Handle<Object> value,
2122 PropertyAttributes attributes);
2123
2124 // Equivalent to one of the above depending on whether |name| can be converted
2125 // to an array index.
2126 MUST_USE_RESULT static MaybeHandle<Object>
2127 DefinePropertyOrElementIgnoreAttributes(Handle<JSObject> object,
2128 Handle<Name> name,
2129 Handle<Object> value,
2130 PropertyAttributes attributes = NONE);
2131
2132 // Adds or reconfigures a property to attributes NONE. It will fail when it
2133 // cannot.
2134 MUST_USE_RESULT static Maybe<bool> CreateDataProperty(
2135 LookupIterator* it, Handle<Object> value,
2136 ShouldThrow should_throw = DONT_THROW);
2137
2138 static void AddProperty(Handle<JSObject> object, Handle<Name> name,
2139 Handle<Object> value, PropertyAttributes attributes);
2140
2141 MUST_USE_RESULT static Maybe<bool> AddDataElement(
2142 Handle<JSObject> receiver, uint32_t index, Handle<Object> value,
2143 PropertyAttributes attributes, ShouldThrow should_throw);
2144 MUST_USE_RESULT static MaybeHandle<Object> AddDataElement(
2145 Handle<JSObject> receiver, uint32_t index, Handle<Object> value,
2146 PropertyAttributes attributes);
2147
2148 // Extend the receiver with a single fast property appeared first in the
2149 // passed map. This also extends the property backing store if necessary.
2150 static void AllocateStorageForMap(Handle<JSObject> object, Handle<Map> map);
2151
2152 // Migrates the given object to a map whose field representations are the
2153 // lowest upper bound of all known representations for that field.
2154 static void MigrateInstance(Handle<JSObject> instance);
2155
2156 // Migrates the given object only if the target map is already available,
2157 // or returns false if such a map is not yet available.
2158 static bool TryMigrateInstance(Handle<JSObject> instance);
2159
2160 // Sets the property value in a normalized object given (key, value, details).
2161 // Handles the special representation of JS global objects.
2162 static void SetNormalizedProperty(Handle<JSObject> object, Handle<Name> name,
2163 Handle<Object> value,
2164 PropertyDetails details);
2165 static void SetDictionaryElement(Handle<JSObject> object, uint32_t index,
2166 Handle<Object> value,
2167 PropertyAttributes attributes);
2168 static void SetDictionaryArgumentsElement(Handle<JSObject> object,
2169 uint32_t index,
2170 Handle<Object> value,
2171 PropertyAttributes attributes);
2172
2173 static void OptimizeAsPrototype(Handle<JSObject> object,
2174 PrototypeOptimizationMode mode);
2175 static void ReoptimizeIfPrototype(Handle<JSObject> object);
2176 static void MakePrototypesFast(Handle<Object> receiver,
2177 WhereToStart where_to_start, Isolate* isolate);
2178 static void LazyRegisterPrototypeUser(Handle<Map> user, Isolate* isolate);
2179 static void UpdatePrototypeUserRegistration(Handle<Map> old_map,
2180 Handle<Map> new_map,
2181 Isolate* isolate);
2182 static bool UnregisterPrototypeUser(Handle<Map> user, Isolate* isolate);
2183 static void InvalidatePrototypeChains(Map* map);
2184
2185 // Alternative implementation of WeakFixedArray::NullCallback.
2186 class PrototypeRegistryCompactionCallback {
2187 public:
2188 static void Callback(Object* value, int old_index, int new_index);
2189 };
2190
2191 // Retrieve interceptors.
2192 inline InterceptorInfo* GetNamedInterceptor();
2193 inline InterceptorInfo* GetIndexedInterceptor();
2194
2195 // Used from JSReceiver.
2196 MUST_USE_RESULT static Maybe<PropertyAttributes>
2197 GetPropertyAttributesWithInterceptor(LookupIterator* it);
2198 MUST_USE_RESULT static Maybe<PropertyAttributes>
2199 GetPropertyAttributesWithFailedAccessCheck(LookupIterator* it);
2200
2201 // Defines an AccessorPair property on the given object.
2202 // TODO(mstarzinger): Rename to SetAccessor().
2203 static MaybeHandle<Object> DefineAccessor(Handle<JSObject> object,
2204 Handle<Name> name,
2205 Handle<Object> getter,
2206 Handle<Object> setter,
2207 PropertyAttributes attributes);
2208 static MaybeHandle<Object> DefineAccessor(LookupIterator* it,
2209 Handle<Object> getter,
2210 Handle<Object> setter,
2211 PropertyAttributes attributes);
2212
2213 // Defines an AccessorInfo property on the given object.
2214 MUST_USE_RESULT static MaybeHandle<Object> SetAccessor(
2215 Handle<JSObject> object,
2216 Handle<AccessorInfo> info);
2217
2218 // The result must be checked first for exceptions. If there's no exception,
2219 // the output parameter |done| indicates whether the interceptor has a result
2220 // or not.
2221 MUST_USE_RESULT static MaybeHandle<Object> GetPropertyWithInterceptor(
2222 LookupIterator* it, bool* done);
2223
2224 static void ValidateElements(Handle<JSObject> object);
2225
2226 // Makes sure that this object can contain HeapObject as elements.
2227 static inline void EnsureCanContainHeapObjectElements(Handle<JSObject> obj);
2228
2229 // Makes sure that this object can contain the specified elements.
2230 static inline void EnsureCanContainElements(
2231 Handle<JSObject> object,
2232 Object** elements,
2233 uint32_t count,
2234 EnsureElementsMode mode);
2235 static inline void EnsureCanContainElements(
2236 Handle<JSObject> object,
2237 Handle<FixedArrayBase> elements,
2238 uint32_t length,
2239 EnsureElementsMode mode);
2240 static void EnsureCanContainElements(
2241 Handle<JSObject> object,
2242 Arguments* arguments,
2243 uint32_t first_arg,
2244 uint32_t arg_count,
2245 EnsureElementsMode mode);
2246
2247 // Would we convert a fast elements array to dictionary mode given
2248 // an access at key?
2249 bool WouldConvertToSlowElements(uint32_t index);
2250
2251 // Computes the new capacity when expanding the elements of a JSObject.
NewElementsCapacity(uint32_t old_capacity)2252 static uint32_t NewElementsCapacity(uint32_t old_capacity) {
2253 // (old_capacity + 50%) + 16
2254 return old_capacity + (old_capacity >> 1) + 16;
2255 }
2256
2257 // These methods do not perform access checks!
2258 static void UpdateAllocationSite(Handle<JSObject> object,
2259 ElementsKind to_kind);
2260
2261 // Lookup interceptors are used for handling properties controlled by host
2262 // objects.
2263 inline bool HasNamedInterceptor();
2264 inline bool HasIndexedInterceptor();
2265
2266 // Support functions for v8 api (needed for correct interceptor behavior).
2267 MUST_USE_RESULT static Maybe<bool> HasRealNamedProperty(
2268 Handle<JSObject> object, Handle<Name> name);
2269 MUST_USE_RESULT static Maybe<bool> HasRealElementProperty(
2270 Handle<JSObject> object, uint32_t index);
2271 MUST_USE_RESULT static Maybe<bool> HasRealNamedCallbackProperty(
2272 Handle<JSObject> object, Handle<Name> name);
2273
2274 // Get the header size for a JSObject. Used to compute the index of
2275 // internal fields as well as the number of internal fields.
2276 static inline int GetHeaderSize(InstanceType instance_type);
2277 inline int GetHeaderSize();
2278
2279 static inline int GetInternalFieldCount(Map* map);
2280 inline int GetInternalFieldCount();
2281 inline int GetInternalFieldOffset(int index);
2282 inline Object* GetInternalField(int index);
2283 inline void SetInternalField(int index, Object* value);
2284 inline void SetInternalField(int index, Smi* value);
2285 bool WasConstructedFromApiFunction();
2286
2287 // Returns a new map with all transitions dropped from the object's current
2288 // map and the ElementsKind set.
2289 static Handle<Map> GetElementsTransitionMap(Handle<JSObject> object,
2290 ElementsKind to_kind);
2291 static void TransitionElementsKind(Handle<JSObject> object,
2292 ElementsKind to_kind);
2293
2294 // Always use this to migrate an object to a new map.
2295 // |expected_additional_properties| is only used for fast-to-slow transitions
2296 // and ignored otherwise.
2297 static void MigrateToMap(Handle<JSObject> object, Handle<Map> new_map,
2298 int expected_additional_properties = 0);
2299
2300 // Convert the object to use the canonical dictionary
2301 // representation. If the object is expected to have additional properties
2302 // added this number can be indicated to have the backing store allocated to
2303 // an initial capacity for holding these properties.
2304 static void NormalizeProperties(Handle<JSObject> object,
2305 PropertyNormalizationMode mode,
2306 int expected_additional_properties,
2307 const char* reason);
2308
2309 // Convert and update the elements backing store to be a
2310 // SeededNumberDictionary dictionary. Returns the backing after conversion.
2311 static Handle<SeededNumberDictionary> NormalizeElements(
2312 Handle<JSObject> object);
2313
2314 void RequireSlowElements(SeededNumberDictionary* dictionary);
2315
2316 // Transform slow named properties to fast variants.
2317 static void MigrateSlowToFast(Handle<JSObject> object,
2318 int unused_property_fields, const char* reason);
2319
2320 inline bool IsUnboxedDoubleField(FieldIndex index);
2321
2322 // Access fast-case object properties at index.
2323 static Handle<Object> FastPropertyAt(Handle<JSObject> object,
2324 Representation representation,
2325 FieldIndex index);
2326 inline Object* RawFastPropertyAt(FieldIndex index);
2327 inline double RawFastDoublePropertyAt(FieldIndex index);
2328
2329 inline void FastPropertyAtPut(FieldIndex index, Object* value);
2330 inline void RawFastPropertyAtPut(FieldIndex index, Object* value);
2331 inline void RawFastDoublePropertyAtPut(FieldIndex index, double value);
2332 inline void WriteToField(int descriptor, PropertyDetails details,
2333 Object* value);
2334 inline void WriteToField(int descriptor, Object* value);
2335
2336 // Access to in object properties.
2337 inline int GetInObjectPropertyOffset(int index);
2338 inline Object* InObjectPropertyAt(int index);
2339 inline Object* InObjectPropertyAtPut(int index,
2340 Object* value,
2341 WriteBarrierMode mode
2342 = UPDATE_WRITE_BARRIER);
2343
2344 // Set the object's prototype (only JSReceiver and null are allowed values).
2345 MUST_USE_RESULT static Maybe<bool> SetPrototype(Handle<JSObject> object,
2346 Handle<Object> value,
2347 bool from_javascript,
2348 ShouldThrow should_throw);
2349
2350 // Initializes the body starting at |start_offset|. It is responsibility of
2351 // the caller to initialize object header. Fill the pre-allocated fields with
2352 // pre_allocated_value and the rest with filler_value.
2353 // Note: this call does not update write barrier, the caller is responsible
2354 // to ensure that |filler_value| can be collected without WB here.
2355 inline void InitializeBody(Map* map, int start_offset,
2356 Object* pre_allocated_value, Object* filler_value);
2357
2358 // Check whether this object references another object
2359 bool ReferencesObject(Object* obj);
2360
2361 MUST_USE_RESULT static Maybe<bool> PreventExtensions(
2362 Handle<JSObject> object, ShouldThrow should_throw);
2363
2364 static bool IsExtensible(Handle<JSObject> object);
2365
2366 // Copy object.
2367 enum DeepCopyHints { kNoHints = 0, kObjectIsShallow = 1 };
2368
2369 MUST_USE_RESULT static MaybeHandle<JSObject> DeepCopy(
2370 Handle<JSObject> object,
2371 AllocationSiteUsageContext* site_context,
2372 DeepCopyHints hints = kNoHints);
2373 MUST_USE_RESULT static MaybeHandle<JSObject> DeepWalk(
2374 Handle<JSObject> object,
2375 AllocationSiteCreationContext* site_context);
2376
2377 DECLARE_CAST(JSObject)
2378
2379 // Dispatched behavior.
2380 void JSObjectShortPrint(StringStream* accumulator);
2381 DECLARE_PRINTER(JSObject)
2382 DECLARE_VERIFIER(JSObject)
2383 #ifdef OBJECT_PRINT
2384 void PrintProperties(std::ostream& os); // NOLINT
2385 void PrintElements(std::ostream& os); // NOLINT
2386 #endif
2387 #if defined(DEBUG) || defined(OBJECT_PRINT)
2388 void PrintTransitions(std::ostream& os); // NOLINT
2389 #endif
2390
2391 static void PrintElementsTransition(
2392 FILE* file, Handle<JSObject> object,
2393 ElementsKind from_kind, Handle<FixedArrayBase> from_elements,
2394 ElementsKind to_kind, Handle<FixedArrayBase> to_elements);
2395
2396 void PrintInstanceMigration(FILE* file, Map* original_map, Map* new_map);
2397
2398 #ifdef DEBUG
2399 // Structure for collecting spill information about JSObjects.
2400 class SpillInformation {
2401 public:
2402 void Clear();
2403 void Print();
2404 int number_of_objects_;
2405 int number_of_objects_with_fast_properties_;
2406 int number_of_objects_with_fast_elements_;
2407 int number_of_fast_used_fields_;
2408 int number_of_fast_unused_fields_;
2409 int number_of_slow_used_properties_;
2410 int number_of_slow_unused_properties_;
2411 int number_of_fast_used_elements_;
2412 int number_of_fast_unused_elements_;
2413 int number_of_slow_used_elements_;
2414 int number_of_slow_unused_elements_;
2415 };
2416
2417 void IncrementSpillStatistics(SpillInformation* info);
2418 #endif
2419
2420 #ifdef VERIFY_HEAP
2421 // If a GC was caused while constructing this object, the elements pointer
2422 // may point to a one pointer filler map. The object won't be rooted, but
2423 // our heap verification code could stumble across it.
2424 bool ElementsAreSafeToExamine();
2425 #endif
2426
2427 Object* SlowReverseLookup(Object* value);
2428
2429 // Maximal number of elements (numbered 0 .. kMaxElementCount - 1).
2430 // Also maximal value of JSArray's length property.
2431 static const uint32_t kMaxElementCount = 0xffffffffu;
2432
2433 // Constants for heuristics controlling conversion of fast elements
2434 // to slow elements.
2435
2436 // Maximal gap that can be introduced by adding an element beyond
2437 // the current elements length.
2438 static const uint32_t kMaxGap = 1024;
2439
2440 // Maximal length of fast elements array that won't be checked for
2441 // being dense enough on expansion.
2442 static const int kMaxUncheckedFastElementsLength = 5000;
2443
2444 // Same as above but for old arrays. This limit is more strict. We
2445 // don't want to be wasteful with long lived objects.
2446 static const int kMaxUncheckedOldFastElementsLength = 500;
2447
2448 // This constant applies only to the initial map of "global.Object" and
2449 // not to arbitrary other JSObject maps.
2450 static const int kInitialGlobalObjectUnusedPropertiesCount = 4;
2451
2452 static const int kMaxInstanceSize = 255 * kPointerSize;
2453 // When extending the backing storage for property values, we increase
2454 // its size by more than the 1 entry necessary, so sequentially adding fields
2455 // to the same object requires fewer allocations and copies.
2456 static const int kFieldsAdded = 3;
2457
2458 // Layout description.
2459 static const int kElementsOffset = JSReceiver::kHeaderSize;
2460 static const int kHeaderSize = kElementsOffset + kPointerSize;
2461
2462 STATIC_ASSERT(kHeaderSize == Internals::kJSObjectHeaderSize);
2463
2464 typedef FlexibleBodyDescriptor<JSReceiver::kPropertiesOffset> BodyDescriptor;
2465
2466 // Gets the number of currently used elements.
2467 int GetFastElementsUsage();
2468
2469 static bool AllCanRead(LookupIterator* it);
2470 static bool AllCanWrite(LookupIterator* it);
2471
2472 private:
2473 friend class JSReceiver;
2474 friend class Object;
2475
2476 // Used from Object::GetProperty().
2477 MUST_USE_RESULT static MaybeHandle<Object> GetPropertyWithFailedAccessCheck(
2478 LookupIterator* it);
2479
2480 MUST_USE_RESULT static Maybe<bool> SetPropertyWithFailedAccessCheck(
2481 LookupIterator* it, Handle<Object> value, ShouldThrow should_throw);
2482
2483 // Add a property to a slow-case object.
2484 static void AddSlowProperty(Handle<JSObject> object,
2485 Handle<Name> name,
2486 Handle<Object> value,
2487 PropertyAttributes attributes);
2488
2489 MUST_USE_RESULT static Maybe<bool> DeletePropertyWithInterceptor(
2490 LookupIterator* it, ShouldThrow should_throw);
2491
2492 bool ReferencesObjectFromElements(FixedArray* elements,
2493 ElementsKind kind,
2494 Object* object);
2495
2496 static Object* GetIdentityHash(Isolate* isolate, Handle<JSObject> object);
2497
2498 static Smi* GetOrCreateIdentityHash(Isolate* isolate,
2499 Handle<JSObject> object);
2500
2501 // Helper for fast versions of preventExtensions, seal, and freeze.
2502 // attrs is one of NONE, SEALED, or FROZEN (depending on the operation).
2503 template <PropertyAttributes attrs>
2504 MUST_USE_RESULT static Maybe<bool> PreventExtensionsWithTransition(
2505 Handle<JSObject> object, ShouldThrow should_throw);
2506
2507 DISALLOW_IMPLICIT_CONSTRUCTORS(JSObject);
2508 };
2509
2510
2511 // JSAccessorPropertyDescriptor is just a JSObject with a specific initial
2512 // map. This initial map adds in-object properties for "get", "set",
2513 // "enumerable" and "configurable" properties, as assigned by the
2514 // FromPropertyDescriptor function for regular accessor properties.
2515 class JSAccessorPropertyDescriptor: public JSObject {
2516 public:
2517 // Offsets of object fields.
2518 static const int kGetOffset = JSObject::kHeaderSize;
2519 static const int kSetOffset = kGetOffset + kPointerSize;
2520 static const int kEnumerableOffset = kSetOffset + kPointerSize;
2521 static const int kConfigurableOffset = kEnumerableOffset + kPointerSize;
2522 static const int kSize = kConfigurableOffset + kPointerSize;
2523 // Indices of in-object properties.
2524 static const int kGetIndex = 0;
2525 static const int kSetIndex = 1;
2526 static const int kEnumerableIndex = 2;
2527 static const int kConfigurableIndex = 3;
2528
2529 private:
2530 DISALLOW_IMPLICIT_CONSTRUCTORS(JSAccessorPropertyDescriptor);
2531 };
2532
2533
2534 // JSDataPropertyDescriptor is just a JSObject with a specific initial map.
2535 // This initial map adds in-object properties for "value", "writable",
2536 // "enumerable" and "configurable" properties, as assigned by the
2537 // FromPropertyDescriptor function for regular data properties.
2538 class JSDataPropertyDescriptor: public JSObject {
2539 public:
2540 // Offsets of object fields.
2541 static const int kValueOffset = JSObject::kHeaderSize;
2542 static const int kWritableOffset = kValueOffset + kPointerSize;
2543 static const int kEnumerableOffset = kWritableOffset + kPointerSize;
2544 static const int kConfigurableOffset = kEnumerableOffset + kPointerSize;
2545 static const int kSize = kConfigurableOffset + kPointerSize;
2546 // Indices of in-object properties.
2547 static const int kValueIndex = 0;
2548 static const int kWritableIndex = 1;
2549 static const int kEnumerableIndex = 2;
2550 static const int kConfigurableIndex = 3;
2551
2552 private:
2553 DISALLOW_IMPLICIT_CONSTRUCTORS(JSDataPropertyDescriptor);
2554 };
2555
2556
2557 // JSIteratorResult is just a JSObject with a specific initial map.
2558 // This initial map adds in-object properties for "done" and "value",
2559 // as specified by ES6 section 25.1.1.3 The IteratorResult Interface
2560 class JSIteratorResult: public JSObject {
2561 public:
2562 // Offsets of object fields.
2563 static const int kValueOffset = JSObject::kHeaderSize;
2564 static const int kDoneOffset = kValueOffset + kPointerSize;
2565 static const int kSize = kDoneOffset + kPointerSize;
2566 // Indices of in-object properties.
2567 static const int kValueIndex = 0;
2568 static const int kDoneIndex = 1;
2569
2570 private:
2571 DISALLOW_IMPLICIT_CONSTRUCTORS(JSIteratorResult);
2572 };
2573
2574
2575 // Common superclass for JSSloppyArgumentsObject and JSStrictArgumentsObject.
2576 class JSArgumentsObject: public JSObject {
2577 public:
2578 // Offsets of object fields.
2579 static const int kLengthOffset = JSObject::kHeaderSize;
2580 static const int kHeaderSize = kLengthOffset + kPointerSize;
2581 // Indices of in-object properties.
2582 static const int kLengthIndex = 0;
2583
2584 private:
2585 DISALLOW_IMPLICIT_CONSTRUCTORS(JSArgumentsObject);
2586 };
2587
2588
2589 // JSSloppyArgumentsObject is just a JSObject with specific initial map.
2590 // This initial map adds in-object properties for "length" and "callee".
2591 class JSSloppyArgumentsObject: public JSArgumentsObject {
2592 public:
2593 // Offsets of object fields.
2594 static const int kCalleeOffset = JSArgumentsObject::kHeaderSize;
2595 static const int kSize = kCalleeOffset + kPointerSize;
2596 // Indices of in-object properties.
2597 static const int kCalleeIndex = 1;
2598
2599 private:
2600 DISALLOW_IMPLICIT_CONSTRUCTORS(JSSloppyArgumentsObject);
2601 };
2602
2603
2604 // JSStrictArgumentsObject is just a JSObject with specific initial map.
2605 // This initial map adds an in-object property for "length".
2606 class JSStrictArgumentsObject: public JSArgumentsObject {
2607 public:
2608 // Offsets of object fields.
2609 static const int kSize = JSArgumentsObject::kHeaderSize;
2610
2611 private:
2612 DISALLOW_IMPLICIT_CONSTRUCTORS(JSStrictArgumentsObject);
2613 };
2614
2615
2616 // Common superclass for FixedArrays that allow implementations to share
2617 // common accessors and some code paths.
2618 class FixedArrayBase: public HeapObject {
2619 public:
2620 // [length]: length of the array.
2621 inline int length() const;
2622 inline void set_length(int value);
2623
2624 // Get and set the length using acquire loads and release stores.
2625 inline int synchronized_length() const;
2626 inline void synchronized_set_length(int value);
2627
2628 DECLARE_CAST(FixedArrayBase)
2629
2630 // Layout description.
2631 // Length is smi tagged when it is stored.
2632 static const int kLengthOffset = HeapObject::kHeaderSize;
2633 static const int kHeaderSize = kLengthOffset + kPointerSize;
2634 };
2635
2636
2637 class FixedDoubleArray;
2638 class IncrementalMarking;
2639
2640
2641 // FixedArray describes fixed-sized arrays with element type Object*.
2642 class FixedArray: public FixedArrayBase {
2643 public:
2644 // Setter and getter for elements.
2645 inline Object* get(int index) const;
2646 static inline Handle<Object> get(FixedArray* array, int index,
2647 Isolate* isolate);
2648 // Setter that uses write barrier.
2649 inline void set(int index, Object* value);
2650 inline bool is_the_hole(int index);
2651
2652 // Setter that doesn't need write barrier.
2653 inline void set(int index, Smi* value);
2654 // Setter with explicit barrier mode.
2655 inline void set(int index, Object* value, WriteBarrierMode mode);
2656
2657 // Setters for frequently used oddballs located in old space.
2658 inline void set_undefined(int index);
2659 inline void set_null(int index);
2660 inline void set_the_hole(int index);
2661
2662 inline Object** GetFirstElementAddress();
2663 inline bool ContainsOnlySmisOrHoles();
2664
2665 // Gives access to raw memory which stores the array's data.
2666 inline Object** data_start();
2667
2668 inline void FillWithHoles(int from, int to);
2669
2670 // Shrink length and insert filler objects.
2671 void Shrink(int length);
2672
2673 // Copy a sub array from the receiver to dest.
2674 void CopyTo(int pos, FixedArray* dest, int dest_pos, int len);
2675
2676 // Garbage collection support.
SizeFor(int length)2677 static int SizeFor(int length) { return kHeaderSize + length * kPointerSize; }
2678
2679 // Code Generation support.
OffsetOfElementAt(int index)2680 static int OffsetOfElementAt(int index) { return SizeFor(index); }
2681
2682 // Garbage collection support.
2683 inline Object** RawFieldOfElementAt(int index);
2684
2685 DECLARE_CAST(FixedArray)
2686
2687 // Maximal allowed size, in bytes, of a single FixedArray.
2688 // Prevents overflowing size computations, as well as extreme memory
2689 // consumption.
2690 static const int kMaxSize = 128 * MB * kPointerSize;
2691 // Maximally allowed length of a FixedArray.
2692 static const int kMaxLength = (kMaxSize - kHeaderSize) / kPointerSize;
2693
2694 // Dispatched behavior.
2695 DECLARE_PRINTER(FixedArray)
2696 DECLARE_VERIFIER(FixedArray)
2697 #ifdef DEBUG
2698 // Checks if two FixedArrays have identical contents.
2699 bool IsEqualTo(FixedArray* other);
2700 #endif
2701
2702 // Swap two elements in a pair of arrays. If this array and the
2703 // numbers array are the same object, the elements are only swapped
2704 // once.
2705 void SwapPairs(FixedArray* numbers, int i, int j);
2706
2707 // Sort prefix of this array and the numbers array as pairs wrt. the
2708 // numbers. If the numbers array and the this array are the same
2709 // object, the prefix of this array is sorted.
2710 void SortPairs(FixedArray* numbers, uint32_t len);
2711
2712 typedef FlexibleBodyDescriptor<kHeaderSize> BodyDescriptor;
2713
2714 protected:
2715 // Set operation on FixedArray without using write barriers. Can
2716 // only be used for storing old space objects or smis.
2717 static inline void NoWriteBarrierSet(FixedArray* array,
2718 int index,
2719 Object* value);
2720
2721 private:
2722 STATIC_ASSERT(kHeaderSize == Internals::kFixedArrayHeaderSize);
2723
2724 DISALLOW_IMPLICIT_CONSTRUCTORS(FixedArray);
2725 };
2726
2727
2728 // FixedDoubleArray describes fixed-sized arrays with element type double.
2729 class FixedDoubleArray: public FixedArrayBase {
2730 public:
2731 // Setter and getter for elements.
2732 inline double get_scalar(int index);
2733 inline uint64_t get_representation(int index);
2734 static inline Handle<Object> get(FixedDoubleArray* array, int index,
2735 Isolate* isolate);
2736 inline void set(int index, double value);
2737 inline void set_the_hole(int index);
2738
2739 // Checking for the hole.
2740 inline bool is_the_hole(int index);
2741
2742 // Garbage collection support.
SizeFor(int length)2743 inline static int SizeFor(int length) {
2744 return kHeaderSize + length * kDoubleSize;
2745 }
2746
2747 // Gives access to raw memory which stores the array's data.
2748 inline double* data_start();
2749
2750 inline void FillWithHoles(int from, int to);
2751
2752 // Code Generation support.
OffsetOfElementAt(int index)2753 static int OffsetOfElementAt(int index) { return SizeFor(index); }
2754
2755 DECLARE_CAST(FixedDoubleArray)
2756
2757 // Maximal allowed size, in bytes, of a single FixedDoubleArray.
2758 // Prevents overflowing size computations, as well as extreme memory
2759 // consumption.
2760 static const int kMaxSize = 512 * MB;
2761 // Maximally allowed length of a FixedArray.
2762 static const int kMaxLength = (kMaxSize - kHeaderSize) / kDoubleSize;
2763
2764 // Dispatched behavior.
2765 DECLARE_PRINTER(FixedDoubleArray)
2766 DECLARE_VERIFIER(FixedDoubleArray)
2767
2768 private:
2769 DISALLOW_IMPLICIT_CONSTRUCTORS(FixedDoubleArray);
2770 };
2771
2772
2773 class WeakFixedArray : public FixedArray {
2774 public:
2775 // If |maybe_array| is not a WeakFixedArray, a fresh one will be allocated.
2776 // This function does not check if the value exists already, callers must
2777 // ensure this themselves if necessary.
2778 static Handle<WeakFixedArray> Add(Handle<Object> maybe_array,
2779 Handle<HeapObject> value,
2780 int* assigned_index = NULL);
2781
2782 // Returns true if an entry was found and removed.
2783 bool Remove(Handle<HeapObject> value);
2784
2785 class NullCallback {
2786 public:
Callback(Object * value,int old_index,int new_index)2787 static void Callback(Object* value, int old_index, int new_index) {}
2788 };
2789
2790 template <class CompactionCallback>
2791 void Compact();
2792
2793 inline Object* Get(int index) const;
2794 inline void Clear(int index);
2795 inline int Length() const;
2796
2797 inline bool IsEmptySlot(int index) const;
Empty()2798 static Object* Empty() { return Smi::FromInt(0); }
2799
2800 class Iterator {
2801 public:
Iterator(Object * maybe_array)2802 explicit Iterator(Object* maybe_array) : list_(NULL) { Reset(maybe_array); }
2803 void Reset(Object* maybe_array);
2804
2805 template <class T>
2806 inline T* Next();
2807
2808 private:
2809 int index_;
2810 WeakFixedArray* list_;
2811 #ifdef DEBUG
2812 int last_used_index_;
2813 DisallowHeapAllocation no_gc_;
2814 #endif // DEBUG
2815 DISALLOW_COPY_AND_ASSIGN(Iterator);
2816 };
2817
2818 DECLARE_CAST(WeakFixedArray)
2819
2820 private:
2821 static const int kLastUsedIndexIndex = 0;
2822 static const int kFirstIndex = 1;
2823
2824 static Handle<WeakFixedArray> Allocate(
2825 Isolate* isolate, int size, Handle<WeakFixedArray> initialize_from);
2826
2827 static void Set(Handle<WeakFixedArray> array, int index,
2828 Handle<HeapObject> value);
2829 inline void clear(int index);
2830
2831 inline int last_used_index() const;
2832 inline void set_last_used_index(int index);
2833
2834 // Disallow inherited setters.
2835 void set(int index, Smi* value);
2836 void set(int index, Object* value);
2837 void set(int index, Object* value, WriteBarrierMode mode);
2838 DISALLOW_IMPLICIT_CONSTRUCTORS(WeakFixedArray);
2839 };
2840
2841
2842 // Generic array grows dynamically with O(1) amortized insertion.
2843 class ArrayList : public FixedArray {
2844 public:
2845 enum AddMode {
2846 kNone,
2847 // Use this if GC can delete elements from the array.
2848 kReloadLengthAfterAllocation,
2849 };
2850 static Handle<ArrayList> Add(Handle<ArrayList> array, Handle<Object> obj,
2851 AddMode mode = kNone);
2852 static Handle<ArrayList> Add(Handle<ArrayList> array, Handle<Object> obj1,
2853 Handle<Object> obj2, AddMode = kNone);
2854 inline int Length();
2855 inline void SetLength(int length);
2856 inline Object* Get(int index);
2857 inline Object** Slot(int index);
2858 inline void Set(int index, Object* obj);
2859 inline void Clear(int index, Object* undefined);
2860 bool IsFull();
2861 DECLARE_CAST(ArrayList)
2862
2863 private:
2864 static Handle<ArrayList> EnsureSpace(Handle<ArrayList> array, int length);
2865 static const int kLengthIndex = 0;
2866 static const int kFirstIndex = 1;
2867 DISALLOW_IMPLICIT_CONSTRUCTORS(ArrayList);
2868 };
2869
2870
2871 // DescriptorArrays are fixed arrays used to hold instance descriptors.
2872 // The format of the these objects is:
2873 // [0]: Number of descriptors
2874 // [1]: Either Smi(0) if uninitialized, or a pointer to small fixed array:
2875 // [0]: pointer to fixed array with enum cache
2876 // [1]: either Smi(0) or pointer to fixed array with indices
2877 // [2]: first key
2878 // [2 + number of descriptors * kDescriptorSize]: start of slack
2879 class DescriptorArray: public FixedArray {
2880 public:
2881 // Returns true for both shared empty_descriptor_array and for smis, which the
2882 // map uses to encode additional bit fields when the descriptor array is not
2883 // yet used.
2884 inline bool IsEmpty();
2885
2886 // Returns the number of descriptors in the array.
2887 inline int number_of_descriptors();
2888
2889 inline int number_of_descriptors_storage();
2890
2891 inline int NumberOfSlackDescriptors();
2892
2893 inline void SetNumberOfDescriptors(int number_of_descriptors);
2894 inline int number_of_entries();
2895
2896 inline bool HasEnumCache();
2897
2898 inline void CopyEnumCacheFrom(DescriptorArray* array);
2899
2900 inline FixedArray* GetEnumCache();
2901
2902 inline bool HasEnumIndicesCache();
2903
2904 inline FixedArray* GetEnumIndicesCache();
2905
2906 inline Object** GetEnumCacheSlot();
2907
2908 void ClearEnumCache();
2909
2910 // Initialize or change the enum cache,
2911 // using the supplied storage for the small "bridge".
2912 static void SetEnumCache(Handle<DescriptorArray> descriptors,
2913 Isolate* isolate, Handle<FixedArray> new_cache,
2914 Handle<FixedArray> new_index_cache);
2915
2916 // Accessors for fetching instance descriptor at descriptor number.
2917 inline Name* GetKey(int descriptor_number);
2918 inline Object** GetKeySlot(int descriptor_number);
2919 inline Object* GetValue(int descriptor_number);
2920 inline void SetValue(int descriptor_number, Object* value);
2921 inline Object** GetValueSlot(int descriptor_number);
2922 static inline int GetValueOffset(int descriptor_number);
2923 inline Object** GetDescriptorStartSlot(int descriptor_number);
2924 inline Object** GetDescriptorEndSlot(int descriptor_number);
2925 inline PropertyDetails GetDetails(int descriptor_number);
2926 inline PropertyType GetType(int descriptor_number);
2927 inline int GetFieldIndex(int descriptor_number);
2928 FieldType* GetFieldType(int descriptor_number);
2929 inline Object* GetConstant(int descriptor_number);
2930 inline Object* GetCallbacksObject(int descriptor_number);
2931 inline AccessorDescriptor* GetCallbacks(int descriptor_number);
2932
2933 inline Name* GetSortedKey(int descriptor_number);
2934 inline int GetSortedKeyIndex(int descriptor_number);
2935 inline void SetSortedKey(int pointer, int descriptor_number);
2936 inline void SetRepresentation(int descriptor_number,
2937 Representation representation);
2938
2939 // Accessor for complete descriptor.
2940 inline void Get(int descriptor_number, Descriptor* desc);
2941 inline void Set(int descriptor_number, Descriptor* desc);
2942 void Replace(int descriptor_number, Descriptor* descriptor);
2943
2944 // Append automatically sets the enumeration index. This should only be used
2945 // to add descriptors in bulk at the end, followed by sorting the descriptor
2946 // array.
2947 inline void Append(Descriptor* desc);
2948
2949 static Handle<DescriptorArray> CopyUpTo(Handle<DescriptorArray> desc,
2950 int enumeration_index,
2951 int slack = 0);
2952
2953 static Handle<DescriptorArray> CopyUpToAddAttributes(
2954 Handle<DescriptorArray> desc,
2955 int enumeration_index,
2956 PropertyAttributes attributes,
2957 int slack = 0);
2958
2959 // Sort the instance descriptors by the hash codes of their keys.
2960 void Sort();
2961
2962 // Search the instance descriptors for given name.
2963 INLINE(int Search(Name* name, int number_of_own_descriptors));
2964
2965 // As the above, but uses DescriptorLookupCache and updates it when
2966 // necessary.
2967 INLINE(int SearchWithCache(Isolate* isolate, Name* name, Map* map));
2968
2969 bool IsEqualUpTo(DescriptorArray* desc, int nof_descriptors);
2970
2971 // Allocates a DescriptorArray, but returns the singleton
2972 // empty descriptor array object if number_of_descriptors is 0.
2973 static Handle<DescriptorArray> Allocate(
2974 Isolate* isolate, int number_of_descriptors, int slack,
2975 PretenureFlag pretenure = NOT_TENURED);
2976
2977 DECLARE_CAST(DescriptorArray)
2978
2979 // Constant for denoting key was not found.
2980 static const int kNotFound = -1;
2981
2982 static const int kDescriptorLengthIndex = 0;
2983 static const int kEnumCacheIndex = 1;
2984 static const int kFirstIndex = 2;
2985
2986 // The length of the "bridge" to the enum cache.
2987 static const int kEnumCacheBridgeLength = 2;
2988 static const int kEnumCacheBridgeCacheIndex = 0;
2989 static const int kEnumCacheBridgeIndicesCacheIndex = 1;
2990
2991 // Layout description.
2992 static const int kDescriptorLengthOffset = FixedArray::kHeaderSize;
2993 static const int kEnumCacheOffset = kDescriptorLengthOffset + kPointerSize;
2994 static const int kFirstOffset = kEnumCacheOffset + kPointerSize;
2995
2996 // Layout description for the bridge array.
2997 static const int kEnumCacheBridgeCacheOffset = FixedArray::kHeaderSize;
2998
2999 // Layout of descriptor.
3000 static const int kDescriptorKey = 0;
3001 static const int kDescriptorDetails = 1;
3002 static const int kDescriptorValue = 2;
3003 static const int kDescriptorSize = 3;
3004
3005 #if defined(DEBUG) || defined(OBJECT_PRINT)
3006 // For our gdb macros, we should perhaps change these in the future.
3007 void Print();
3008
3009 // Print all the descriptors.
3010 void PrintDescriptors(std::ostream& os); // NOLINT
3011 #endif
3012
3013 #ifdef DEBUG
3014 // Is the descriptor array sorted and without duplicates?
3015 bool IsSortedNoDuplicates(int valid_descriptors = -1);
3016
3017 // Is the descriptor array consistent with the back pointers in targets?
3018 bool IsConsistentWithBackPointers(Map* current_map);
3019
3020 // Are two DescriptorArrays equal?
3021 bool IsEqualTo(DescriptorArray* other);
3022 #endif
3023
3024 // Returns the fixed array length required to hold number_of_descriptors
3025 // descriptors.
LengthFor(int number_of_descriptors)3026 static int LengthFor(int number_of_descriptors) {
3027 return ToKeyIndex(number_of_descriptors);
3028 }
3029
ToDetailsIndex(int descriptor_number)3030 static int ToDetailsIndex(int descriptor_number) {
3031 return kFirstIndex + (descriptor_number * kDescriptorSize) +
3032 kDescriptorDetails;
3033 }
3034
3035 // Conversion from descriptor number to array indices.
ToKeyIndex(int descriptor_number)3036 static int ToKeyIndex(int descriptor_number) {
3037 return kFirstIndex + (descriptor_number * kDescriptorSize) + kDescriptorKey;
3038 }
3039
ToValueIndex(int descriptor_number)3040 static int ToValueIndex(int descriptor_number) {
3041 return kFirstIndex + (descriptor_number * kDescriptorSize) +
3042 kDescriptorValue;
3043 }
3044
3045 private:
3046 // An entry in a DescriptorArray, represented as an (array, index) pair.
3047 class Entry {
3048 public:
Entry(DescriptorArray * descs,int index)3049 inline explicit Entry(DescriptorArray* descs, int index) :
3050 descs_(descs), index_(index) { }
3051
3052 inline PropertyType type();
3053 inline Object* GetCallbackObject();
3054
3055 private:
3056 DescriptorArray* descs_;
3057 int index_;
3058 };
3059
3060 // Transfer a complete descriptor from the src descriptor array to this
3061 // descriptor array.
3062 void CopyFrom(int index, DescriptorArray* src);
3063
3064 inline void SetDescriptor(int descriptor_number, Descriptor* desc);
3065
3066 // Swap first and second descriptor.
3067 inline void SwapSortedKeys(int first, int second);
3068
3069 DISALLOW_IMPLICIT_CONSTRUCTORS(DescriptorArray);
3070 };
3071
3072
3073 enum SearchMode { ALL_ENTRIES, VALID_ENTRIES };
3074
3075 template <SearchMode search_mode, typename T>
3076 inline int Search(T* array, Name* name, int valid_entries = 0,
3077 int* out_insertion_index = NULL);
3078
3079
3080 // HashTable is a subclass of FixedArray that implements a hash table
3081 // that uses open addressing and quadratic probing.
3082 //
3083 // In order for the quadratic probing to work, elements that have not
3084 // yet been used and elements that have been deleted are
3085 // distinguished. Probing continues when deleted elements are
3086 // encountered and stops when unused elements are encountered.
3087 //
3088 // - Elements with key == undefined have not been used yet.
3089 // - Elements with key == the_hole have been deleted.
3090 //
3091 // The hash table class is parameterized with a Shape and a Key.
3092 // Shape must be a class with the following interface:
3093 // class ExampleShape {
3094 // public:
3095 // // Tells whether key matches other.
3096 // static bool IsMatch(Key key, Object* other);
3097 // // Returns the hash value for key.
3098 // static uint32_t Hash(Key key);
3099 // // Returns the hash value for object.
3100 // static uint32_t HashForObject(Key key, Object* object);
3101 // // Convert key to an object.
3102 // static inline Handle<Object> AsHandle(Isolate* isolate, Key key);
3103 // // The prefix size indicates number of elements in the beginning
3104 // // of the backing storage.
3105 // static const int kPrefixSize = ..;
3106 // // The Element size indicates number of elements per entry.
3107 // static const int kEntrySize = ..;
3108 // };
3109 // The prefix size indicates an amount of memory in the
3110 // beginning of the backing storage that can be used for non-element
3111 // information by subclasses.
3112
3113 template<typename Key>
3114 class BaseShape {
3115 public:
3116 static const bool UsesSeed = false;
Hash(Key key)3117 static uint32_t Hash(Key key) { return 0; }
SeededHash(Key key,uint32_t seed)3118 static uint32_t SeededHash(Key key, uint32_t seed) {
3119 DCHECK(UsesSeed);
3120 return Hash(key);
3121 }
HashForObject(Key key,Object * object)3122 static uint32_t HashForObject(Key key, Object* object) { return 0; }
SeededHashForObject(Key key,uint32_t seed,Object * object)3123 static uint32_t SeededHashForObject(Key key, uint32_t seed, Object* object) {
3124 DCHECK(UsesSeed);
3125 return HashForObject(key, object);
3126 }
3127 };
3128
3129
3130 class HashTableBase : public FixedArray {
3131 public:
3132 // Returns the number of elements in the hash table.
3133 inline int NumberOfElements();
3134
3135 // Returns the number of deleted elements in the hash table.
3136 inline int NumberOfDeletedElements();
3137
3138 // Returns the capacity of the hash table.
3139 inline int Capacity();
3140
3141 // ElementAdded should be called whenever an element is added to a
3142 // hash table.
3143 inline void ElementAdded();
3144
3145 // ElementRemoved should be called whenever an element is removed from
3146 // a hash table.
3147 inline void ElementRemoved();
3148 inline void ElementsRemoved(int n);
3149
3150 // Computes the required capacity for a table holding the given
3151 // number of elements. May be more than HashTable::kMaxCapacity.
3152 static inline int ComputeCapacity(int at_least_space_for);
3153
3154 // Tells whether k is a real key. The hole and undefined are not allowed
3155 // as keys and can be used to indicate missing or deleted elements.
3156 inline bool IsKey(Object* k);
3157 inline bool IsKey(Isolate* isolate, Object* k);
3158
3159 // Compute the probe offset (quadratic probing).
INLINE(static uint32_t GetProbeOffset (uint32_t n))3160 INLINE(static uint32_t GetProbeOffset(uint32_t n)) {
3161 return (n + n * n) >> 1;
3162 }
3163
3164 static const int kNumberOfElementsIndex = 0;
3165 static const int kNumberOfDeletedElementsIndex = 1;
3166 static const int kCapacityIndex = 2;
3167 static const int kPrefixStartIndex = 3;
3168
3169 // Constant used for denoting a absent entry.
3170 static const int kNotFound = -1;
3171
3172 protected:
3173 // Update the number of elements in the hash table.
3174 inline void SetNumberOfElements(int nof);
3175
3176 // Update the number of deleted elements in the hash table.
3177 inline void SetNumberOfDeletedElements(int nod);
3178
3179 // Returns probe entry.
GetProbe(uint32_t hash,uint32_t number,uint32_t size)3180 static uint32_t GetProbe(uint32_t hash, uint32_t number, uint32_t size) {
3181 DCHECK(base::bits::IsPowerOfTwo32(size));
3182 return (hash + GetProbeOffset(number)) & (size - 1);
3183 }
3184
FirstProbe(uint32_t hash,uint32_t size)3185 inline static uint32_t FirstProbe(uint32_t hash, uint32_t size) {
3186 return hash & (size - 1);
3187 }
3188
NextProbe(uint32_t last,uint32_t number,uint32_t size)3189 inline static uint32_t NextProbe(
3190 uint32_t last, uint32_t number, uint32_t size) {
3191 return (last + number) & (size - 1);
3192 }
3193 };
3194
3195
3196 template <typename Derived, typename Shape, typename Key>
3197 class HashTable : public HashTableBase {
3198 public:
3199 typedef Shape ShapeT;
3200
3201 // Wrapper methods
Hash(Key key)3202 inline uint32_t Hash(Key key) {
3203 if (Shape::UsesSeed) {
3204 return Shape::SeededHash(key, GetHeap()->HashSeed());
3205 } else {
3206 return Shape::Hash(key);
3207 }
3208 }
3209
HashForObject(Key key,Object * object)3210 inline uint32_t HashForObject(Key key, Object* object) {
3211 if (Shape::UsesSeed) {
3212 return Shape::SeededHashForObject(key, GetHeap()->HashSeed(), object);
3213 } else {
3214 return Shape::HashForObject(key, object);
3215 }
3216 }
3217
3218 // Returns a new HashTable object.
3219 MUST_USE_RESULT static Handle<Derived> New(
3220 Isolate* isolate, int at_least_space_for,
3221 MinimumCapacity capacity_option = USE_DEFAULT_MINIMUM_CAPACITY,
3222 PretenureFlag pretenure = NOT_TENURED);
3223
3224 DECLARE_CAST(HashTable)
3225
3226 // Garbage collection support.
3227 void IteratePrefix(ObjectVisitor* visitor);
3228 void IterateElements(ObjectVisitor* visitor);
3229
3230 // Find entry for key otherwise return kNotFound.
3231 inline int FindEntry(Key key);
3232 inline int FindEntry(Isolate* isolate, Key key, int32_t hash);
3233 int FindEntry(Isolate* isolate, Key key);
3234
3235 // Rehashes the table in-place.
3236 void Rehash(Key key);
3237
3238 // Returns the key at entry.
KeyAt(int entry)3239 Object* KeyAt(int entry) { return get(EntryToIndex(entry) + kEntryKeyIndex); }
3240
3241 static const int kElementsStartIndex = kPrefixStartIndex + Shape::kPrefixSize;
3242 static const int kEntrySize = Shape::kEntrySize;
3243 STATIC_ASSERT(kEntrySize > 0);
3244 static const int kEntryKeyIndex = 0;
3245 static const int kElementsStartOffset =
3246 kHeaderSize + kElementsStartIndex * kPointerSize;
3247 static const int kCapacityOffset =
3248 kHeaderSize + kCapacityIndex * kPointerSize;
3249
3250 // Returns the index for an entry (of the key)
EntryToIndex(int entry)3251 static inline int EntryToIndex(int entry) {
3252 return (entry * kEntrySize) + kElementsStartIndex;
3253 }
3254
3255 protected:
3256 friend class ObjectHashTable;
3257
3258 // Find the entry at which to insert element with the given key that
3259 // has the given hash value.
3260 uint32_t FindInsertionEntry(uint32_t hash);
3261
3262 // Attempt to shrink hash table after removal of key.
3263 MUST_USE_RESULT static Handle<Derived> Shrink(Handle<Derived> table, Key key);
3264
3265 // Ensure enough space for n additional elements.
3266 MUST_USE_RESULT static Handle<Derived> EnsureCapacity(
3267 Handle<Derived> table,
3268 int n,
3269 Key key,
3270 PretenureFlag pretenure = NOT_TENURED);
3271
3272 // Returns true if this table has sufficient capacity for adding n elements.
3273 bool HasSufficientCapacityToAdd(int number_of_additional_elements);
3274
3275 // Sets the capacity of the hash table.
SetCapacity(int capacity)3276 void SetCapacity(int capacity) {
3277 // To scale a computed hash code to fit within the hash table, we
3278 // use bit-wise AND with a mask, so the capacity must be positive
3279 // and non-zero.
3280 DCHECK(capacity > 0);
3281 DCHECK(capacity <= kMaxCapacity);
3282 set(kCapacityIndex, Smi::FromInt(capacity));
3283 }
3284
3285 // Maximal capacity of HashTable. Based on maximal length of underlying
3286 // FixedArray. Staying below kMaxCapacity also ensures that EntryToIndex
3287 // cannot overflow.
3288 static const int kMaxCapacity =
3289 (FixedArray::kMaxLength - kElementsStartOffset) / kEntrySize;
3290
3291 private:
3292 // Returns _expected_ if one of entries given by the first _probe_ probes is
3293 // equal to _expected_. Otherwise, returns the entry given by the probe
3294 // number _probe_.
3295 uint32_t EntryForProbe(Key key, Object* k, int probe, uint32_t expected);
3296
3297 void Swap(uint32_t entry1, uint32_t entry2, WriteBarrierMode mode);
3298
3299 // Rehashes this hash-table into the new table.
3300 void Rehash(Handle<Derived> new_table, Key key);
3301 };
3302
3303
3304 // HashTableKey is an abstract superclass for virtual key behavior.
3305 class HashTableKey {
3306 public:
3307 // Returns whether the other object matches this key.
3308 virtual bool IsMatch(Object* other) = 0;
3309 // Returns the hash value for this key.
3310 virtual uint32_t Hash() = 0;
3311 // Returns the hash value for object.
3312 virtual uint32_t HashForObject(Object* key) = 0;
3313 // Returns the key object for storing into the hash table.
3314 MUST_USE_RESULT virtual Handle<Object> AsHandle(Isolate* isolate) = 0;
3315 // Required.
~HashTableKey()3316 virtual ~HashTableKey() {}
3317 };
3318
3319
3320 class StringTableShape : public BaseShape<HashTableKey*> {
3321 public:
IsMatch(HashTableKey * key,Object * value)3322 static inline bool IsMatch(HashTableKey* key, Object* value) {
3323 return key->IsMatch(value);
3324 }
3325
Hash(HashTableKey * key)3326 static inline uint32_t Hash(HashTableKey* key) {
3327 return key->Hash();
3328 }
3329
HashForObject(HashTableKey * key,Object * object)3330 static inline uint32_t HashForObject(HashTableKey* key, Object* object) {
3331 return key->HashForObject(object);
3332 }
3333
3334 static inline Handle<Object> AsHandle(Isolate* isolate, HashTableKey* key);
3335
3336 static const int kPrefixSize = 0;
3337 static const int kEntrySize = 1;
3338 };
3339
3340 class SeqOneByteString;
3341
3342 // StringTable.
3343 //
3344 // No special elements in the prefix and the element size is 1
3345 // because only the string itself (the key) needs to be stored.
3346 class StringTable: public HashTable<StringTable,
3347 StringTableShape,
3348 HashTableKey*> {
3349 public:
3350 // Find string in the string table. If it is not there yet, it is
3351 // added. The return value is the string found.
3352 static Handle<String> LookupString(Isolate* isolate, Handle<String> key);
3353 static Handle<String> LookupKey(Isolate* isolate, HashTableKey* key);
3354 static String* LookupKeyIfExists(Isolate* isolate, HashTableKey* key);
3355
3356 // Tries to internalize given string and returns string handle on success
3357 // or an empty handle otherwise.
3358 MUST_USE_RESULT static MaybeHandle<String> InternalizeStringIfExists(
3359 Isolate* isolate,
3360 Handle<String> string);
3361
3362 // Looks up a string that is equal to the given string and returns
3363 // string handle if it is found, or an empty handle otherwise.
3364 MUST_USE_RESULT static MaybeHandle<String> LookupStringIfExists(
3365 Isolate* isolate,
3366 Handle<String> str);
3367 MUST_USE_RESULT static MaybeHandle<String> LookupTwoCharsStringIfExists(
3368 Isolate* isolate,
3369 uint16_t c1,
3370 uint16_t c2);
3371
3372 static void EnsureCapacityForDeserialization(Isolate* isolate, int expected);
3373
3374 DECLARE_CAST(StringTable)
3375
3376 private:
3377 template <bool seq_one_byte>
3378 friend class JsonParser;
3379
3380 DISALLOW_IMPLICIT_CONSTRUCTORS(StringTable);
3381 };
3382
3383 class StringSetShape : public BaseShape<String*> {
3384 public:
3385 static inline bool IsMatch(String* key, Object* value);
3386 static inline uint32_t Hash(String* key);
3387 static inline uint32_t HashForObject(String* key, Object* object);
3388
3389 static const int kPrefixSize = 0;
3390 static const int kEntrySize = 1;
3391 };
3392
3393 class StringSet : public HashTable<StringSet, StringSetShape, String*> {
3394 public:
3395 static Handle<StringSet> New(Isolate* isolate);
3396 static Handle<StringSet> Add(Handle<StringSet> blacklist,
3397 Handle<String> name);
3398 bool Has(Handle<String> name);
3399
3400 DECLARE_CAST(StringSet)
3401 };
3402
3403 template <typename Derived, typename Shape, typename Key>
3404 class Dictionary: public HashTable<Derived, Shape, Key> {
3405 typedef HashTable<Derived, Shape, Key> DerivedHashTable;
3406
3407 public:
3408 // Returns the value at entry.
ValueAt(int entry)3409 Object* ValueAt(int entry) {
3410 return this->get(Derived::EntryToIndex(entry) + 1);
3411 }
3412
3413 // Set the value for entry.
ValueAtPut(int entry,Object * value)3414 void ValueAtPut(int entry, Object* value) {
3415 this->set(Derived::EntryToIndex(entry) + 1, value);
3416 }
3417
3418 // Returns the property details for the property at entry.
DetailsAt(int entry)3419 PropertyDetails DetailsAt(int entry) {
3420 return Shape::DetailsAt(static_cast<Derived*>(this), entry);
3421 }
3422
3423 // Set the details for entry.
DetailsAtPut(int entry,PropertyDetails value)3424 void DetailsAtPut(int entry, PropertyDetails value) {
3425 Shape::DetailsAtPut(static_cast<Derived*>(this), entry, value);
3426 }
3427
3428 // Returns true if property at given entry is deleted.
IsDeleted(int entry)3429 bool IsDeleted(int entry) {
3430 return Shape::IsDeleted(static_cast<Derived*>(this), entry);
3431 }
3432
3433 // Delete a property from the dictionary.
3434 static Handle<Object> DeleteProperty(Handle<Derived> dictionary, int entry);
3435
3436 // Attempt to shrink the dictionary after deletion of key.
Shrink(Handle<Derived> dictionary,Key key)3437 MUST_USE_RESULT static inline Handle<Derived> Shrink(
3438 Handle<Derived> dictionary,
3439 Key key) {
3440 return DerivedHashTable::Shrink(dictionary, key);
3441 }
3442
3443 // Sorting support
3444 // TODO(dcarney): templatize or move to SeededNumberDictionary
3445 void CopyValuesTo(FixedArray* elements);
3446
3447 // Returns the number of elements in the dictionary filtering out properties
3448 // with the specified attributes.
3449 int NumberOfElementsFilterAttributes(PropertyFilter filter);
3450
3451 // Returns the number of enumerable elements in the dictionary.
NumberOfEnumElements()3452 int NumberOfEnumElements() {
3453 return NumberOfElementsFilterAttributes(ENUMERABLE_STRINGS);
3454 }
3455
3456 enum SortMode { UNSORTED, SORTED };
3457
3458 // Collect the keys into the given KeyAccumulator, in ascending chronological
3459 // order of property creation.
3460 static void CollectKeysTo(Handle<Dictionary<Derived, Shape, Key> > dictionary,
3461 KeyAccumulator* keys, PropertyFilter filter);
3462
3463 // Copies enumerable keys to preallocated fixed array.
3464 void CopyEnumKeysTo(FixedArray* storage);
3465
3466 // Accessors for next enumeration index.
SetNextEnumerationIndex(int index)3467 void SetNextEnumerationIndex(int index) {
3468 DCHECK(index != 0);
3469 this->set(kNextEnumerationIndexIndex, Smi::FromInt(index));
3470 }
3471
NextEnumerationIndex()3472 int NextEnumerationIndex() {
3473 return Smi::cast(this->get(kNextEnumerationIndexIndex))->value();
3474 }
3475
3476 // Creates a new dictionary.
3477 MUST_USE_RESULT static Handle<Derived> New(
3478 Isolate* isolate,
3479 int at_least_space_for,
3480 PretenureFlag pretenure = NOT_TENURED);
3481
3482 // Ensures that a new dictionary is created when the capacity is checked.
3483 void SetRequiresCopyOnCapacityChange();
3484
3485 // Ensure enough space for n additional elements.
3486 static Handle<Derived> EnsureCapacity(Handle<Derived> obj, int n, Key key);
3487
3488 #ifdef OBJECT_PRINT
3489 // For our gdb macros, we should perhaps change these in the future.
3490 void Print();
3491
3492 void Print(std::ostream& os); // NOLINT
3493 #endif
3494 // Returns the key (slow).
3495 Object* SlowReverseLookup(Object* value);
3496
3497 // Sets the entry to (key, value) pair.
3498 inline void SetEntry(int entry,
3499 Handle<Object> key,
3500 Handle<Object> value);
3501 inline void SetEntry(int entry,
3502 Handle<Object> key,
3503 Handle<Object> value,
3504 PropertyDetails details);
3505
3506 MUST_USE_RESULT static Handle<Derived> Add(
3507 Handle<Derived> dictionary,
3508 Key key,
3509 Handle<Object> value,
3510 PropertyDetails details);
3511
3512 // Returns iteration indices array for the |dictionary|.
3513 // Values are direct indices in the |HashTable| array.
3514 static Handle<FixedArray> BuildIterationIndicesArray(
3515 Handle<Derived> dictionary);
3516
3517 protected:
3518 // Generic at put operation.
3519 MUST_USE_RESULT static Handle<Derived> AtPut(
3520 Handle<Derived> dictionary,
3521 Key key,
3522 Handle<Object> value);
3523
3524 // Add entry to dictionary.
3525 static void AddEntry(
3526 Handle<Derived> dictionary,
3527 Key key,
3528 Handle<Object> value,
3529 PropertyDetails details,
3530 uint32_t hash);
3531
3532 // Generate new enumeration indices to avoid enumeration index overflow.
3533 // Returns iteration indices array for the |dictionary|.
3534 static Handle<FixedArray> GenerateNewEnumerationIndices(
3535 Handle<Derived> dictionary);
3536 static const int kMaxNumberKeyIndex = DerivedHashTable::kPrefixStartIndex;
3537 static const int kNextEnumerationIndexIndex = kMaxNumberKeyIndex + 1;
3538 };
3539
3540
3541 template <typename Derived, typename Shape>
3542 class NameDictionaryBase : public Dictionary<Derived, Shape, Handle<Name> > {
3543 typedef Dictionary<Derived, Shape, Handle<Name> > DerivedDictionary;
3544
3545 public:
3546 // Find entry for key, otherwise return kNotFound. Optimized version of
3547 // HashTable::FindEntry.
3548 int FindEntry(Handle<Name> key);
3549 };
3550
3551
3552 template <typename Key>
3553 class BaseDictionaryShape : public BaseShape<Key> {
3554 public:
3555 template <typename Dictionary>
DetailsAt(Dictionary * dict,int entry)3556 static inline PropertyDetails DetailsAt(Dictionary* dict, int entry) {
3557 STATIC_ASSERT(Dictionary::kEntrySize == 3);
3558 DCHECK(entry >= 0); // Not found is -1, which is not caught by get().
3559 return PropertyDetails(Smi::cast(dict->get(
3560 Dictionary::EntryToIndex(entry) + Dictionary::kEntryDetailsIndex)));
3561 }
3562
3563 template <typename Dictionary>
DetailsAtPut(Dictionary * dict,int entry,PropertyDetails value)3564 static inline void DetailsAtPut(Dictionary* dict, int entry,
3565 PropertyDetails value) {
3566 STATIC_ASSERT(Dictionary::kEntrySize == 3);
3567 dict->set(Dictionary::EntryToIndex(entry) + Dictionary::kEntryDetailsIndex,
3568 value.AsSmi());
3569 }
3570
3571 template <typename Dictionary>
IsDeleted(Dictionary * dict,int entry)3572 static bool IsDeleted(Dictionary* dict, int entry) {
3573 return false;
3574 }
3575
3576 template <typename Dictionary>
3577 static inline void SetEntry(Dictionary* dict, int entry, Handle<Object> key,
3578 Handle<Object> value, PropertyDetails details);
3579 };
3580
3581
3582 class NameDictionaryShape : public BaseDictionaryShape<Handle<Name> > {
3583 public:
3584 static inline bool IsMatch(Handle<Name> key, Object* other);
3585 static inline uint32_t Hash(Handle<Name> key);
3586 static inline uint32_t HashForObject(Handle<Name> key, Object* object);
3587 static inline Handle<Object> AsHandle(Isolate* isolate, Handle<Name> key);
3588 static const int kPrefixSize = 2;
3589 static const int kEntrySize = 3;
3590 static const int kEntryValueIndex = 1;
3591 static const int kEntryDetailsIndex = 2;
3592 static const bool kIsEnumerable = true;
3593 };
3594
3595
3596 class NameDictionary
3597 : public NameDictionaryBase<NameDictionary, NameDictionaryShape> {
3598 typedef NameDictionaryBase<NameDictionary, NameDictionaryShape>
3599 DerivedDictionary;
3600
3601 public:
3602 DECLARE_CAST(NameDictionary)
3603
3604 inline static Handle<FixedArray> DoGenerateNewEnumerationIndices(
3605 Handle<NameDictionary> dictionary);
3606
3607 static const int kEntryValueIndex = 1;
3608 static const int kEntryDetailsIndex = 2;
3609 };
3610
3611
3612 class GlobalDictionaryShape : public NameDictionaryShape {
3613 public:
3614 static const int kEntrySize = 2; // Overrides NameDictionaryShape::kEntrySize
3615
3616 template <typename Dictionary>
3617 static inline PropertyDetails DetailsAt(Dictionary* dict, int entry);
3618
3619 template <typename Dictionary>
3620 static inline void DetailsAtPut(Dictionary* dict, int entry,
3621 PropertyDetails value);
3622
3623 template <typename Dictionary>
3624 static bool IsDeleted(Dictionary* dict, int entry);
3625
3626 template <typename Dictionary>
3627 static inline void SetEntry(Dictionary* dict, int entry, Handle<Object> key,
3628 Handle<Object> value, PropertyDetails details);
3629 };
3630
3631
3632 class GlobalDictionary
3633 : public NameDictionaryBase<GlobalDictionary, GlobalDictionaryShape> {
3634 public:
3635 DECLARE_CAST(GlobalDictionary)
3636
3637 static const int kEntryValueIndex = 1;
3638 };
3639
3640
3641 class NumberDictionaryShape : public BaseDictionaryShape<uint32_t> {
3642 public:
3643 static inline bool IsMatch(uint32_t key, Object* other);
3644 static inline Handle<Object> AsHandle(Isolate* isolate, uint32_t key);
3645 static const int kEntrySize = 3;
3646 static const bool kIsEnumerable = false;
3647 };
3648
3649
3650 class SeededNumberDictionaryShape : public NumberDictionaryShape {
3651 public:
3652 static const bool UsesSeed = true;
3653 static const int kPrefixSize = 2;
3654
3655 static inline uint32_t SeededHash(uint32_t key, uint32_t seed);
3656 static inline uint32_t SeededHashForObject(uint32_t key,
3657 uint32_t seed,
3658 Object* object);
3659 };
3660
3661
3662 class UnseededNumberDictionaryShape : public NumberDictionaryShape {
3663 public:
3664 static const int kPrefixSize = 0;
3665
3666 static inline uint32_t Hash(uint32_t key);
3667 static inline uint32_t HashForObject(uint32_t key, Object* object);
3668 };
3669
3670
3671 class SeededNumberDictionary
3672 : public Dictionary<SeededNumberDictionary,
3673 SeededNumberDictionaryShape,
3674 uint32_t> {
3675 public:
3676 DECLARE_CAST(SeededNumberDictionary)
3677
3678 // Type specific at put (default NONE attributes is used when adding).
3679 MUST_USE_RESULT static Handle<SeededNumberDictionary> AtNumberPut(
3680 Handle<SeededNumberDictionary> dictionary, uint32_t key,
3681 Handle<Object> value, bool used_as_prototype);
3682 MUST_USE_RESULT static Handle<SeededNumberDictionary> AddNumberEntry(
3683 Handle<SeededNumberDictionary> dictionary, uint32_t key,
3684 Handle<Object> value, PropertyDetails details, bool used_as_prototype);
3685
3686 // Set an existing entry or add a new one if needed.
3687 // Return the updated dictionary.
3688 MUST_USE_RESULT static Handle<SeededNumberDictionary> Set(
3689 Handle<SeededNumberDictionary> dictionary, uint32_t key,
3690 Handle<Object> value, PropertyDetails details, bool used_as_prototype);
3691
3692 void UpdateMaxNumberKey(uint32_t key, bool used_as_prototype);
3693
3694 // Returns true if the dictionary contains any elements that are non-writable,
3695 // non-configurable, non-enumerable, or have getters/setters.
3696 bool HasComplexElements();
3697
3698 // If slow elements are required we will never go back to fast-case
3699 // for the elements kept in this dictionary. We require slow
3700 // elements if an element has been added at an index larger than
3701 // kRequiresSlowElementsLimit or set_requires_slow_elements() has been called
3702 // when defining a getter or setter with a number key.
3703 inline bool requires_slow_elements();
3704 inline void set_requires_slow_elements();
3705
3706 // Get the value of the max number key that has been added to this
3707 // dictionary. max_number_key can only be called if
3708 // requires_slow_elements returns false.
3709 inline uint32_t max_number_key();
3710
3711 static const int kEntryValueIndex = 1;
3712 static const int kEntryDetailsIndex = 2;
3713
3714 // Bit masks.
3715 static const int kRequiresSlowElementsMask = 1;
3716 static const int kRequiresSlowElementsTagSize = 1;
3717 static const uint32_t kRequiresSlowElementsLimit = (1 << 29) - 1;
3718 };
3719
3720
3721 class UnseededNumberDictionary
3722 : public Dictionary<UnseededNumberDictionary,
3723 UnseededNumberDictionaryShape,
3724 uint32_t> {
3725 public:
3726 DECLARE_CAST(UnseededNumberDictionary)
3727
3728 // Type specific at put (default NONE attributes is used when adding).
3729 MUST_USE_RESULT static Handle<UnseededNumberDictionary> AtNumberPut(
3730 Handle<UnseededNumberDictionary> dictionary,
3731 uint32_t key,
3732 Handle<Object> value);
3733 MUST_USE_RESULT static Handle<UnseededNumberDictionary> AddNumberEntry(
3734 Handle<UnseededNumberDictionary> dictionary,
3735 uint32_t key,
3736 Handle<Object> value);
3737
3738 // Set an existing entry or add a new one if needed.
3739 // Return the updated dictionary.
3740 MUST_USE_RESULT static Handle<UnseededNumberDictionary> Set(
3741 Handle<UnseededNumberDictionary> dictionary,
3742 uint32_t key,
3743 Handle<Object> value);
3744
3745 static const int kEntryValueIndex = 1;
3746 static const int kEntryDetailsIndex = 2;
3747 };
3748
3749
3750 class ObjectHashTableShape : public BaseShape<Handle<Object> > {
3751 public:
3752 static inline bool IsMatch(Handle<Object> key, Object* other);
3753 static inline uint32_t Hash(Handle<Object> key);
3754 static inline uint32_t HashForObject(Handle<Object> key, Object* object);
3755 static inline Handle<Object> AsHandle(Isolate* isolate, Handle<Object> key);
3756 static const int kPrefixSize = 0;
3757 static const int kEntrySize = 2;
3758 };
3759
3760
3761 // ObjectHashTable maps keys that are arbitrary objects to object values by
3762 // using the identity hash of the key for hashing purposes.
3763 class ObjectHashTable: public HashTable<ObjectHashTable,
3764 ObjectHashTableShape,
3765 Handle<Object> > {
3766 typedef HashTable<
3767 ObjectHashTable, ObjectHashTableShape, Handle<Object> > DerivedHashTable;
3768 public:
3769 DECLARE_CAST(ObjectHashTable)
3770
3771 // Attempt to shrink hash table after removal of key.
3772 MUST_USE_RESULT static inline Handle<ObjectHashTable> Shrink(
3773 Handle<ObjectHashTable> table,
3774 Handle<Object> key);
3775
3776 // Looks up the value associated with the given key. The hole value is
3777 // returned in case the key is not present.
3778 Object* Lookup(Handle<Object> key);
3779 Object* Lookup(Handle<Object> key, int32_t hash);
3780 Object* Lookup(Isolate* isolate, Handle<Object> key, int32_t hash);
3781
3782 // Adds (or overwrites) the value associated with the given key.
3783 static Handle<ObjectHashTable> Put(Handle<ObjectHashTable> table,
3784 Handle<Object> key,
3785 Handle<Object> value);
3786 static Handle<ObjectHashTable> Put(Handle<ObjectHashTable> table,
3787 Handle<Object> key, Handle<Object> value,
3788 int32_t hash);
3789
3790 // Returns an ObjectHashTable (possibly |table|) where |key| has been removed.
3791 static Handle<ObjectHashTable> Remove(Handle<ObjectHashTable> table,
3792 Handle<Object> key,
3793 bool* was_present);
3794 static Handle<ObjectHashTable> Remove(Handle<ObjectHashTable> table,
3795 Handle<Object> key, bool* was_present,
3796 int32_t hash);
3797
3798 protected:
3799 friend class MarkCompactCollector;
3800
3801 void AddEntry(int entry, Object* key, Object* value);
3802 void RemoveEntry(int entry);
3803
3804 // Returns the index to the value of an entry.
EntryToValueIndex(int entry)3805 static inline int EntryToValueIndex(int entry) {
3806 return EntryToIndex(entry) + 1;
3807 }
3808 };
3809
3810
3811 // OrderedHashTable is a HashTable with Object keys that preserves
3812 // insertion order. There are Map and Set interfaces (OrderedHashMap
3813 // and OrderedHashTable, below). It is meant to be used by JSMap/JSSet.
3814 //
3815 // Only Object* keys are supported, with Object::SameValueZero() used as the
3816 // equality operator and Object::GetHash() for the hash function.
3817 //
3818 // Based on the "Deterministic Hash Table" as described by Jason Orendorff at
3819 // https://wiki.mozilla.org/User:Jorend/Deterministic_hash_tables
3820 // Originally attributed to Tyler Close.
3821 //
3822 // Memory layout:
3823 // [0]: bucket count
3824 // [1]: element count
3825 // [2]: deleted element count
3826 // [3..(3 + NumberOfBuckets() - 1)]: "hash table", where each item is an
3827 // offset into the data table (see below) where the
3828 // first item in this bucket is stored.
3829 // [3 + NumberOfBuckets()..length]: "data table", an array of length
3830 // Capacity() * kEntrySize, where the first entrysize
3831 // items are handled by the derived class and the
3832 // item at kChainOffset is another entry into the
3833 // data table indicating the next entry in this hash
3834 // bucket.
3835 //
3836 // When we transition the table to a new version we obsolete it and reuse parts
3837 // of the memory to store information how to transition an iterator to the new
3838 // table:
3839 //
3840 // Memory layout for obsolete table:
3841 // [0]: bucket count
3842 // [1]: Next newer table
3843 // [2]: Number of removed holes or -1 when the table was cleared.
3844 // [3..(3 + NumberOfRemovedHoles() - 1)]: The indexes of the removed holes.
3845 // [3 + NumberOfRemovedHoles()..length]: Not used
3846 //
3847 template<class Derived, class Iterator, int entrysize>
3848 class OrderedHashTable: public FixedArray {
3849 public:
3850 // Returns an OrderedHashTable with a capacity of at least |capacity|.
3851 static Handle<Derived> Allocate(
3852 Isolate* isolate, int capacity, PretenureFlag pretenure = NOT_TENURED);
3853
3854 // Returns an OrderedHashTable (possibly |table|) with enough space
3855 // to add at least one new element.
3856 static Handle<Derived> EnsureGrowable(Handle<Derived> table);
3857
3858 // Returns an OrderedHashTable (possibly |table|) that's shrunken
3859 // if possible.
3860 static Handle<Derived> Shrink(Handle<Derived> table);
3861
3862 // Returns a new empty OrderedHashTable and records the clearing so that
3863 // existing iterators can be updated.
3864 static Handle<Derived> Clear(Handle<Derived> table);
3865
3866 // Returns a true if the OrderedHashTable contains the key
3867 static bool HasKey(Handle<Derived> table, Handle<Object> key);
3868
NumberOfElements()3869 int NumberOfElements() {
3870 return Smi::cast(get(kNumberOfElementsIndex))->value();
3871 }
3872
NumberOfDeletedElements()3873 int NumberOfDeletedElements() {
3874 return Smi::cast(get(kNumberOfDeletedElementsIndex))->value();
3875 }
3876
3877 // Returns the number of contiguous entries in the data table, starting at 0,
3878 // that either are real entries or have been deleted.
UsedCapacity()3879 int UsedCapacity() { return NumberOfElements() + NumberOfDeletedElements(); }
3880
NumberOfBuckets()3881 int NumberOfBuckets() {
3882 return Smi::cast(get(kNumberOfBucketsIndex))->value();
3883 }
3884
3885 // Returns an index into |this| for the given entry.
EntryToIndex(int entry)3886 int EntryToIndex(int entry) {
3887 return kHashTableStartIndex + NumberOfBuckets() + (entry * kEntrySize);
3888 }
3889
HashToBucket(int hash)3890 int HashToBucket(int hash) { return hash & (NumberOfBuckets() - 1); }
3891
HashToEntry(int hash)3892 int HashToEntry(int hash) {
3893 int bucket = HashToBucket(hash);
3894 Object* entry = this->get(kHashTableStartIndex + bucket);
3895 return Smi::cast(entry)->value();
3896 }
3897
KeyToFirstEntry(Isolate * isolate,Object * key)3898 int KeyToFirstEntry(Isolate* isolate, Object* key) {
3899 Object* hash = key->GetHash();
3900 // If the object does not have an identity hash, it was never used as a key
3901 if (hash->IsUndefined(isolate)) return kNotFound;
3902 return HashToEntry(Smi::cast(hash)->value());
3903 }
3904
NextChainEntry(int entry)3905 int NextChainEntry(int entry) {
3906 Object* next_entry = get(EntryToIndex(entry) + kChainOffset);
3907 return Smi::cast(next_entry)->value();
3908 }
3909
3910 // use KeyAt(i)->IsTheHole(isolate) to determine if this is a deleted entry.
KeyAt(int entry)3911 Object* KeyAt(int entry) {
3912 DCHECK_LT(entry, this->UsedCapacity());
3913 return get(EntryToIndex(entry));
3914 }
3915
IsObsolete()3916 bool IsObsolete() {
3917 return !get(kNextTableIndex)->IsSmi();
3918 }
3919
3920 // The next newer table. This is only valid if the table is obsolete.
NextTable()3921 Derived* NextTable() {
3922 return Derived::cast(get(kNextTableIndex));
3923 }
3924
3925 // When the table is obsolete we store the indexes of the removed holes.
RemovedIndexAt(int index)3926 int RemovedIndexAt(int index) {
3927 return Smi::cast(get(kRemovedHolesIndex + index))->value();
3928 }
3929
3930 static const int kNotFound = -1;
3931 static const int kMinCapacity = 4;
3932
3933 static const int kNumberOfBucketsIndex = 0;
3934 static const int kNumberOfElementsIndex = kNumberOfBucketsIndex + 1;
3935 static const int kNumberOfDeletedElementsIndex = kNumberOfElementsIndex + 1;
3936 static const int kHashTableStartIndex = kNumberOfDeletedElementsIndex + 1;
3937 static const int kNextTableIndex = kNumberOfElementsIndex;
3938
3939 static const int kNumberOfBucketsOffset =
3940 kHeaderSize + kNumberOfBucketsIndex * kPointerSize;
3941 static const int kNumberOfElementsOffset =
3942 kHeaderSize + kNumberOfElementsIndex * kPointerSize;
3943 static const int kNumberOfDeletedElementsOffset =
3944 kHeaderSize + kNumberOfDeletedElementsIndex * kPointerSize;
3945 static const int kHashTableStartOffset =
3946 kHeaderSize + kHashTableStartIndex * kPointerSize;
3947 static const int kNextTableOffset =
3948 kHeaderSize + kNextTableIndex * kPointerSize;
3949
3950 static const int kEntrySize = entrysize + 1;
3951 static const int kChainOffset = entrysize;
3952
3953 static const int kLoadFactor = 2;
3954
3955 // NumberOfDeletedElements is set to kClearedTableSentinel when
3956 // the table is cleared, which allows iterator transitions to
3957 // optimize that case.
3958 static const int kClearedTableSentinel = -1;
3959
3960 protected:
3961 static Handle<Derived> Rehash(Handle<Derived> table, int new_capacity);
3962
SetNumberOfBuckets(int num)3963 void SetNumberOfBuckets(int num) {
3964 set(kNumberOfBucketsIndex, Smi::FromInt(num));
3965 }
3966
SetNumberOfElements(int num)3967 void SetNumberOfElements(int num) {
3968 set(kNumberOfElementsIndex, Smi::FromInt(num));
3969 }
3970
SetNumberOfDeletedElements(int num)3971 void SetNumberOfDeletedElements(int num) {
3972 set(kNumberOfDeletedElementsIndex, Smi::FromInt(num));
3973 }
3974
3975 // Returns the number elements that can fit into the allocated buffer.
Capacity()3976 int Capacity() {
3977 return NumberOfBuckets() * kLoadFactor;
3978 }
3979
SetNextTable(Derived * next_table)3980 void SetNextTable(Derived* next_table) {
3981 set(kNextTableIndex, next_table);
3982 }
3983
SetRemovedIndexAt(int index,int removed_index)3984 void SetRemovedIndexAt(int index, int removed_index) {
3985 return set(kRemovedHolesIndex + index, Smi::FromInt(removed_index));
3986 }
3987
3988 static const int kRemovedHolesIndex = kHashTableStartIndex;
3989
3990 static const int kMaxCapacity =
3991 (FixedArray::kMaxLength - kHashTableStartIndex)
3992 / (1 + (kEntrySize * kLoadFactor));
3993 };
3994
3995
3996 class JSSetIterator;
3997
3998
3999 class OrderedHashSet: public OrderedHashTable<
4000 OrderedHashSet, JSSetIterator, 1> {
4001 public:
4002 DECLARE_CAST(OrderedHashSet)
4003
4004 static Handle<OrderedHashSet> Add(Handle<OrderedHashSet> table,
4005 Handle<Object> value);
4006 static Handle<FixedArray> ConvertToKeysArray(Handle<OrderedHashSet> table,
4007 GetKeysConversion convert);
4008 };
4009
4010
4011 class JSMapIterator;
4012
4013
4014 class OrderedHashMap
4015 : public OrderedHashTable<OrderedHashMap, JSMapIterator, 2> {
4016 public:
4017 DECLARE_CAST(OrderedHashMap)
4018
4019 inline Object* ValueAt(int entry);
4020
4021 static const int kValueOffset = 1;
4022 };
4023
4024
4025 template <int entrysize>
4026 class WeakHashTableShape : public BaseShape<Handle<Object> > {
4027 public:
4028 static inline bool IsMatch(Handle<Object> key, Object* other);
4029 static inline uint32_t Hash(Handle<Object> key);
4030 static inline uint32_t HashForObject(Handle<Object> key, Object* object);
4031 static inline Handle<Object> AsHandle(Isolate* isolate, Handle<Object> key);
4032 static const int kPrefixSize = 0;
4033 static const int kEntrySize = entrysize;
4034 };
4035
4036
4037 // WeakHashTable maps keys that are arbitrary heap objects to heap object
4038 // values. The table wraps the keys in weak cells and store values directly.
4039 // Thus it references keys weakly and values strongly.
4040 class WeakHashTable: public HashTable<WeakHashTable,
4041 WeakHashTableShape<2>,
4042 Handle<Object> > {
4043 typedef HashTable<
4044 WeakHashTable, WeakHashTableShape<2>, Handle<Object> > DerivedHashTable;
4045 public:
4046 DECLARE_CAST(WeakHashTable)
4047
4048 // Looks up the value associated with the given key. The hole value is
4049 // returned in case the key is not present.
4050 Object* Lookup(Handle<HeapObject> key);
4051
4052 // Adds (or overwrites) the value associated with the given key. Mapping a
4053 // key to the hole value causes removal of the whole entry.
4054 MUST_USE_RESULT static Handle<WeakHashTable> Put(Handle<WeakHashTable> table,
4055 Handle<HeapObject> key,
4056 Handle<HeapObject> value);
4057
4058 static Handle<FixedArray> GetValues(Handle<WeakHashTable> table);
4059
4060 private:
4061 friend class MarkCompactCollector;
4062
4063 void AddEntry(int entry, Handle<WeakCell> key, Handle<HeapObject> value);
4064
4065 // Returns the index to the value of an entry.
EntryToValueIndex(int entry)4066 static inline int EntryToValueIndex(int entry) {
4067 return EntryToIndex(entry) + 1;
4068 }
4069 };
4070
4071
4072 // ScopeInfo represents information about different scopes of a source
4073 // program and the allocation of the scope's variables. Scope information
4074 // is stored in a compressed form in ScopeInfo objects and is used
4075 // at runtime (stack dumps, deoptimization, etc.).
4076
4077 // This object provides quick access to scope info details for runtime
4078 // routines.
4079 class ScopeInfo : public FixedArray {
4080 public:
4081 DECLARE_CAST(ScopeInfo)
4082
4083 // Return the type of this scope.
4084 ScopeType scope_type();
4085
4086 // Does this scope call eval?
4087 bool CallsEval();
4088
4089 // Return the language mode of this scope.
4090 LanguageMode language_mode();
4091
4092 // True if this scope is a (var) declaration scope.
4093 bool is_declaration_scope();
4094
4095 // Does this scope make a sloppy eval call?
CallsSloppyEval()4096 bool CallsSloppyEval() { return CallsEval() && is_sloppy(language_mode()); }
4097
4098 // Return the total number of locals allocated on the stack and in the
4099 // context. This includes the parameters that are allocated in the context.
4100 int LocalCount();
4101
4102 // Return the number of stack slots for code. This number consists of two
4103 // parts:
4104 // 1. One stack slot per stack allocated local.
4105 // 2. One stack slot for the function name if it is stack allocated.
4106 int StackSlotCount();
4107
4108 // Return the number of context slots for code if a context is allocated. This
4109 // number consists of three parts:
4110 // 1. Size of fixed header for every context: Context::MIN_CONTEXT_SLOTS
4111 // 2. One context slot per context allocated local.
4112 // 3. One context slot for the function name if it is context allocated.
4113 // Parameters allocated in the context count as context allocated locals. If
4114 // no contexts are allocated for this scope ContextLength returns 0.
4115 int ContextLength();
4116
4117 // Does this scope declare a "this" binding?
4118 bool HasReceiver();
4119
4120 // Does this scope declare a "this" binding, and the "this" binding is stack-
4121 // or context-allocated?
4122 bool HasAllocatedReceiver();
4123
4124 // Does this scope declare a "new.target" binding?
4125 bool HasNewTarget();
4126
4127 // Is this scope the scope of a named function expression?
4128 bool HasFunctionName();
4129
4130 // Return if this has context allocated locals.
4131 bool HasHeapAllocatedLocals();
4132
4133 // Return if contexts are allocated for this scope.
4134 bool HasContext();
4135
4136 // Return if this is a function scope with "use asm".
4137 inline bool IsAsmModule();
4138
4139 // Return if this is a nested function within an asm module scope.
4140 inline bool IsAsmFunction();
4141
4142 inline bool HasSimpleParameters();
4143
4144 // Return the function_name if present.
4145 String* FunctionName();
4146
4147 // Return the name of the given parameter.
4148 String* ParameterName(int var);
4149
4150 // Return the name of the given local.
4151 String* LocalName(int var);
4152
4153 // Return the name of the given stack local.
4154 String* StackLocalName(int var);
4155
4156 // Return the name of the given stack local.
4157 int StackLocalIndex(int var);
4158
4159 // Return the name of the given context local.
4160 String* ContextLocalName(int var);
4161
4162 // Return the mode of the given context local.
4163 VariableMode ContextLocalMode(int var);
4164
4165 // Return the initialization flag of the given context local.
4166 InitializationFlag ContextLocalInitFlag(int var);
4167
4168 // Return the initialization flag of the given context local.
4169 MaybeAssignedFlag ContextLocalMaybeAssignedFlag(int var);
4170
4171 // Return true if this local was introduced by the compiler, and should not be
4172 // exposed to the user in a debugger.
4173 static bool VariableIsSynthetic(String* name);
4174
4175 // Lookup support for serialized scope info. Returns the
4176 // the stack slot index for a given slot name if the slot is
4177 // present; otherwise returns a value < 0. The name must be an internalized
4178 // string.
4179 int StackSlotIndex(String* name);
4180
4181 // Lookup support for serialized scope info. Returns the local context slot
4182 // index for a given slot name if the slot is present; otherwise
4183 // returns a value < 0. The name must be an internalized string.
4184 // If the slot is present and mode != NULL, sets *mode to the corresponding
4185 // mode for that variable.
4186 static int ContextSlotIndex(Handle<ScopeInfo> scope_info, Handle<String> name,
4187 VariableMode* mode, InitializationFlag* init_flag,
4188 MaybeAssignedFlag* maybe_assigned_flag);
4189
4190 // Similar to ContextSlotIndex() but this method searches only among
4191 // global slots of the serialized scope info. Returns the context slot index
4192 // for a given slot name if the slot is present; otherwise returns a
4193 // value < 0. The name must be an internalized string. If the slot is present
4194 // and mode != NULL, sets *mode to the corresponding mode for that variable.
4195 static int ContextGlobalSlotIndex(Handle<ScopeInfo> scope_info,
4196 Handle<String> name, VariableMode* mode,
4197 InitializationFlag* init_flag,
4198 MaybeAssignedFlag* maybe_assigned_flag);
4199
4200 // Lookup the name of a certain context slot by its index.
4201 String* ContextSlotName(int slot_index);
4202
4203 // Lookup support for serialized scope info. Returns the
4204 // parameter index for a given parameter name if the parameter is present;
4205 // otherwise returns a value < 0. The name must be an internalized string.
4206 int ParameterIndex(String* name);
4207
4208 // Lookup support for serialized scope info. Returns the function context
4209 // slot index if the function name is present and context-allocated (named
4210 // function expressions, only), otherwise returns a value < 0. The name
4211 // must be an internalized string.
4212 int FunctionContextSlotIndex(String* name, VariableMode* mode);
4213
4214 // Lookup support for serialized scope info. Returns the receiver context
4215 // slot index if scope has a "this" binding, and the binding is
4216 // context-allocated. Otherwise returns a value < 0.
4217 int ReceiverContextSlotIndex();
4218
4219 FunctionKind function_kind();
4220
4221 static Handle<ScopeInfo> Create(Isolate* isolate, Zone* zone, Scope* scope);
4222 static Handle<ScopeInfo> CreateGlobalThisBinding(Isolate* isolate);
4223
4224 // Serializes empty scope info.
4225 static ScopeInfo* Empty(Isolate* isolate);
4226
4227 #ifdef DEBUG
4228 void Print();
4229 #endif
4230
4231 // The layout of the static part of a ScopeInfo is as follows. Each entry is
4232 // numeric and occupies one array slot.
4233 // 1. A set of properties of the scope
4234 // 2. The number of parameters. This only applies to function scopes. For
4235 // non-function scopes this is 0.
4236 // 3. The number of non-parameter variables allocated on the stack.
4237 // 4. The number of non-parameter and parameter variables allocated in the
4238 // context.
4239 #define FOR_EACH_SCOPE_INFO_NUMERIC_FIELD(V) \
4240 V(Flags) \
4241 V(ParameterCount) \
4242 V(StackLocalCount) \
4243 V(ContextLocalCount) \
4244 V(ContextGlobalCount)
4245
4246 #define FIELD_ACCESSORS(name) \
4247 inline void Set##name(int value); \
4248 inline int name();
4249 FOR_EACH_SCOPE_INFO_NUMERIC_FIELD(FIELD_ACCESSORS)
4250 #undef FIELD_ACCESSORS
4251
4252 enum {
4253 #define DECL_INDEX(name) k##name,
4254 FOR_EACH_SCOPE_INFO_NUMERIC_FIELD(DECL_INDEX)
4255 #undef DECL_INDEX
4256 kVariablePartIndex
4257 };
4258
4259 private:
4260 // The layout of the variable part of a ScopeInfo is as follows:
4261 // 1. ParameterEntries:
4262 // This part stores the names of the parameters for function scopes. One
4263 // slot is used per parameter, so in total this part occupies
4264 // ParameterCount() slots in the array. For other scopes than function
4265 // scopes ParameterCount() is 0.
4266 // 2. StackLocalFirstSlot:
4267 // Index of a first stack slot for stack local. Stack locals belonging to
4268 // this scope are located on a stack at slots starting from this index.
4269 // 3. StackLocalEntries:
4270 // Contains the names of local variables that are allocated on the stack,
4271 // in increasing order of the stack slot index. First local variable has
4272 // a stack slot index defined in StackLocalFirstSlot (point 2 above).
4273 // One slot is used per stack local, so in total this part occupies
4274 // StackLocalCount() slots in the array.
4275 // 4. ContextLocalNameEntries:
4276 // Contains the names of local variables and parameters that are allocated
4277 // in the context. They are stored in increasing order of the context slot
4278 // index starting with Context::MIN_CONTEXT_SLOTS. One slot is used per
4279 // context local, so in total this part occupies ContextLocalCount() slots
4280 // in the array.
4281 // 5. ContextLocalInfoEntries:
4282 // Contains the variable modes and initialization flags corresponding to
4283 // the context locals in ContextLocalNameEntries. One slot is used per
4284 // context local, so in total this part occupies ContextLocalCount()
4285 // slots in the array.
4286 // 6. RecieverEntryIndex:
4287 // If the scope binds a "this" value, one slot is reserved to hold the
4288 // context or stack slot index for the variable.
4289 // 7. FunctionNameEntryIndex:
4290 // If the scope belongs to a named function expression this part contains
4291 // information about the function variable. It always occupies two array
4292 // slots: a. The name of the function variable.
4293 // b. The context or stack slot index for the variable.
4294 int ParameterEntriesIndex();
4295 int StackLocalFirstSlotIndex();
4296 int StackLocalEntriesIndex();
4297 int ContextLocalNameEntriesIndex();
4298 int ContextGlobalNameEntriesIndex();
4299 int ContextLocalInfoEntriesIndex();
4300 int ContextGlobalInfoEntriesIndex();
4301 int ReceiverEntryIndex();
4302 int FunctionNameEntryIndex();
4303
4304 int Lookup(Handle<String> name, int start, int end, VariableMode* mode,
4305 VariableLocation* location, InitializationFlag* init_flag,
4306 MaybeAssignedFlag* maybe_assigned_flag);
4307
4308 // Used for the function name variable for named function expressions, and for
4309 // the receiver.
4310 enum VariableAllocationInfo { NONE, STACK, CONTEXT, UNUSED };
4311
4312 // Properties of scopes.
4313 class ScopeTypeField : public BitField<ScopeType, 0, 4> {};
4314 class CallsEvalField : public BitField<bool, ScopeTypeField::kNext, 1> {};
4315 STATIC_ASSERT(LANGUAGE_END == 3);
4316 class LanguageModeField
4317 : public BitField<LanguageMode, CallsEvalField::kNext, 2> {};
4318 class DeclarationScopeField
4319 : public BitField<bool, LanguageModeField::kNext, 1> {};
4320 class ReceiverVariableField
4321 : public BitField<VariableAllocationInfo, DeclarationScopeField::kNext,
4322 2> {};
4323 class HasNewTargetField
4324 : public BitField<bool, ReceiverVariableField::kNext, 1> {};
4325 class FunctionVariableField
4326 : public BitField<VariableAllocationInfo, HasNewTargetField::kNext, 2> {};
4327 class FunctionVariableMode
4328 : public BitField<VariableMode, FunctionVariableField::kNext, 3> {};
4329 class AsmModuleField : public BitField<bool, FunctionVariableMode::kNext, 1> {
4330 };
4331 class AsmFunctionField : public BitField<bool, AsmModuleField::kNext, 1> {};
4332 class HasSimpleParametersField
4333 : public BitField<bool, AsmFunctionField::kNext, 1> {};
4334 class FunctionKindField
4335 : public BitField<FunctionKind, HasSimpleParametersField::kNext, 9> {};
4336
4337 // BitFields representing the encoded information for context locals in the
4338 // ContextLocalInfoEntries part.
4339 class ContextLocalMode: public BitField<VariableMode, 0, 3> {};
4340 class ContextLocalInitFlag: public BitField<InitializationFlag, 3, 1> {};
4341 class ContextLocalMaybeAssignedFlag
4342 : public BitField<MaybeAssignedFlag, 4, 1> {};
4343
4344 friend class ScopeIterator;
4345 };
4346
4347
4348 // The cache for maps used by normalized (dictionary mode) objects.
4349 // Such maps do not have property descriptors, so a typical program
4350 // needs very limited number of distinct normalized maps.
4351 class NormalizedMapCache: public FixedArray {
4352 public:
4353 static Handle<NormalizedMapCache> New(Isolate* isolate);
4354
4355 MUST_USE_RESULT MaybeHandle<Map> Get(Handle<Map> fast_map,
4356 PropertyNormalizationMode mode);
4357 void Set(Handle<Map> fast_map, Handle<Map> normalized_map);
4358
4359 void Clear();
4360
4361 DECLARE_CAST(NormalizedMapCache)
4362
4363 static inline bool IsNormalizedMapCache(const HeapObject* obj);
4364
4365 DECLARE_VERIFIER(NormalizedMapCache)
4366 private:
4367 static const int kEntries = 64;
4368
4369 static inline int GetIndex(Handle<Map> map);
4370
4371 // The following declarations hide base class methods.
4372 Object* get(int index);
4373 void set(int index, Object* value);
4374 };
4375
4376
4377 // ByteArray represents fixed sized byte arrays. Used for the relocation info
4378 // that is attached to code objects.
4379 class ByteArray: public FixedArrayBase {
4380 public:
4381 inline int Size();
4382
4383 // Setter and getter.
4384 inline byte get(int index);
4385 inline void set(int index, byte value);
4386
4387 // Copy in / copy out whole byte slices.
4388 inline void copy_out(int index, byte* buffer, int length);
4389 inline void copy_in(int index, const byte* buffer, int length);
4390
4391 // Treat contents as an int array.
4392 inline int get_int(int index);
4393 inline void set_int(int index, int value);
4394
SizeFor(int length)4395 static int SizeFor(int length) {
4396 return OBJECT_POINTER_ALIGN(kHeaderSize + length);
4397 }
4398 // We use byte arrays for free blocks in the heap. Given a desired size in
4399 // bytes that is a multiple of the word size and big enough to hold a byte
4400 // array, this function returns the number of elements a byte array should
4401 // have.
LengthFor(int size_in_bytes)4402 static int LengthFor(int size_in_bytes) {
4403 DCHECK(IsAligned(size_in_bytes, kPointerSize));
4404 DCHECK(size_in_bytes >= kHeaderSize);
4405 return size_in_bytes - kHeaderSize;
4406 }
4407
4408 // Returns data start address.
4409 inline Address GetDataStartAddress();
4410
4411 // Returns a pointer to the ByteArray object for a given data start address.
4412 static inline ByteArray* FromDataStartAddress(Address address);
4413
4414 DECLARE_CAST(ByteArray)
4415
4416 // Dispatched behavior.
4417 inline int ByteArraySize();
4418 DECLARE_PRINTER(ByteArray)
4419 DECLARE_VERIFIER(ByteArray)
4420
4421 // Layout description.
4422 static const int kAlignedSize = OBJECT_POINTER_ALIGN(kHeaderSize);
4423
4424 // Maximal memory consumption for a single ByteArray.
4425 static const int kMaxSize = 512 * MB;
4426 // Maximal length of a single ByteArray.
4427 static const int kMaxLength = kMaxSize - kHeaderSize;
4428
4429 private:
4430 DISALLOW_IMPLICIT_CONSTRUCTORS(ByteArray);
4431 };
4432
4433
4434 // BytecodeArray represents a sequence of interpreter bytecodes.
4435 class BytecodeArray : public FixedArrayBase {
4436 public:
SizeFor(int length)4437 static int SizeFor(int length) {
4438 return OBJECT_POINTER_ALIGN(kHeaderSize + length);
4439 }
4440
4441 // Setter and getter
4442 inline byte get(int index);
4443 inline void set(int index, byte value);
4444
4445 // Returns data start address.
4446 inline Address GetFirstBytecodeAddress();
4447
4448 // Accessors for frame size.
4449 inline int frame_size() const;
4450 inline void set_frame_size(int frame_size);
4451
4452 // Accessor for register count (derived from frame_size).
4453 inline int register_count() const;
4454
4455 // Accessors for parameter count (including implicit 'this' receiver).
4456 inline int parameter_count() const;
4457 inline void set_parameter_count(int number_of_parameters);
4458
4459 // Accessors for profiling count.
4460 inline int interrupt_budget() const;
4461 inline void set_interrupt_budget(int interrupt_budget);
4462
4463 // Accessors for the constant pool.
4464 DECL_ACCESSORS(constant_pool, FixedArray)
4465
4466 // Accessors for handler table containing offsets of exception handlers.
4467 DECL_ACCESSORS(handler_table, FixedArray)
4468
4469 // Accessors for source position table containing mappings between byte code
4470 // offset and source position.
4471 DECL_ACCESSORS(source_position_table, ByteArray)
4472
4473 DECLARE_CAST(BytecodeArray)
4474
4475 // Dispatched behavior.
4476 inline int BytecodeArraySize();
4477
4478 inline int instruction_size();
4479
4480 // Returns the size of bytecode and its metadata. This includes the size of
4481 // bytecode, constant pool, source position table, and handler table.
4482 inline int SizeIncludingMetadata();
4483
4484 int SourcePosition(int offset);
4485 int SourceStatementPosition(int offset);
4486
4487 DECLARE_PRINTER(BytecodeArray)
4488 DECLARE_VERIFIER(BytecodeArray)
4489
4490 void Disassemble(std::ostream& os);
4491
4492 void CopyBytecodesTo(BytecodeArray* to);
4493
4494 // Layout description.
4495 static const int kConstantPoolOffset = FixedArrayBase::kHeaderSize;
4496 static const int kHandlerTableOffset = kConstantPoolOffset + kPointerSize;
4497 static const int kSourcePositionTableOffset =
4498 kHandlerTableOffset + kPointerSize;
4499 static const int kFrameSizeOffset = kSourcePositionTableOffset + kPointerSize;
4500 static const int kParameterSizeOffset = kFrameSizeOffset + kIntSize;
4501 static const int kInterruptBudgetOffset = kParameterSizeOffset + kIntSize;
4502 static const int kHeaderSize = kInterruptBudgetOffset + kIntSize;
4503
4504 // Maximal memory consumption for a single BytecodeArray.
4505 static const int kMaxSize = 512 * MB;
4506 // Maximal length of a single BytecodeArray.
4507 static const int kMaxLength = kMaxSize - kHeaderSize;
4508
4509 class BodyDescriptor;
4510
4511 private:
4512 DISALLOW_IMPLICIT_CONSTRUCTORS(BytecodeArray);
4513 };
4514
4515
4516 // FreeSpace are fixed-size free memory blocks used by the heap and GC.
4517 // They look like heap objects (are heap object tagged and have a map) so that
4518 // the heap remains iterable. They have a size and a next pointer.
4519 // The next pointer is the raw address of the next FreeSpace object (or NULL)
4520 // in the free list.
4521 class FreeSpace: public HeapObject {
4522 public:
4523 // [size]: size of the free space including the header.
4524 inline int size() const;
4525 inline void set_size(int value);
4526
4527 inline int nobarrier_size() const;
4528 inline void nobarrier_set_size(int value);
4529
4530 inline int Size();
4531
4532 // Accessors for the next field.
4533 inline FreeSpace* next();
4534 inline void set_next(FreeSpace* next);
4535
4536 inline static FreeSpace* cast(HeapObject* obj);
4537
4538 // Dispatched behavior.
4539 DECLARE_PRINTER(FreeSpace)
4540 DECLARE_VERIFIER(FreeSpace)
4541
4542 // Layout description.
4543 // Size is smi tagged when it is stored.
4544 static const int kSizeOffset = HeapObject::kHeaderSize;
4545 static const int kNextOffset = POINTER_SIZE_ALIGN(kSizeOffset + kPointerSize);
4546
4547 private:
4548 DISALLOW_IMPLICIT_CONSTRUCTORS(FreeSpace);
4549 };
4550
4551
4552 // V has parameters (Type, type, TYPE, C type, element_size)
4553 #define TYPED_ARRAYS(V) \
4554 V(Uint8, uint8, UINT8, uint8_t, 1) \
4555 V(Int8, int8, INT8, int8_t, 1) \
4556 V(Uint16, uint16, UINT16, uint16_t, 2) \
4557 V(Int16, int16, INT16, int16_t, 2) \
4558 V(Uint32, uint32, UINT32, uint32_t, 4) \
4559 V(Int32, int32, INT32, int32_t, 4) \
4560 V(Float32, float32, FLOAT32, float, 4) \
4561 V(Float64, float64, FLOAT64, double, 8) \
4562 V(Uint8Clamped, uint8_clamped, UINT8_CLAMPED, uint8_t, 1)
4563
4564
4565 class FixedTypedArrayBase: public FixedArrayBase {
4566 public:
4567 // [base_pointer]: Either points to the FixedTypedArrayBase itself or nullptr.
4568 DECL_ACCESSORS(base_pointer, Object)
4569
4570 // [external_pointer]: Contains the offset between base_pointer and the start
4571 // of the data. If the base_pointer is a nullptr, the external_pointer
4572 // therefore points to the actual backing store.
4573 DECL_ACCESSORS(external_pointer, void)
4574
4575 // Dispatched behavior.
4576 DECLARE_CAST(FixedTypedArrayBase)
4577
4578 static const int kBasePointerOffset = FixedArrayBase::kHeaderSize;
4579 static const int kExternalPointerOffset = kBasePointerOffset + kPointerSize;
4580 static const int kHeaderSize =
4581 DOUBLE_POINTER_ALIGN(kExternalPointerOffset + kPointerSize);
4582
4583 static const int kDataOffset = kHeaderSize;
4584
4585 class BodyDescriptor;
4586
4587 inline int size();
4588
4589 static inline int TypedArraySize(InstanceType type, int length);
4590 inline int TypedArraySize(InstanceType type);
4591
4592 // Use with care: returns raw pointer into heap.
4593 inline void* DataPtr();
4594
4595 inline int DataSize();
4596
4597 private:
4598 static inline int ElementSize(InstanceType type);
4599
4600 inline int DataSize(InstanceType type);
4601
4602 DISALLOW_IMPLICIT_CONSTRUCTORS(FixedTypedArrayBase);
4603 };
4604
4605
4606 template <class Traits>
4607 class FixedTypedArray: public FixedTypedArrayBase {
4608 public:
4609 typedef typename Traits::ElementType ElementType;
4610 static const InstanceType kInstanceType = Traits::kInstanceType;
4611
4612 DECLARE_CAST(FixedTypedArray<Traits>)
4613
4614 inline ElementType get_scalar(int index);
4615 static inline Handle<Object> get(FixedTypedArray* array, int index);
4616 inline void set(int index, ElementType value);
4617
4618 static inline ElementType from_int(int value);
4619 static inline ElementType from_double(double value);
4620
4621 // This accessor applies the correct conversion from Smi, HeapNumber
4622 // and undefined.
4623 inline void SetValue(uint32_t index, Object* value);
4624
4625 DECLARE_PRINTER(FixedTypedArray)
4626 DECLARE_VERIFIER(FixedTypedArray)
4627
4628 private:
4629 DISALLOW_IMPLICIT_CONSTRUCTORS(FixedTypedArray);
4630 };
4631
4632 #define FIXED_TYPED_ARRAY_TRAITS(Type, type, TYPE, elementType, size) \
4633 class Type##ArrayTraits { \
4634 public: /* NOLINT */ \
4635 typedef elementType ElementType; \
4636 static const InstanceType kInstanceType = FIXED_##TYPE##_ARRAY_TYPE; \
4637 static const char* Designator() { return #type " array"; } \
4638 static inline Handle<Object> ToHandle(Isolate* isolate, \
4639 elementType scalar); \
4640 static inline elementType defaultValue(); \
4641 }; \
4642 \
4643 typedef FixedTypedArray<Type##ArrayTraits> Fixed##Type##Array;
4644
TYPED_ARRAYS(FIXED_TYPED_ARRAY_TRAITS)4645 TYPED_ARRAYS(FIXED_TYPED_ARRAY_TRAITS)
4646
4647 #undef FIXED_TYPED_ARRAY_TRAITS
4648
4649
4650 // DeoptimizationInputData is a fixed array used to hold the deoptimization
4651 // data for code generated by the Hydrogen/Lithium compiler. It also
4652 // contains information about functions that were inlined. If N different
4653 // functions were inlined then first N elements of the literal array will
4654 // contain these functions.
4655 //
4656 // It can be empty.
4657 class DeoptimizationInputData: public FixedArray {
4658 public:
4659 // Layout description. Indices in the array.
4660 static const int kTranslationByteArrayIndex = 0;
4661 static const int kInlinedFunctionCountIndex = 1;
4662 static const int kLiteralArrayIndex = 2;
4663 static const int kOsrAstIdIndex = 3;
4664 static const int kOsrPcOffsetIndex = 4;
4665 static const int kOptimizationIdIndex = 5;
4666 static const int kSharedFunctionInfoIndex = 6;
4667 static const int kWeakCellCacheIndex = 7;
4668 static const int kFirstDeoptEntryIndex = 8;
4669
4670 // Offsets of deopt entry elements relative to the start of the entry.
4671 static const int kAstIdRawOffset = 0;
4672 static const int kTranslationIndexOffset = 1;
4673 static const int kArgumentsStackHeightOffset = 2;
4674 static const int kPcOffset = 3;
4675 static const int kDeoptEntrySize = 4;
4676
4677 // Simple element accessors.
4678 #define DECLARE_ELEMENT_ACCESSORS(name, type) \
4679 inline type* name(); \
4680 inline void Set##name(type* value);
4681
4682 DECLARE_ELEMENT_ACCESSORS(TranslationByteArray, ByteArray)
4683 DECLARE_ELEMENT_ACCESSORS(InlinedFunctionCount, Smi)
4684 DECLARE_ELEMENT_ACCESSORS(LiteralArray, FixedArray)
4685 DECLARE_ELEMENT_ACCESSORS(OsrAstId, Smi)
4686 DECLARE_ELEMENT_ACCESSORS(OsrPcOffset, Smi)
4687 DECLARE_ELEMENT_ACCESSORS(OptimizationId, Smi)
4688 DECLARE_ELEMENT_ACCESSORS(SharedFunctionInfo, Object)
4689 DECLARE_ELEMENT_ACCESSORS(WeakCellCache, Object)
4690
4691 #undef DECLARE_ELEMENT_ACCESSORS
4692
4693 // Accessors for elements of the ith deoptimization entry.
4694 #define DECLARE_ENTRY_ACCESSORS(name, type) \
4695 inline type* name(int i); \
4696 inline void Set##name(int i, type* value);
4697
4698 DECLARE_ENTRY_ACCESSORS(AstIdRaw, Smi)
4699 DECLARE_ENTRY_ACCESSORS(TranslationIndex, Smi)
4700 DECLARE_ENTRY_ACCESSORS(ArgumentsStackHeight, Smi)
4701 DECLARE_ENTRY_ACCESSORS(Pc, Smi)
4702
4703 #undef DECLARE_ENTRY_ACCESSORS
4704
4705 inline BailoutId AstId(int i);
4706
4707 inline void SetAstId(int i, BailoutId value);
4708
4709 inline int DeoptCount();
4710
4711 // Allocates a DeoptimizationInputData.
4712 static Handle<DeoptimizationInputData> New(Isolate* isolate,
4713 int deopt_entry_count,
4714 PretenureFlag pretenure);
4715
4716 DECLARE_CAST(DeoptimizationInputData)
4717
4718 #ifdef ENABLE_DISASSEMBLER
4719 void DeoptimizationInputDataPrint(std::ostream& os); // NOLINT
4720 #endif
4721
4722 private:
4723 static int IndexForEntry(int i) {
4724 return kFirstDeoptEntryIndex + (i * kDeoptEntrySize);
4725 }
4726
4727
4728 static int LengthFor(int entry_count) { return IndexForEntry(entry_count); }
4729 };
4730
4731
4732 // DeoptimizationOutputData is a fixed array used to hold the deoptimization
4733 // data for code generated by the full compiler.
4734 // The format of the these objects is
4735 // [i * 2]: Ast ID for ith deoptimization.
4736 // [i * 2 + 1]: PC and state of ith deoptimization
4737 class DeoptimizationOutputData: public FixedArray {
4738 public:
4739 inline int DeoptPoints();
4740
4741 inline BailoutId AstId(int index);
4742
4743 inline void SetAstId(int index, BailoutId id);
4744
4745 inline Smi* PcAndState(int index);
4746 inline void SetPcAndState(int index, Smi* offset);
4747
LengthOfFixedArray(int deopt_points)4748 static int LengthOfFixedArray(int deopt_points) {
4749 return deopt_points * 2;
4750 }
4751
4752 // Allocates a DeoptimizationOutputData.
4753 static Handle<DeoptimizationOutputData> New(Isolate* isolate,
4754 int number_of_deopt_points,
4755 PretenureFlag pretenure);
4756
4757 DECLARE_CAST(DeoptimizationOutputData)
4758
4759 #ifdef ENABLE_DISASSEMBLER
4760 void DeoptimizationOutputDataPrint(std::ostream& os); // NOLINT
4761 #endif
4762 };
4763
4764
4765 // A literals array contains the literals for a JSFunction. It also holds
4766 // the type feedback vector.
4767 class LiteralsArray : public FixedArray {
4768 public:
4769 static const int kVectorIndex = 0;
4770 static const int kFirstLiteralIndex = 1;
4771 static const int kFeedbackVectorOffset;
4772 static const int kOffsetToFirstLiteral;
4773
OffsetOfLiteralAt(int index)4774 static int OffsetOfLiteralAt(int index) {
4775 return OffsetOfElementAt(index + kFirstLiteralIndex);
4776 }
4777
4778 inline TypeFeedbackVector* feedback_vector() const;
4779 inline void set_feedback_vector(TypeFeedbackVector* vector);
4780 inline Object* literal(int literal_index) const;
4781 inline void set_literal(int literal_index, Object* literal);
4782 inline void set_literal_undefined(int literal_index);
4783 inline int literals_count() const;
4784
4785 static Handle<LiteralsArray> New(Isolate* isolate,
4786 Handle<TypeFeedbackVector> vector,
4787 int number_of_literals,
4788 PretenureFlag pretenure);
4789
4790 DECLARE_CAST(LiteralsArray)
4791
4792 private:
4793 inline Object* get(int index) const;
4794 inline void set(int index, Object* value);
4795 inline void set(int index, Smi* value);
4796 inline void set(int index, Object* value, WriteBarrierMode mode);
4797 };
4798
4799
4800 // HandlerTable is a fixed array containing entries for exception handlers in
4801 // the code object it is associated with. The tables comes in two flavors:
4802 // 1) Based on ranges: Used for unoptimized code. Contains one entry per
4803 // exception handler and a range representing the try-block covered by that
4804 // handler. Layout looks as follows:
4805 // [ range-start , range-end , handler-offset , handler-data ]
4806 // 2) Based on return addresses: Used for turbofanned code. Contains one entry
4807 // per call-site that could throw an exception. Layout looks as follows:
4808 // [ return-address-offset , handler-offset ]
4809 class HandlerTable : public FixedArray {
4810 public:
4811 // Conservative prediction whether a given handler will locally catch an
4812 // exception or cause a re-throw to outside the code boundary. Since this is
4813 // undecidable it is merely an approximation (e.g. useful for debugger).
4814 enum CatchPrediction { UNCAUGHT, CAUGHT };
4815
4816 // Getters for handler table based on ranges.
4817 inline int GetRangeStart(int index) const;
4818 inline int GetRangeEnd(int index) const;
4819 inline int GetRangeHandler(int index) const;
4820 inline int GetRangeData(int index) const;
4821
4822 // Setters for handler table based on ranges.
4823 inline void SetRangeStart(int index, int value);
4824 inline void SetRangeEnd(int index, int value);
4825 inline void SetRangeHandler(int index, int offset, CatchPrediction pred);
4826 inline void SetRangeData(int index, int value);
4827
4828 // Setters for handler table based on return addresses.
4829 inline void SetReturnOffset(int index, int value);
4830 inline void SetReturnHandler(int index, int offset, CatchPrediction pred);
4831
4832 // Lookup handler in a table based on ranges.
4833 int LookupRange(int pc_offset, int* data, CatchPrediction* prediction);
4834
4835 // Lookup handler in a table based on return addresses.
4836 int LookupReturn(int pc_offset, CatchPrediction* prediction);
4837
4838 // Returns the conservative catch predication.
4839 inline CatchPrediction GetRangePrediction(int index) const;
4840
4841 // Returns the number of entries in the table.
4842 inline int NumberOfRangeEntries() const;
4843
4844 // Returns the required length of the underlying fixed array.
LengthForRange(int entries)4845 static int LengthForRange(int entries) { return entries * kRangeEntrySize; }
LengthForReturn(int entries)4846 static int LengthForReturn(int entries) { return entries * kReturnEntrySize; }
4847
4848 DECLARE_CAST(HandlerTable)
4849
4850 #ifdef ENABLE_DISASSEMBLER
4851 void HandlerTableRangePrint(std::ostream& os); // NOLINT
4852 void HandlerTableReturnPrint(std::ostream& os); // NOLINT
4853 #endif
4854
4855 private:
4856 // Layout description for handler table based on ranges.
4857 static const int kRangeStartIndex = 0;
4858 static const int kRangeEndIndex = 1;
4859 static const int kRangeHandlerIndex = 2;
4860 static const int kRangeDataIndex = 3;
4861 static const int kRangeEntrySize = 4;
4862
4863 // Layout description for handler table based on return addresses.
4864 static const int kReturnOffsetIndex = 0;
4865 static const int kReturnHandlerIndex = 1;
4866 static const int kReturnEntrySize = 2;
4867
4868 // Encoding of the {handler} field.
4869 class HandlerPredictionField : public BitField<CatchPrediction, 0, 1> {};
4870 class HandlerOffsetField : public BitField<int, 1, 30> {};
4871 };
4872
4873
4874 // Code describes objects with on-the-fly generated machine code.
4875 class Code: public HeapObject {
4876 public:
4877 // Opaque data type for encapsulating code flags like kind, inline
4878 // cache state, and arguments count.
4879 typedef uint32_t Flags;
4880
4881 #define NON_IC_KIND_LIST(V) \
4882 V(FUNCTION) \
4883 V(OPTIMIZED_FUNCTION) \
4884 V(BYTECODE_HANDLER) \
4885 V(STUB) \
4886 V(HANDLER) \
4887 V(BUILTIN) \
4888 V(REGEXP) \
4889 V(WASM_FUNCTION) \
4890 V(WASM_TO_JS_FUNCTION) \
4891 V(JS_TO_WASM_FUNCTION)
4892
4893 #define IC_KIND_LIST(V) \
4894 V(LOAD_IC) \
4895 V(LOAD_GLOBAL_IC) \
4896 V(KEYED_LOAD_IC) \
4897 V(CALL_IC) \
4898 V(STORE_IC) \
4899 V(KEYED_STORE_IC) \
4900 V(BINARY_OP_IC) \
4901 V(COMPARE_IC) \
4902 V(TO_BOOLEAN_IC)
4903
4904 #define CODE_KIND_LIST(V) \
4905 NON_IC_KIND_LIST(V) \
4906 IC_KIND_LIST(V)
4907
4908 enum Kind {
4909 #define DEFINE_CODE_KIND_ENUM(name) name,
4910 CODE_KIND_LIST(DEFINE_CODE_KIND_ENUM)
4911 #undef DEFINE_CODE_KIND_ENUM
4912 NUMBER_OF_KINDS
4913 };
4914
4915 static const char* Kind2String(Kind kind);
4916
4917 static const int kPrologueOffsetNotSet = -1;
4918
4919 #ifdef ENABLE_DISASSEMBLER
4920 // Printing
4921 static const char* ICState2String(InlineCacheState state);
4922 static void PrintExtraICState(std::ostream& os, // NOLINT
4923 Kind kind, ExtraICState extra);
4924 void Disassemble(const char* name, std::ostream& os); // NOLINT
4925 #endif // ENABLE_DISASSEMBLER
4926
4927 // [instruction_size]: Size of the native instructions
4928 inline int instruction_size() const;
4929 inline void set_instruction_size(int value);
4930
4931 // [relocation_info]: Code relocation information
4932 DECL_ACCESSORS(relocation_info, ByteArray)
4933 void InvalidateRelocation();
4934 void InvalidateEmbeddedObjects();
4935
4936 // [handler_table]: Fixed array containing offsets of exception handlers.
4937 DECL_ACCESSORS(handler_table, FixedArray)
4938
4939 // [deoptimization_data]: Array containing data for deopt.
4940 DECL_ACCESSORS(deoptimization_data, FixedArray)
4941
4942 // [raw_type_feedback_info]: This field stores various things, depending on
4943 // the kind of the code object.
4944 // FUNCTION => type feedback information.
4945 // STUB and ICs => major/minor key as Smi.
4946 DECL_ACCESSORS(raw_type_feedback_info, Object)
4947 inline Object* type_feedback_info();
4948 inline void set_type_feedback_info(
4949 Object* value, WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
4950 inline uint32_t stub_key();
4951 inline void set_stub_key(uint32_t key);
4952
4953 // [next_code_link]: Link for lists of optimized or deoptimized code.
4954 // Note that storage for this field is overlapped with typefeedback_info.
4955 DECL_ACCESSORS(next_code_link, Object)
4956
4957 // [gc_metadata]: Field used to hold GC related metadata. The contents of this
4958 // field does not have to be traced during garbage collection since
4959 // it is only used by the garbage collector itself.
4960 DECL_ACCESSORS(gc_metadata, Object)
4961
4962 // [ic_age]: Inline caching age: the value of the Heap::global_ic_age
4963 // at the moment when this object was created.
4964 inline void set_ic_age(int count);
4965 inline int ic_age() const;
4966
4967 // [prologue_offset]: Offset of the function prologue, used for aging
4968 // FUNCTIONs and OPTIMIZED_FUNCTIONs.
4969 inline int prologue_offset() const;
4970 inline void set_prologue_offset(int offset);
4971
4972 // [constant_pool offset]: Offset of the constant pool.
4973 // Valid for FLAG_enable_embedded_constant_pool only
4974 inline int constant_pool_offset() const;
4975 inline void set_constant_pool_offset(int offset);
4976
4977 // Unchecked accessors to be used during GC.
4978 inline ByteArray* unchecked_relocation_info();
4979
4980 inline int relocation_size();
4981
4982 // [flags]: Various code flags.
4983 inline Flags flags();
4984 inline void set_flags(Flags flags);
4985
4986 // [flags]: Access to specific code flags.
4987 inline Kind kind();
4988 inline ExtraICState extra_ic_state(); // Only valid for IC stubs.
4989
4990 // Testers for IC stub kinds.
4991 inline bool is_inline_cache_stub();
4992 inline bool is_debug_stub();
4993 inline bool is_handler();
4994 inline bool is_call_stub();
4995 inline bool is_binary_op_stub();
4996 inline bool is_compare_ic_stub();
4997 inline bool is_to_boolean_ic_stub();
4998 inline bool is_optimized_code();
4999 inline bool is_wasm_code();
5000
5001 inline bool IsCodeStubOrIC();
5002
5003 inline void set_raw_kind_specific_flags1(int value);
5004 inline void set_raw_kind_specific_flags2(int value);
5005
5006 // Testers for interpreter builtins.
5007 inline bool is_interpreter_trampoline_builtin();
5008
5009 // [is_crankshafted]: For kind STUB or ICs, tells whether or not a code
5010 // object was generated by either the hydrogen or the TurboFan optimizing
5011 // compiler (but it may not be an optimized function).
5012 inline bool is_crankshafted();
5013 inline bool is_hydrogen_stub(); // Crankshafted, but not a function.
5014 inline void set_is_crankshafted(bool value);
5015
5016 // [is_turbofanned]: For kind STUB or OPTIMIZED_FUNCTION, tells whether the
5017 // code object was generated by the TurboFan optimizing compiler.
5018 inline bool is_turbofanned();
5019 inline void set_is_turbofanned(bool value);
5020
5021 // [can_have_weak_objects]: For kind OPTIMIZED_FUNCTION, tells whether the
5022 // embedded objects in code should be treated weakly.
5023 inline bool can_have_weak_objects();
5024 inline void set_can_have_weak_objects(bool value);
5025
5026 // [has_deoptimization_support]: For FUNCTION kind, tells if it has
5027 // deoptimization support.
5028 inline bool has_deoptimization_support();
5029 inline void set_has_deoptimization_support(bool value);
5030
5031 // [has_debug_break_slots]: For FUNCTION kind, tells if it has
5032 // been compiled with debug break slots.
5033 inline bool has_debug_break_slots();
5034 inline void set_has_debug_break_slots(bool value);
5035
5036 // [has_reloc_info_for_serialization]: For FUNCTION kind, tells if its
5037 // reloc info includes runtime and external references to support
5038 // serialization/deserialization.
5039 inline bool has_reloc_info_for_serialization();
5040 inline void set_has_reloc_info_for_serialization(bool value);
5041
5042 // [allow_osr_at_loop_nesting_level]: For FUNCTION kind, tells for
5043 // how long the function has been marked for OSR and therefore which
5044 // level of loop nesting we are willing to do on-stack replacement
5045 // for.
5046 inline void set_allow_osr_at_loop_nesting_level(int level);
5047 inline int allow_osr_at_loop_nesting_level();
5048
5049 // [profiler_ticks]: For FUNCTION kind, tells for how many profiler ticks
5050 // the code object was seen on the stack with no IC patching going on.
5051 inline int profiler_ticks();
5052 inline void set_profiler_ticks(int ticks);
5053
5054 // [builtin_index]: For BUILTIN kind, tells which builtin index it has.
5055 // For builtins, tells which builtin index it has.
5056 // Note that builtins can have a code kind other than BUILTIN, which means
5057 // that for arbitrary code objects, this index value may be random garbage.
5058 // To verify in that case, compare the code object to the indexed builtin.
5059 inline int builtin_index();
5060 inline void set_builtin_index(int id);
5061
5062 // [stack_slots]: For kind OPTIMIZED_FUNCTION, the number of stack slots
5063 // reserved in the code prologue.
5064 inline unsigned stack_slots();
5065 inline void set_stack_slots(unsigned slots);
5066
5067 // [safepoint_table_start]: For kind OPTIMIZED_FUNCTION, the offset in
5068 // the instruction stream where the safepoint table starts.
5069 inline unsigned safepoint_table_offset();
5070 inline void set_safepoint_table_offset(unsigned offset);
5071
5072 // [back_edge_table_start]: For kind FUNCTION, the offset in the
5073 // instruction stream where the back edge table starts.
5074 inline unsigned back_edge_table_offset();
5075 inline void set_back_edge_table_offset(unsigned offset);
5076
5077 inline bool back_edges_patched_for_osr();
5078
5079 // [to_boolean_foo]: For kind TO_BOOLEAN_IC tells what state the stub is in.
5080 inline uint16_t to_boolean_state();
5081
5082 // [marked_for_deoptimization]: For kind OPTIMIZED_FUNCTION tells whether
5083 // the code is going to be deoptimized because of dead embedded maps.
5084 inline bool marked_for_deoptimization();
5085 inline void set_marked_for_deoptimization(bool flag);
5086
5087 // [constant_pool]: The constant pool for this function.
5088 inline Address constant_pool();
5089
5090 // Get the safepoint entry for the given pc.
5091 SafepointEntry GetSafepointEntry(Address pc);
5092
5093 // Find an object in a stub with a specified map
5094 Object* FindNthObject(int n, Map* match_map);
5095
5096 // Find the first allocation site in an IC stub.
5097 AllocationSite* FindFirstAllocationSite();
5098
5099 // Find the first map in an IC stub.
5100 Map* FindFirstMap();
5101
5102 class FindAndReplacePattern;
5103 // For each (map-to-find, object-to-replace) pair in the pattern, this
5104 // function replaces the corresponding placeholder in the code with the
5105 // object-to-replace. The function assumes that pairs in the pattern come in
5106 // the same order as the placeholders in the code.
5107 // If the placeholder is a weak cell, then the value of weak cell is matched
5108 // against the map-to-find.
5109 void FindAndReplace(const FindAndReplacePattern& pattern);
5110
5111 // The entire code object including its header is copied verbatim to the
5112 // snapshot so that it can be written in one, fast, memcpy during
5113 // deserialization. The deserializer will overwrite some pointers, rather
5114 // like a runtime linker, but the random allocation addresses used in the
5115 // mksnapshot process would still be present in the unlinked snapshot data,
5116 // which would make snapshot production non-reproducible. This method wipes
5117 // out the to-be-overwritten header data for reproducible snapshots.
5118 inline void WipeOutHeader();
5119
5120 // Flags operations.
5121 static inline Flags ComputeFlags(
5122 Kind kind, ExtraICState extra_ic_state = kNoExtraICState,
5123 CacheHolderFlag holder = kCacheOnReceiver);
5124
5125 static inline Flags ComputeHandlerFlags(
5126 Kind handler_kind, CacheHolderFlag holder = kCacheOnReceiver);
5127
5128 static inline CacheHolderFlag ExtractCacheHolderFromFlags(Flags flags);
5129 static inline Kind ExtractKindFromFlags(Flags flags);
5130 static inline ExtraICState ExtractExtraICStateFromFlags(Flags flags);
5131
5132 static inline Flags RemoveHolderFromFlags(Flags flags);
5133
5134 // Convert a target address into a code object.
5135 static inline Code* GetCodeFromTargetAddress(Address address);
5136
5137 // Convert an entry address into an object.
5138 static inline Object* GetObjectFromEntryAddress(Address location_of_address);
5139
5140 // Returns the address of the first instruction.
5141 inline byte* instruction_start();
5142
5143 // Returns the address right after the last instruction.
5144 inline byte* instruction_end();
5145
5146 // Returns the size of the instructions, padding, relocation and unwinding
5147 // information.
5148 inline int body_size();
5149
5150 // Returns the size of code and its metadata. This includes the size of code
5151 // relocation information, deoptimization data and handler table.
5152 inline int SizeIncludingMetadata();
5153
5154 // Returns the address of the first relocation info (read backwards!).
5155 inline byte* relocation_start();
5156
5157 // [has_unwinding_info]: Whether this code object has unwinding information.
5158 // If it doesn't, unwinding_information_start() will point to invalid data.
5159 //
5160 // The body of all code objects has the following layout.
5161 //
5162 // +--------------------------+ <-- instruction_start()
5163 // | instructions |
5164 // | ... |
5165 // +--------------------------+
5166 // | relocation info |
5167 // | ... |
5168 // +--------------------------+ <-- instruction_end()
5169 //
5170 // If has_unwinding_info() is false, instruction_end() points to the first
5171 // memory location after the end of the code object. Otherwise, the body
5172 // continues as follows:
5173 //
5174 // +--------------------------+
5175 // | padding to the next |
5176 // | 8-byte aligned address |
5177 // +--------------------------+ <-- instruction_end()
5178 // | [unwinding_info_size] |
5179 // | as uint64_t |
5180 // +--------------------------+ <-- unwinding_info_start()
5181 // | unwinding info |
5182 // | ... |
5183 // +--------------------------+ <-- unwinding_info_end()
5184 //
5185 // and unwinding_info_end() points to the first memory location after the end
5186 // of the code object.
5187 //
5188 DECL_BOOLEAN_ACCESSORS(has_unwinding_info)
5189
5190 // [unwinding_info_size]: Size of the unwinding information.
5191 inline int unwinding_info_size() const;
5192 inline void set_unwinding_info_size(int value);
5193
5194 // Returns the address of the unwinding information, if any.
5195 inline byte* unwinding_info_start();
5196
5197 // Returns the address right after the end of the unwinding information.
5198 inline byte* unwinding_info_end();
5199
5200 // Code entry point.
5201 inline byte* entry();
5202
5203 // Returns true if pc is inside this object's instructions.
5204 inline bool contains(byte* pc);
5205
5206 // Relocate the code by delta bytes. Called to signal that this code
5207 // object has been moved by delta bytes.
5208 void Relocate(intptr_t delta);
5209
5210 // Migrate code described by desc.
5211 void CopyFrom(const CodeDesc& desc);
5212
5213 // Returns the object size for a given body (used for allocation).
SizeFor(int body_size)5214 static int SizeFor(int body_size) {
5215 DCHECK_SIZE_TAG_ALIGNED(body_size);
5216 return RoundUp(kHeaderSize + body_size, kCodeAlignment);
5217 }
5218
5219 // Calculate the size of the code object to report for log events. This takes
5220 // the layout of the code object into account.
5221 inline int ExecutableSize();
5222
5223 // Locating source position.
5224 int SourcePosition(int code_offset);
5225 int SourceStatementPosition(int code_offset);
5226
5227 DECLARE_CAST(Code)
5228
5229 // Dispatched behavior.
5230 inline int CodeSize();
5231
5232 DECLARE_PRINTER(Code)
5233 DECLARE_VERIFIER(Code)
5234
5235 void ClearInlineCaches();
5236
5237 BailoutId TranslatePcOffsetToAstId(uint32_t pc_offset);
5238 uint32_t TranslateAstIdToPcOffset(BailoutId ast_id);
5239
5240 #define DECLARE_CODE_AGE_ENUM(X) k##X##CodeAge,
5241 enum Age {
5242 kToBeExecutedOnceCodeAge = -3,
5243 kNotExecutedCodeAge = -2,
5244 kExecutedOnceCodeAge = -1,
5245 kNoAgeCodeAge = 0,
5246 CODE_AGE_LIST(DECLARE_CODE_AGE_ENUM)
5247 kAfterLastCodeAge,
5248 kFirstCodeAge = kToBeExecutedOnceCodeAge,
5249 kLastCodeAge = kAfterLastCodeAge - 1,
5250 kCodeAgeCount = kAfterLastCodeAge - kFirstCodeAge - 1,
5251 kIsOldCodeAge = kSexagenarianCodeAge,
5252 kPreAgedCodeAge = kIsOldCodeAge - 1
5253 };
5254 #undef DECLARE_CODE_AGE_ENUM
5255
5256 // Code aging. Indicates how many full GCs this code has survived without
5257 // being entered through the prologue. Used to determine when it is
5258 // relatively safe to flush this code object and replace it with the lazy
5259 // compilation stub.
5260 static void MakeCodeAgeSequenceYoung(byte* sequence, Isolate* isolate);
5261 static void MarkCodeAsExecuted(byte* sequence, Isolate* isolate);
5262 void MakeYoung(Isolate* isolate);
5263 void PreAge(Isolate* isolate);
5264 void MarkToBeExecutedOnce(Isolate* isolate);
5265 void MakeOlder(MarkingParity);
5266 static bool IsYoungSequence(Isolate* isolate, byte* sequence);
5267 bool IsOld();
5268 Age GetAge();
GetPreAgedCodeAgeStub(Isolate * isolate)5269 static inline Code* GetPreAgedCodeAgeStub(Isolate* isolate) {
5270 return GetCodeAgeStub(isolate, kNotExecutedCodeAge, NO_MARKING_PARITY);
5271 }
5272
5273 void PrintDeoptLocation(FILE* out, Address pc);
5274 bool CanDeoptAt(Address pc);
5275
5276 #ifdef VERIFY_HEAP
5277 void VerifyEmbeddedObjectsDependency();
5278 #endif
5279
5280 #ifdef DEBUG
5281 enum VerifyMode { kNoContextSpecificPointers, kNoContextRetainingPointers };
5282 void VerifyEmbeddedObjects(VerifyMode mode = kNoContextRetainingPointers);
5283 static void VerifyRecompiledCode(Code* old_code, Code* new_code);
5284 #endif // DEBUG
5285
5286 inline bool CanContainWeakObjects();
5287
5288 inline bool IsWeakObject(Object* object);
5289
5290 static inline bool IsWeakObjectInOptimizedCode(Object* object);
5291
5292 static Handle<WeakCell> WeakCellFor(Handle<Code> code);
5293 WeakCell* CachedWeakCell();
5294
5295 // Max loop nesting marker used to postpose OSR. We don't take loop
5296 // nesting that is deeper than 5 levels into account.
5297 static const int kMaxLoopNestingMarker = 6;
5298
5299 static const int kConstantPoolSize =
5300 FLAG_enable_embedded_constant_pool ? kIntSize : 0;
5301
5302 // Layout description.
5303 static const int kRelocationInfoOffset = HeapObject::kHeaderSize;
5304 static const int kHandlerTableOffset = kRelocationInfoOffset + kPointerSize;
5305 static const int kDeoptimizationDataOffset =
5306 kHandlerTableOffset + kPointerSize;
5307 // For FUNCTION kind, we store the type feedback info here.
5308 static const int kTypeFeedbackInfoOffset =
5309 kDeoptimizationDataOffset + kPointerSize;
5310 static const int kNextCodeLinkOffset = kTypeFeedbackInfoOffset + kPointerSize;
5311 static const int kGCMetadataOffset = kNextCodeLinkOffset + kPointerSize;
5312 static const int kInstructionSizeOffset = kGCMetadataOffset + kPointerSize;
5313 static const int kICAgeOffset = kInstructionSizeOffset + kIntSize;
5314 static const int kFlagsOffset = kICAgeOffset + kIntSize;
5315 static const int kKindSpecificFlags1Offset = kFlagsOffset + kIntSize;
5316 static const int kKindSpecificFlags2Offset =
5317 kKindSpecificFlags1Offset + kIntSize;
5318 // Note: We might be able to squeeze this into the flags above.
5319 static const int kPrologueOffset = kKindSpecificFlags2Offset + kIntSize;
5320 static const int kConstantPoolOffset = kPrologueOffset + kIntSize;
5321 static const int kBuiltinIndexOffset =
5322 kConstantPoolOffset + kConstantPoolSize;
5323 static const int kHeaderPaddingStart = kBuiltinIndexOffset + kIntSize;
5324
5325 // Add padding to align the instruction start following right after
5326 // the Code object header.
5327 static const int kHeaderSize =
5328 (kHeaderPaddingStart + kCodeAlignmentMask) & ~kCodeAlignmentMask;
5329
5330 inline int GetUnwindingInfoSizeOffset() const;
5331
5332 class BodyDescriptor;
5333
5334 // Byte offsets within kKindSpecificFlags1Offset.
5335 static const int kFullCodeFlags = kKindSpecificFlags1Offset;
5336 class FullCodeFlagsHasDeoptimizationSupportField:
5337 public BitField<bool, 0, 1> {}; // NOLINT
5338 class FullCodeFlagsHasDebugBreakSlotsField: public BitField<bool, 1, 1> {};
5339 class FullCodeFlagsHasRelocInfoForSerialization
5340 : public BitField<bool, 2, 1> {};
5341 // Bit 3 in this bitfield is unused.
5342 class ProfilerTicksField : public BitField<int, 4, 28> {};
5343
5344 // Flags layout. BitField<type, shift, size>.
5345 class ICStateField : public BitField<InlineCacheState, 0, 2> {};
5346 class HasUnwindingInfoField : public BitField<bool, ICStateField::kNext, 1> {
5347 };
5348 class CacheHolderField
5349 : public BitField<CacheHolderFlag, HasUnwindingInfoField::kNext, 2> {};
5350 class KindField : public BitField<Kind, CacheHolderField::kNext, 5> {};
5351 STATIC_ASSERT(NUMBER_OF_KINDS <= KindField::kMax);
5352 class ExtraICStateField : public BitField<ExtraICState, KindField::kNext,
5353 PlatformSmiTagging::kSmiValueSize -
5354 KindField::kNext + 1> {};
5355
5356 // KindSpecificFlags1 layout (STUB, BUILTIN and OPTIMIZED_FUNCTION)
5357 static const int kStackSlotsFirstBit = 0;
5358 static const int kStackSlotsBitCount = 24;
5359 static const int kMarkedForDeoptimizationBit =
5360 kStackSlotsFirstBit + kStackSlotsBitCount;
5361 static const int kIsTurbofannedBit = kMarkedForDeoptimizationBit + 1;
5362 static const int kCanHaveWeakObjects = kIsTurbofannedBit + 1;
5363
5364 STATIC_ASSERT(kStackSlotsFirstBit + kStackSlotsBitCount <= 32);
5365 STATIC_ASSERT(kCanHaveWeakObjects + 1 <= 32);
5366
5367 class StackSlotsField: public BitField<int,
5368 kStackSlotsFirstBit, kStackSlotsBitCount> {}; // NOLINT
5369 class MarkedForDeoptimizationField
5370 : public BitField<bool, kMarkedForDeoptimizationBit, 1> {}; // NOLINT
5371 class IsTurbofannedField : public BitField<bool, kIsTurbofannedBit, 1> {
5372 }; // NOLINT
5373 class CanHaveWeakObjectsField
5374 : public BitField<bool, kCanHaveWeakObjects, 1> {}; // NOLINT
5375
5376 // KindSpecificFlags2 layout (ALL)
5377 static const int kIsCrankshaftedBit = 0;
5378 class IsCrankshaftedField: public BitField<bool,
5379 kIsCrankshaftedBit, 1> {}; // NOLINT
5380
5381 // KindSpecificFlags2 layout (STUB and OPTIMIZED_FUNCTION)
5382 static const int kSafepointTableOffsetFirstBit = kIsCrankshaftedBit + 1;
5383 static const int kSafepointTableOffsetBitCount = 30;
5384
5385 STATIC_ASSERT(kSafepointTableOffsetFirstBit +
5386 kSafepointTableOffsetBitCount <= 32);
5387 STATIC_ASSERT(1 + kSafepointTableOffsetBitCount <= 32);
5388
5389 class SafepointTableOffsetField: public BitField<int,
5390 kSafepointTableOffsetFirstBit,
5391 kSafepointTableOffsetBitCount> {}; // NOLINT
5392
5393 // KindSpecificFlags2 layout (FUNCTION)
5394 class BackEdgeTableOffsetField: public BitField<int,
5395 kIsCrankshaftedBit + 1, 27> {}; // NOLINT
5396 class AllowOSRAtLoopNestingLevelField: public BitField<int,
5397 kIsCrankshaftedBit + 1 + 27, 4> {}; // NOLINT
5398 STATIC_ASSERT(AllowOSRAtLoopNestingLevelField::kMax >= kMaxLoopNestingMarker);
5399
5400 static const int kArgumentsBits = 16;
5401 static const int kMaxArguments = (1 << kArgumentsBits) - 1;
5402
5403 // This constant should be encodable in an ARM instruction.
5404 static const int kFlagsNotUsedInLookup = CacheHolderField::kMask;
5405
5406 private:
5407 friend class RelocIterator;
5408 friend class Deoptimizer; // For FindCodeAgeSequence.
5409
5410 // Code aging
5411 byte* FindCodeAgeSequence();
5412 static void GetCodeAgeAndParity(Code* code, Age* age,
5413 MarkingParity* parity);
5414 static void GetCodeAgeAndParity(Isolate* isolate, byte* sequence, Age* age,
5415 MarkingParity* parity);
5416 static Code* GetCodeAgeStub(Isolate* isolate, Age age, MarkingParity parity);
5417
5418 // Code aging -- platform-specific
5419 static void PatchPlatformCodeAge(Isolate* isolate,
5420 byte* sequence, Age age,
5421 MarkingParity parity);
5422
5423 DISALLOW_IMPLICIT_CONSTRUCTORS(Code);
5424 };
5425
5426 class AbstractCode : public HeapObject {
5427 public:
5428 // All code kinds and INTERPRETED_FUNCTION.
5429 enum Kind {
5430 #define DEFINE_CODE_KIND_ENUM(name) name,
5431 CODE_KIND_LIST(DEFINE_CODE_KIND_ENUM)
5432 #undef DEFINE_CODE_KIND_ENUM
5433 INTERPRETED_FUNCTION,
5434 NUMBER_OF_KINDS
5435 };
5436
5437 static const char* Kind2String(Kind kind);
5438
5439 int SourcePosition(int offset);
5440 int SourceStatementPosition(int offset);
5441
5442 // Returns the address of the first instruction.
5443 inline Address instruction_start();
5444
5445 // Returns the address right after the last instruction.
5446 inline Address instruction_end();
5447
5448 // Returns the size of the code instructions.
5449 inline int instruction_size();
5450
5451 // Returns the size of instructions and the metadata.
5452 inline int SizeIncludingMetadata();
5453
5454 // Returns true if pc is inside this object's instructions.
5455 inline bool contains(byte* pc);
5456
5457 // Returns the AbstractCode::Kind of the code.
5458 inline Kind kind();
5459
5460 // Calculate the size of the code object to report for log events. This takes
5461 // the layout of the code object into account.
5462 inline int ExecutableSize();
5463
5464 DECLARE_CAST(AbstractCode)
5465 inline Code* GetCode();
5466 inline BytecodeArray* GetBytecodeArray();
5467 };
5468
5469 // Dependent code is a singly linked list of fixed arrays. Each array contains
5470 // code objects in weak cells for one dependent group. The suffix of the array
5471 // can be filled with the undefined value if the number of codes is less than
5472 // the length of the array.
5473 //
5474 // +------+-----------------+--------+--------+-----+--------+-----------+-----+
5475 // | next | count & group 1 | code 1 | code 2 | ... | code n | undefined | ... |
5476 // +------+-----------------+--------+--------+-----+--------+-----------+-----+
5477 // |
5478 // V
5479 // +------+-----------------+--------+--------+-----+--------+-----------+-----+
5480 // | next | count & group 2 | code 1 | code 2 | ... | code m | undefined | ... |
5481 // +------+-----------------+--------+--------+-----+--------+-----------+-----+
5482 // |
5483 // V
5484 // empty_fixed_array()
5485 //
5486 // The list of fixed arrays is ordered by dependency groups.
5487
5488 class DependentCode: public FixedArray {
5489 public:
5490 enum DependencyGroup {
5491 // Group of code that weakly embed this map and depend on being
5492 // deoptimized when the map is garbage collected.
5493 kWeakCodeGroup,
5494 // Group of code that embed a transition to this map, and depend on being
5495 // deoptimized when the transition is replaced by a new version.
5496 kTransitionGroup,
5497 // Group of code that omit run-time prototype checks for prototypes
5498 // described by this map. The group is deoptimized whenever an object
5499 // described by this map changes shape (and transitions to a new map),
5500 // possibly invalidating the assumptions embedded in the code.
5501 kPrototypeCheckGroup,
5502 // Group of code that depends on global property values in property cells
5503 // not being changed.
5504 kPropertyCellChangedGroup,
5505 // Group of code that omit run-time type checks for the field(s) introduced
5506 // by this map.
5507 kFieldTypeGroup,
5508 // Group of code that omit run-time type checks for initial maps of
5509 // constructors.
5510 kInitialMapChangedGroup,
5511 // Group of code that depends on tenuring information in AllocationSites
5512 // not being changed.
5513 kAllocationSiteTenuringChangedGroup,
5514 // Group of code that depends on element transition information in
5515 // AllocationSites not being changed.
5516 kAllocationSiteTransitionChangedGroup
5517 };
5518
5519 static const int kGroupCount = kAllocationSiteTransitionChangedGroup + 1;
5520
5521 bool Contains(DependencyGroup group, WeakCell* code_cell);
5522 bool IsEmpty(DependencyGroup group);
5523
5524 static Handle<DependentCode> InsertCompilationDependencies(
5525 Handle<DependentCode> entries, DependencyGroup group,
5526 Handle<Foreign> info);
5527
5528 static Handle<DependentCode> InsertWeakCode(Handle<DependentCode> entries,
5529 DependencyGroup group,
5530 Handle<WeakCell> code_cell);
5531
5532 void UpdateToFinishedCode(DependencyGroup group, Foreign* info,
5533 WeakCell* code_cell);
5534
5535 void RemoveCompilationDependencies(DependentCode::DependencyGroup group,
5536 Foreign* info);
5537
5538 void DeoptimizeDependentCodeGroup(Isolate* isolate,
5539 DependentCode::DependencyGroup group);
5540
5541 bool MarkCodeForDeoptimization(Isolate* isolate,
5542 DependentCode::DependencyGroup group);
5543
5544 // The following low-level accessors should only be used by this class
5545 // and the mark compact collector.
5546 inline DependentCode* next_link();
5547 inline void set_next_link(DependentCode* next);
5548 inline int count();
5549 inline void set_count(int value);
5550 inline DependencyGroup group();
5551 inline void set_group(DependencyGroup group);
5552 inline Object* object_at(int i);
5553 inline void set_object_at(int i, Object* object);
5554 inline void clear_at(int i);
5555 inline void copy(int from, int to);
5556 DECLARE_CAST(DependentCode)
5557
5558 static const char* DependencyGroupName(DependencyGroup group);
5559 static void SetMarkedForDeoptimization(Code* code, DependencyGroup group);
5560
5561 private:
5562 static Handle<DependentCode> Insert(Handle<DependentCode> entries,
5563 DependencyGroup group,
5564 Handle<Object> object);
5565 static Handle<DependentCode> New(DependencyGroup group, Handle<Object> object,
5566 Handle<DependentCode> next);
5567 static Handle<DependentCode> EnsureSpace(Handle<DependentCode> entries);
5568 // Compact by removing cleared weak cells and return true if there was
5569 // any cleared weak cell.
5570 bool Compact();
Grow(int number_of_entries)5571 static int Grow(int number_of_entries) {
5572 if (number_of_entries < 5) return number_of_entries + 1;
5573 return number_of_entries * 5 / 4;
5574 }
5575 inline int flags();
5576 inline void set_flags(int flags);
5577 class GroupField : public BitField<int, 0, 3> {};
5578 class CountField : public BitField<int, 3, 27> {};
5579 STATIC_ASSERT(kGroupCount <= GroupField::kMax + 1);
5580 static const int kNextLinkIndex = 0;
5581 static const int kFlagsIndex = 1;
5582 static const int kCodesStartIndex = 2;
5583 };
5584
5585
5586 class PrototypeInfo;
5587
5588
5589 // All heap objects have a Map that describes their structure.
5590 // A Map contains information about:
5591 // - Size information about the object
5592 // - How to iterate over an object (for garbage collection)
5593 class Map: public HeapObject {
5594 public:
5595 // Instance size.
5596 // Size in bytes or kVariableSizeSentinel if instances do not have
5597 // a fixed size.
5598 inline int instance_size();
5599 inline void set_instance_size(int value);
5600
5601 // Only to clear an unused byte, remove once byte is used.
5602 inline void clear_unused();
5603
5604 // [inobject_properties_or_constructor_function_index]: Provides access
5605 // to the inobject properties in case of JSObject maps, or the constructor
5606 // function index in case of primitive maps.
5607 inline int inobject_properties_or_constructor_function_index();
5608 inline void set_inobject_properties_or_constructor_function_index(int value);
5609 // Count of properties allocated in the object (JSObject only).
5610 inline int GetInObjectProperties();
5611 inline void SetInObjectProperties(int value);
5612 // Index of the constructor function in the native context (primitives only),
5613 // or the special sentinel value to indicate that there is no object wrapper
5614 // for the primitive (i.e. in case of null or undefined).
5615 static const int kNoConstructorFunctionIndex = 0;
5616 inline int GetConstructorFunctionIndex();
5617 inline void SetConstructorFunctionIndex(int value);
5618 static MaybeHandle<JSFunction> GetConstructorFunction(
5619 Handle<Map> map, Handle<Context> native_context);
5620
5621 // Retrieve interceptors.
5622 inline InterceptorInfo* GetNamedInterceptor();
5623 inline InterceptorInfo* GetIndexedInterceptor();
5624
5625 // Instance type.
5626 inline InstanceType instance_type();
5627 inline void set_instance_type(InstanceType value);
5628
5629 // Tells how many unused property fields are available in the
5630 // instance (only used for JSObject in fast mode).
5631 inline int unused_property_fields();
5632 inline void set_unused_property_fields(int value);
5633
5634 // Bit field.
5635 inline byte bit_field() const;
5636 inline void set_bit_field(byte value);
5637
5638 // Bit field 2.
5639 inline byte bit_field2() const;
5640 inline void set_bit_field2(byte value);
5641
5642 // Bit field 3.
5643 inline uint32_t bit_field3() const;
5644 inline void set_bit_field3(uint32_t bits);
5645
5646 class EnumLengthBits: public BitField<int,
5647 0, kDescriptorIndexBitCount> {}; // NOLINT
5648 class NumberOfOwnDescriptorsBits: public BitField<int,
5649 kDescriptorIndexBitCount, kDescriptorIndexBitCount> {}; // NOLINT
5650 STATIC_ASSERT(kDescriptorIndexBitCount + kDescriptorIndexBitCount == 20);
5651 class DictionaryMap : public BitField<bool, 20, 1> {};
5652 class OwnsDescriptors : public BitField<bool, 21, 1> {};
5653 class HasHiddenPrototype : public BitField<bool, 22, 1> {};
5654 class Deprecated : public BitField<bool, 23, 1> {};
5655 class IsUnstable : public BitField<bool, 24, 1> {};
5656 class IsMigrationTarget : public BitField<bool, 25, 1> {};
5657 // Bit 26 is free.
5658 class NewTargetIsBase : public BitField<bool, 27, 1> {};
5659 // Bit 28 is free.
5660
5661 // Keep this bit field at the very end for better code in
5662 // Builtins::kJSConstructStubGeneric stub.
5663 // This counter is used for in-object slack tracking.
5664 // The in-object slack tracking is considered enabled when the counter is
5665 // non zero. The counter only has a valid count for initial maps. For
5666 // transitioned maps only kNoSlackTracking has a meaning, namely that inobject
5667 // slack tracking already finished for the transition tree. Any other value
5668 // indicates that either inobject slack tracking is still in progress, or that
5669 // the map isn't part of the transition tree anymore.
5670 class ConstructionCounter : public BitField<int, 29, 3> {};
5671 static const int kSlackTrackingCounterStart = 7;
5672 static const int kSlackTrackingCounterEnd = 1;
5673 static const int kNoSlackTracking = 0;
5674 STATIC_ASSERT(kSlackTrackingCounterStart <= ConstructionCounter::kMax);
5675
5676
5677 // Inobject slack tracking is the way to reclaim unused inobject space.
5678 //
5679 // The instance size is initially determined by adding some slack to
5680 // expected_nof_properties (to allow for a few extra properties added
5681 // after the constructor). There is no guarantee that the extra space
5682 // will not be wasted.
5683 //
5684 // Here is the algorithm to reclaim the unused inobject space:
5685 // - Detect the first constructor call for this JSFunction.
5686 // When it happens enter the "in progress" state: initialize construction
5687 // counter in the initial_map.
5688 // - While the tracking is in progress initialize unused properties of a new
5689 // object with one_pointer_filler_map instead of undefined_value (the "used"
5690 // part is initialized with undefined_value as usual). This way they can
5691 // be resized quickly and safely.
5692 // - Once enough objects have been created compute the 'slack'
5693 // (traverse the map transition tree starting from the
5694 // initial_map and find the lowest value of unused_property_fields).
5695 // - Traverse the transition tree again and decrease the instance size
5696 // of every map. Existing objects will resize automatically (they are
5697 // filled with one_pointer_filler_map). All further allocations will
5698 // use the adjusted instance size.
5699 // - SharedFunctionInfo's expected_nof_properties left unmodified since
5700 // allocations made using different closures could actually create different
5701 // kind of objects (see prototype inheritance pattern).
5702 //
5703 // Important: inobject slack tracking is not attempted during the snapshot
5704 // creation.
5705
5706 static const int kGenerousAllocationCount =
5707 kSlackTrackingCounterStart - kSlackTrackingCounterEnd + 1;
5708
5709 // Starts the tracking by initializing object constructions countdown counter.
5710 void StartInobjectSlackTracking();
5711
5712 // True if the object constructions countdown counter is a range
5713 // [kSlackTrackingCounterEnd, kSlackTrackingCounterStart].
5714 inline bool IsInobjectSlackTrackingInProgress();
5715
5716 // Does the tracking step.
5717 inline void InobjectSlackTrackingStep();
5718
5719 // Completes inobject slack tracking for the transition tree starting at this
5720 // initial map.
5721 void CompleteInobjectSlackTracking();
5722
5723 // Tells whether the object in the prototype property will be used
5724 // for instances created from this function. If the prototype
5725 // property is set to a value that is not a JSObject, the prototype
5726 // property will not be used to create instances of the function.
5727 // See ECMA-262, 13.2.2.
5728 inline void set_non_instance_prototype(bool value);
5729 inline bool has_non_instance_prototype();
5730
5731 // Tells whether the instance has a [[Construct]] internal method.
5732 // This property is implemented according to ES6, section 7.2.4.
5733 inline void set_is_constructor(bool value);
5734 inline bool is_constructor() const;
5735
5736 // Tells whether the instance with this map has a hidden prototype.
5737 inline void set_has_hidden_prototype(bool value);
5738 inline bool has_hidden_prototype() const;
5739
5740 // Records and queries whether the instance has a named interceptor.
5741 inline void set_has_named_interceptor();
5742 inline bool has_named_interceptor();
5743
5744 // Records and queries whether the instance has an indexed interceptor.
5745 inline void set_has_indexed_interceptor();
5746 inline bool has_indexed_interceptor();
5747
5748 // Tells whether the instance is undetectable.
5749 // An undetectable object is a special class of JSObject: 'typeof' operator
5750 // returns undefined, ToBoolean returns false. Otherwise it behaves like
5751 // a normal JS object. It is useful for implementing undetectable
5752 // document.all in Firefox & Safari.
5753 // See https://bugzilla.mozilla.org/show_bug.cgi?id=248549.
5754 inline void set_is_undetectable();
5755 inline bool is_undetectable();
5756
5757 // Tells whether the instance has a [[Call]] internal method.
5758 // This property is implemented according to ES6, section 7.2.3.
5759 inline void set_is_callable();
5760 inline bool is_callable() const;
5761
5762 inline void set_new_target_is_base(bool value);
5763 inline bool new_target_is_base();
5764 inline void set_is_extensible(bool value);
5765 inline bool is_extensible();
5766 inline void set_is_prototype_map(bool value);
5767 inline bool is_prototype_map() const;
5768
5769 inline void set_elements_kind(ElementsKind elements_kind);
5770 inline ElementsKind elements_kind();
5771
5772 // Tells whether the instance has fast elements that are only Smis.
5773 inline bool has_fast_smi_elements();
5774
5775 // Tells whether the instance has fast elements.
5776 inline bool has_fast_object_elements();
5777 inline bool has_fast_smi_or_object_elements();
5778 inline bool has_fast_double_elements();
5779 inline bool has_fast_elements();
5780 inline bool has_sloppy_arguments_elements();
5781 inline bool has_fast_sloppy_arguments_elements();
5782 inline bool has_fast_string_wrapper_elements();
5783 inline bool has_fixed_typed_array_elements();
5784 inline bool has_dictionary_elements();
5785
5786 static bool IsValidElementsTransition(ElementsKind from_kind,
5787 ElementsKind to_kind);
5788
5789 // Returns true if the current map doesn't have DICTIONARY_ELEMENTS but if a
5790 // map with DICTIONARY_ELEMENTS was found in the prototype chain.
5791 bool DictionaryElementsInPrototypeChainOnly();
5792
5793 inline Map* ElementsTransitionMap();
5794
5795 inline FixedArrayBase* GetInitialElements();
5796
5797 // [raw_transitions]: Provides access to the transitions storage field.
5798 // Don't call set_raw_transitions() directly to overwrite transitions, use
5799 // the TransitionArray::ReplaceTransitions() wrapper instead!
5800 DECL_ACCESSORS(raw_transitions, Object)
5801 // [prototype_info]: Per-prototype metadata. Aliased with transitions
5802 // (which prototype maps don't have).
5803 DECL_ACCESSORS(prototype_info, Object)
5804 // PrototypeInfo is created lazily using this helper (which installs it on
5805 // the given prototype's map).
5806 static Handle<PrototypeInfo> GetOrCreatePrototypeInfo(
5807 Handle<JSObject> prototype, Isolate* isolate);
5808 static Handle<PrototypeInfo> GetOrCreatePrototypeInfo(
5809 Handle<Map> prototype_map, Isolate* isolate);
5810 inline bool should_be_fast_prototype_map() const;
5811 static void SetShouldBeFastPrototypeMap(Handle<Map> map, bool value,
5812 Isolate* isolate);
5813
5814 // [prototype chain validity cell]: Associated with a prototype object,
5815 // stored in that object's map's PrototypeInfo, indicates that prototype
5816 // chains through this object are currently valid. The cell will be
5817 // invalidated and replaced when the prototype chain changes.
5818 static Handle<Cell> GetOrCreatePrototypeChainValidityCell(Handle<Map> map,
5819 Isolate* isolate);
5820 static const int kPrototypeChainValid = 0;
5821 static const int kPrototypeChainInvalid = 1;
5822
5823 Map* FindRootMap();
5824 Map* FindFieldOwner(int descriptor);
5825
5826 inline int GetInObjectPropertyOffset(int index);
5827
5828 int NumberOfFields();
5829
5830 // TODO(ishell): candidate with JSObject::MigrateToMap().
5831 bool InstancesNeedRewriting(Map* target);
5832 bool InstancesNeedRewriting(Map* target, int target_number_of_fields,
5833 int target_inobject, int target_unused,
5834 int* old_number_of_fields);
5835 // TODO(ishell): moveit!
5836 static Handle<Map> GeneralizeAllFieldRepresentations(Handle<Map> map);
5837 MUST_USE_RESULT static Handle<FieldType> GeneralizeFieldType(
5838 Representation rep1, Handle<FieldType> type1, Representation rep2,
5839 Handle<FieldType> type2, Isolate* isolate);
5840 static void GeneralizeFieldType(Handle<Map> map, int modify_index,
5841 Representation new_representation,
5842 Handle<FieldType> new_field_type);
5843
5844 static inline Handle<Map> ReconfigureProperty(
5845 Handle<Map> map, int modify_index, PropertyKind new_kind,
5846 PropertyAttributes new_attributes, Representation new_representation,
5847 Handle<FieldType> new_field_type, StoreMode store_mode);
5848
5849 static inline Handle<Map> ReconfigureElementsKind(
5850 Handle<Map> map, ElementsKind new_elements_kind);
5851
5852 static Handle<Map> PrepareForDataProperty(Handle<Map> old_map,
5853 int descriptor_number,
5854 Handle<Object> value);
5855
5856 static Handle<Map> Normalize(Handle<Map> map, PropertyNormalizationMode mode,
5857 const char* reason);
5858
5859 // Tells whether the map is used for JSObjects in dictionary mode (ie
5860 // normalized objects, ie objects for which HasFastProperties returns false).
5861 // A map can never be used for both dictionary mode and fast mode JSObjects.
5862 // False by default and for HeapObjects that are not JSObjects.
5863 inline void set_dictionary_map(bool value);
5864 inline bool is_dictionary_map();
5865
5866 // Tells whether the instance needs security checks when accessing its
5867 // properties.
5868 inline void set_is_access_check_needed(bool access_check_needed);
5869 inline bool is_access_check_needed();
5870
5871 // Returns true if map has a non-empty stub code cache.
5872 inline bool has_code_cache();
5873
5874 // [prototype]: implicit prototype object.
5875 DECL_ACCESSORS(prototype, Object)
5876 // TODO(jkummerow): make set_prototype private.
5877 static void SetPrototype(
5878 Handle<Map> map, Handle<Object> prototype,
5879 PrototypeOptimizationMode proto_mode = FAST_PROTOTYPE);
5880
5881 // [constructor]: points back to the function responsible for this map.
5882 // The field overlaps with the back pointer. All maps in a transition tree
5883 // have the same constructor, so maps with back pointers can walk the
5884 // back pointer chain until they find the map holding their constructor.
5885 DECL_ACCESSORS(constructor_or_backpointer, Object)
5886 inline Object* GetConstructor() const;
5887 inline void SetConstructor(Object* constructor,
5888 WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
5889 // [back pointer]: points back to the parent map from which a transition
5890 // leads to this map. The field overlaps with the constructor (see above).
5891 inline Object* GetBackPointer();
5892 inline void SetBackPointer(Object* value,
5893 WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
5894
5895 // [instance descriptors]: describes the object.
5896 DECL_ACCESSORS(instance_descriptors, DescriptorArray)
5897
5898 // [layout descriptor]: describes the object layout.
5899 DECL_ACCESSORS(layout_descriptor, LayoutDescriptor)
5900 // |layout descriptor| accessor which can be used from GC.
5901 inline LayoutDescriptor* layout_descriptor_gc_safe();
5902 inline bool HasFastPointerLayout() const;
5903
5904 // |layout descriptor| accessor that is safe to call even when
5905 // FLAG_unbox_double_fields is disabled (in this case Map does not contain
5906 // |layout_descriptor| field at all).
5907 inline LayoutDescriptor* GetLayoutDescriptor();
5908
5909 inline void UpdateDescriptors(DescriptorArray* descriptors,
5910 LayoutDescriptor* layout_descriptor);
5911 inline void InitializeDescriptors(DescriptorArray* descriptors,
5912 LayoutDescriptor* layout_descriptor);
5913
5914 // [stub cache]: contains stubs compiled for this map.
5915 DECL_ACCESSORS(code_cache, FixedArray)
5916
5917 // [dependent code]: list of optimized codes that weakly embed this map.
5918 DECL_ACCESSORS(dependent_code, DependentCode)
5919
5920 // [weak cell cache]: cache that stores a weak cell pointing to this map.
5921 DECL_ACCESSORS(weak_cell_cache, Object)
5922
5923 inline PropertyDetails GetLastDescriptorDetails();
5924
5925 inline int LastAdded();
5926
5927 inline int NumberOfOwnDescriptors();
5928 inline void SetNumberOfOwnDescriptors(int number);
5929
5930 inline Cell* RetrieveDescriptorsPointer();
5931
5932 // Checks whether all properties are stored either in the map or on the object
5933 // (inobject, properties, or elements backing store), requiring no special
5934 // checks.
5935 bool OnlyHasSimpleProperties();
5936 inline int EnumLength();
5937 inline void SetEnumLength(int length);
5938
5939 inline bool owns_descriptors();
5940 inline void set_owns_descriptors(bool owns_descriptors);
5941 inline void mark_unstable();
5942 inline bool is_stable();
5943 inline void set_migration_target(bool value);
5944 inline bool is_migration_target();
5945 inline void set_construction_counter(int value);
5946 inline int construction_counter();
5947 inline void deprecate();
5948 inline bool is_deprecated();
5949 inline bool CanBeDeprecated();
5950 // Returns a non-deprecated version of the input. If the input was not
5951 // deprecated, it is directly returned. Otherwise, the non-deprecated version
5952 // is found by re-transitioning from the root of the transition tree using the
5953 // descriptor array of the map. Returns MaybeHandle<Map>() if no updated map
5954 // is found.
5955 static MaybeHandle<Map> TryUpdate(Handle<Map> map) WARN_UNUSED_RESULT;
5956
5957 // Returns a non-deprecated version of the input. This method may deprecate
5958 // existing maps along the way if encodings conflict. Not for use while
5959 // gathering type feedback. Use TryUpdate in those cases instead.
5960 static Handle<Map> Update(Handle<Map> map);
5961
5962 static inline Handle<Map> CopyInitialMap(Handle<Map> map);
5963 static Handle<Map> CopyInitialMap(Handle<Map> map, int instance_size,
5964 int in_object_properties,
5965 int unused_property_fields);
5966 static Handle<Map> CopyDropDescriptors(Handle<Map> map);
5967 static Handle<Map> CopyInsertDescriptor(Handle<Map> map,
5968 Descriptor* descriptor,
5969 TransitionFlag flag);
5970
5971 MUST_USE_RESULT static MaybeHandle<Map> CopyWithField(
5972 Handle<Map> map, Handle<Name> name, Handle<FieldType> type,
5973 PropertyAttributes attributes, Representation representation,
5974 TransitionFlag flag);
5975
5976 MUST_USE_RESULT static MaybeHandle<Map> CopyWithConstant(
5977 Handle<Map> map,
5978 Handle<Name> name,
5979 Handle<Object> constant,
5980 PropertyAttributes attributes,
5981 TransitionFlag flag);
5982
5983 // Returns a new map with all transitions dropped from the given map and
5984 // the ElementsKind set.
5985 static Handle<Map> TransitionElementsTo(Handle<Map> map,
5986 ElementsKind to_kind);
5987
5988 static Handle<Map> AsElementsKind(Handle<Map> map, ElementsKind kind);
5989
5990 static Handle<Map> CopyAsElementsKind(Handle<Map> map,
5991 ElementsKind kind,
5992 TransitionFlag flag);
5993
5994 static Handle<Map> AsLanguageMode(Handle<Map> initial_map,
5995 LanguageMode language_mode,
5996 FunctionKind kind);
5997
5998
5999 static Handle<Map> CopyForPreventExtensions(Handle<Map> map,
6000 PropertyAttributes attrs_to_add,
6001 Handle<Symbol> transition_marker,
6002 const char* reason);
6003
6004 static Handle<Map> FixProxy(Handle<Map> map, InstanceType type, int size);
6005
6006
6007 // Maximal number of fast properties. Used to restrict the number of map
6008 // transitions to avoid an explosion in the number of maps for objects used as
6009 // dictionaries.
6010 inline bool TooManyFastProperties(StoreFromKeyed store_mode);
6011 static Handle<Map> TransitionToDataProperty(Handle<Map> map,
6012 Handle<Name> name,
6013 Handle<Object> value,
6014 PropertyAttributes attributes,
6015 StoreFromKeyed store_mode);
6016 static Handle<Map> TransitionToAccessorProperty(
6017 Isolate* isolate, Handle<Map> map, Handle<Name> name, int descriptor,
6018 Handle<Object> getter, Handle<Object> setter,
6019 PropertyAttributes attributes);
6020 static Handle<Map> ReconfigureExistingProperty(Handle<Map> map,
6021 int descriptor,
6022 PropertyKind kind,
6023 PropertyAttributes attributes);
6024
6025 inline void AppendDescriptor(Descriptor* desc);
6026
6027 // Returns a copy of the map, prepared for inserting into the transition
6028 // tree (if the |map| owns descriptors then the new one will share
6029 // descriptors with |map|).
6030 static Handle<Map> CopyForTransition(Handle<Map> map, const char* reason);
6031
6032 // Returns a copy of the map, with all transitions dropped from the
6033 // instance descriptors.
6034 static Handle<Map> Copy(Handle<Map> map, const char* reason);
6035 static Handle<Map> Create(Isolate* isolate, int inobject_properties);
6036
6037 // Returns the next free property index (only valid for FAST MODE).
6038 int NextFreePropertyIndex();
6039
6040 // Returns the number of properties described in instance_descriptors
6041 // filtering out properties with the specified attributes.
6042 int NumberOfDescribedProperties(DescriptorFlag which = OWN_DESCRIPTORS,
6043 PropertyFilter filter = ALL_PROPERTIES);
6044
6045 DECLARE_CAST(Map)
6046
6047 // Code cache operations.
6048
6049 // Clears the code cache.
6050 inline void ClearCodeCache(Heap* heap);
6051
6052 // Update code cache.
6053 static void UpdateCodeCache(Handle<Map> map,
6054 Handle<Name> name,
6055 Handle<Code> code);
6056
6057 // Extend the descriptor array of the map with the list of descriptors.
6058 // In case of duplicates, the latest descriptor is used.
6059 static void AppendCallbackDescriptors(Handle<Map> map,
6060 Handle<Object> descriptors);
6061
6062 static inline int SlackForArraySize(int old_size, int size_limit);
6063
6064 static void EnsureDescriptorSlack(Handle<Map> map, int slack);
6065
6066 Code* LookupInCodeCache(Name* name, Code::Flags code);
6067
6068 // Computes a hash value for this map, to be used in HashTables and such.
6069 int Hash();
6070
6071 // Returns the transitioned map for this map with the most generic
6072 // elements_kind that's found in |candidates|, or |nullptr| if no match is
6073 // found at all.
6074 Map* FindElementsKindTransitionedMap(MapHandleList* candidates);
6075
6076 inline bool CanTransition();
6077
6078 inline bool IsBooleanMap();
6079 inline bool IsPrimitiveMap();
6080 inline bool IsJSReceiverMap();
6081 inline bool IsJSObjectMap();
6082 inline bool IsJSArrayMap();
6083 inline bool IsJSFunctionMap();
6084 inline bool IsStringMap();
6085 inline bool IsJSProxyMap();
6086 inline bool IsJSGlobalProxyMap();
6087 inline bool IsJSGlobalObjectMap();
6088 inline bool IsJSTypedArrayMap();
6089 inline bool IsJSDataViewMap();
6090
6091 inline bool CanOmitMapChecks();
6092
6093 static void AddDependentCode(Handle<Map> map,
6094 DependentCode::DependencyGroup group,
6095 Handle<Code> code);
6096
6097 bool IsMapInArrayPrototypeChain();
6098
6099 static Handle<WeakCell> WeakCellForMap(Handle<Map> map);
6100
6101 // Dispatched behavior.
6102 DECLARE_PRINTER(Map)
6103 DECLARE_VERIFIER(Map)
6104
6105 #ifdef VERIFY_HEAP
6106 void DictionaryMapVerify();
6107 void VerifyOmittedMapChecks();
6108 #endif
6109
6110 inline int visitor_id();
6111 inline void set_visitor_id(int visitor_id);
6112
6113 static Handle<Map> TransitionToPrototype(Handle<Map> map,
6114 Handle<Object> prototype,
6115 PrototypeOptimizationMode mode);
6116
6117 static const int kMaxPreAllocatedPropertyFields = 255;
6118
6119 // Layout description.
6120 static const int kInstanceSizesOffset = HeapObject::kHeaderSize;
6121 static const int kInstanceAttributesOffset = kInstanceSizesOffset + kIntSize;
6122 static const int kBitField3Offset = kInstanceAttributesOffset + kIntSize;
6123 static const int kPrototypeOffset = kBitField3Offset + kPointerSize;
6124 static const int kConstructorOrBackPointerOffset =
6125 kPrototypeOffset + kPointerSize;
6126 // When there is only one transition, it is stored directly in this field;
6127 // otherwise a transition array is used.
6128 // For prototype maps, this slot is used to store this map's PrototypeInfo
6129 // struct.
6130 static const int kTransitionsOrPrototypeInfoOffset =
6131 kConstructorOrBackPointerOffset + kPointerSize;
6132 static const int kDescriptorsOffset =
6133 kTransitionsOrPrototypeInfoOffset + kPointerSize;
6134 #if V8_DOUBLE_FIELDS_UNBOXING
6135 static const int kLayoutDecriptorOffset = kDescriptorsOffset + kPointerSize;
6136 static const int kCodeCacheOffset = kLayoutDecriptorOffset + kPointerSize;
6137 #else
6138 static const int kLayoutDecriptorOffset = 1; // Must not be ever accessed.
6139 static const int kCodeCacheOffset = kDescriptorsOffset + kPointerSize;
6140 #endif
6141 static const int kDependentCodeOffset = kCodeCacheOffset + kPointerSize;
6142 static const int kWeakCellCacheOffset = kDependentCodeOffset + kPointerSize;
6143 static const int kSize = kWeakCellCacheOffset + kPointerSize;
6144
6145 // Layout of pointer fields. Heap iteration code relies on them
6146 // being continuously allocated.
6147 static const int kPointerFieldsBeginOffset = Map::kPrototypeOffset;
6148 static const int kPointerFieldsEndOffset = kSize;
6149
6150 // Byte offsets within kInstanceSizesOffset.
6151 static const int kInstanceSizeOffset = kInstanceSizesOffset + 0;
6152 static const int kInObjectPropertiesOrConstructorFunctionIndexByte = 1;
6153 static const int kInObjectPropertiesOrConstructorFunctionIndexOffset =
6154 kInstanceSizesOffset + kInObjectPropertiesOrConstructorFunctionIndexByte;
6155 // Note there is one byte available for use here.
6156 static const int kUnusedByte = 2;
6157 static const int kUnusedOffset = kInstanceSizesOffset + kUnusedByte;
6158 static const int kVisitorIdByte = 3;
6159 static const int kVisitorIdOffset = kInstanceSizesOffset + kVisitorIdByte;
6160
6161 // Byte offsets within kInstanceAttributesOffset attributes.
6162 #if V8_TARGET_LITTLE_ENDIAN
6163 // Order instance type and bit field together such that they can be loaded
6164 // together as a 16-bit word with instance type in the lower 8 bits regardless
6165 // of endianess. Also provide endian-independent offset to that 16-bit word.
6166 static const int kInstanceTypeOffset = kInstanceAttributesOffset + 0;
6167 static const int kBitFieldOffset = kInstanceAttributesOffset + 1;
6168 #else
6169 static const int kBitFieldOffset = kInstanceAttributesOffset + 0;
6170 static const int kInstanceTypeOffset = kInstanceAttributesOffset + 1;
6171 #endif
6172 static const int kInstanceTypeAndBitFieldOffset =
6173 kInstanceAttributesOffset + 0;
6174 static const int kBitField2Offset = kInstanceAttributesOffset + 2;
6175 static const int kUnusedPropertyFieldsByte = 3;
6176 static const int kUnusedPropertyFieldsOffset = kInstanceAttributesOffset + 3;
6177
6178 STATIC_ASSERT(kInstanceTypeAndBitFieldOffset ==
6179 Internals::kMapInstanceTypeAndBitFieldOffset);
6180
6181 // Bit positions for bit field.
6182 static const int kHasNonInstancePrototype = 0;
6183 static const int kIsCallable = 1;
6184 static const int kHasNamedInterceptor = 2;
6185 static const int kHasIndexedInterceptor = 3;
6186 static const int kIsUndetectable = 4;
6187 static const int kIsAccessCheckNeeded = 5;
6188 static const int kIsConstructor = 6;
6189 // Bit 7 is free.
6190
6191 // Bit positions for bit field 2
6192 static const int kIsExtensible = 0;
6193 // Bit 1 is free.
6194 class IsPrototypeMapBits : public BitField<bool, 2, 1> {};
6195 class ElementsKindBits: public BitField<ElementsKind, 3, 5> {};
6196
6197 // Derived values from bit field 2
6198 static const int8_t kMaximumBitField2FastElementValue = static_cast<int8_t>(
6199 (FAST_ELEMENTS + 1) << Map::ElementsKindBits::kShift) - 1;
6200 static const int8_t kMaximumBitField2FastSmiElementValue =
6201 static_cast<int8_t>((FAST_SMI_ELEMENTS + 1) <<
6202 Map::ElementsKindBits::kShift) - 1;
6203 static const int8_t kMaximumBitField2FastHoleyElementValue =
6204 static_cast<int8_t>((FAST_HOLEY_ELEMENTS + 1) <<
6205 Map::ElementsKindBits::kShift) - 1;
6206 static const int8_t kMaximumBitField2FastHoleySmiElementValue =
6207 static_cast<int8_t>((FAST_HOLEY_SMI_ELEMENTS + 1) <<
6208 Map::ElementsKindBits::kShift) - 1;
6209
6210 typedef FixedBodyDescriptor<kPointerFieldsBeginOffset,
6211 kPointerFieldsEndOffset,
6212 kSize> BodyDescriptor;
6213
6214 // Compares this map to another to see if they describe equivalent objects.
6215 // If |mode| is set to CLEAR_INOBJECT_PROPERTIES, |other| is treated as if
6216 // it had exactly zero inobject properties.
6217 // The "shared" flags of both this map and |other| are ignored.
6218 bool EquivalentToForNormalization(Map* other, PropertyNormalizationMode mode);
6219
6220 // Returns true if given field is unboxed double.
6221 inline bool IsUnboxedDoubleField(FieldIndex index);
6222
6223 #if TRACE_MAPS
6224 static void TraceTransition(const char* what, Map* from, Map* to, Name* name);
6225 static void TraceAllTransitions(Map* map);
6226 #endif
6227
6228 static inline Handle<Map> AddMissingTransitionsForTesting(
6229 Handle<Map> split_map, Handle<DescriptorArray> descriptors,
6230 Handle<LayoutDescriptor> full_layout_descriptor);
6231
6232 private:
6233 // Returns the map that this (root) map transitions to if its elements_kind
6234 // is changed to |elements_kind|, or |nullptr| if no such map is cached yet.
6235 Map* LookupElementsTransitionMap(ElementsKind elements_kind);
6236
6237 // Tries to replay property transitions starting from this (root) map using
6238 // the descriptor array of the |map|. The |root_map| is expected to have
6239 // proper elements kind and therefore elements kinds transitions are not
6240 // taken by this function. Returns |nullptr| if matching transition map is
6241 // not found.
6242 Map* TryReplayPropertyTransitions(Map* map);
6243
6244 static void ConnectTransition(Handle<Map> parent, Handle<Map> child,
6245 Handle<Name> name, SimpleTransitionFlag flag);
6246
6247 bool EquivalentToForTransition(Map* other);
6248 static Handle<Map> RawCopy(Handle<Map> map, int instance_size);
6249 static Handle<Map> ShareDescriptor(Handle<Map> map,
6250 Handle<DescriptorArray> descriptors,
6251 Descriptor* descriptor);
6252 static Handle<Map> AddMissingTransitions(
6253 Handle<Map> map, Handle<DescriptorArray> descriptors,
6254 Handle<LayoutDescriptor> full_layout_descriptor);
6255 static void InstallDescriptors(
6256 Handle<Map> parent_map, Handle<Map> child_map, int new_descriptor,
6257 Handle<DescriptorArray> descriptors,
6258 Handle<LayoutDescriptor> full_layout_descriptor);
6259 static Handle<Map> CopyAddDescriptor(Handle<Map> map,
6260 Descriptor* descriptor,
6261 TransitionFlag flag);
6262 static Handle<Map> CopyReplaceDescriptors(
6263 Handle<Map> map, Handle<DescriptorArray> descriptors,
6264 Handle<LayoutDescriptor> layout_descriptor, TransitionFlag flag,
6265 MaybeHandle<Name> maybe_name, const char* reason,
6266 SimpleTransitionFlag simple_flag);
6267
6268 static Handle<Map> CopyReplaceDescriptor(Handle<Map> map,
6269 Handle<DescriptorArray> descriptors,
6270 Descriptor* descriptor,
6271 int index,
6272 TransitionFlag flag);
6273 static MUST_USE_RESULT MaybeHandle<Map> TryReconfigureExistingProperty(
6274 Handle<Map> map, int descriptor, PropertyKind kind,
6275 PropertyAttributes attributes, const char** reason);
6276
6277 static Handle<Map> CopyNormalized(Handle<Map> map,
6278 PropertyNormalizationMode mode);
6279
6280 static Handle<Map> Reconfigure(Handle<Map> map,
6281 ElementsKind new_elements_kind,
6282 int modify_index, PropertyKind new_kind,
6283 PropertyAttributes new_attributes,
6284 Representation new_representation,
6285 Handle<FieldType> new_field_type,
6286 StoreMode store_mode);
6287
6288 static Handle<Map> CopyGeneralizeAllRepresentations(
6289 Handle<Map> map, ElementsKind elements_kind, int modify_index,
6290 StoreMode store_mode, PropertyKind kind, PropertyAttributes attributes,
6291 const char* reason);
6292
6293 // Fires when the layout of an object with a leaf map changes.
6294 // This includes adding transitions to the leaf map or changing
6295 // the descriptor array.
6296 inline void NotifyLeafMapLayoutChange();
6297
6298 void DeprecateTransitionTree();
6299
6300 void ReplaceDescriptors(DescriptorArray* new_descriptors,
6301 LayoutDescriptor* new_layout_descriptor);
6302
6303
6304 Map* FindLastMatchMap(int verbatim, int length, DescriptorArray* descriptors);
6305
6306 // Update field type of the given descriptor to new representation and new
6307 // type. The type must be prepared for storing in descriptor array:
6308 // it must be either a simple type or a map wrapped in a weak cell.
6309 void UpdateFieldType(int descriptor_number, Handle<Name> name,
6310 Representation new_representation,
6311 Handle<Object> new_wrapped_type);
6312
6313 void PrintReconfiguration(FILE* file, int modify_index, PropertyKind kind,
6314 PropertyAttributes attributes);
6315 void PrintGeneralization(FILE* file, const char* reason, int modify_index,
6316 int split, int descriptors, bool constant_to_field,
6317 Representation old_representation,
6318 Representation new_representation,
6319 MaybeHandle<FieldType> old_field_type,
6320 MaybeHandle<Object> old_value,
6321 MaybeHandle<FieldType> new_field_type,
6322 MaybeHandle<Object> new_value);
6323
6324 static const int kFastPropertiesSoftLimit = 12;
6325 static const int kMaxFastProperties = 128;
6326
6327 DISALLOW_IMPLICIT_CONSTRUCTORS(Map);
6328 };
6329
6330
6331 // An abstract superclass, a marker class really, for simple structure classes.
6332 // It doesn't carry much functionality but allows struct classes to be
6333 // identified in the type system.
6334 class Struct: public HeapObject {
6335 public:
6336 inline void InitializeBody(int object_size);
6337 DECLARE_CAST(Struct)
6338 };
6339
6340
6341 // A simple one-element struct, useful where smis need to be boxed.
6342 class Box : public Struct {
6343 public:
6344 // [value]: the boxed contents.
6345 DECL_ACCESSORS(value, Object)
6346
6347 DECLARE_CAST(Box)
6348
6349 // Dispatched behavior.
6350 DECLARE_PRINTER(Box)
6351 DECLARE_VERIFIER(Box)
6352
6353 static const int kValueOffset = HeapObject::kHeaderSize;
6354 static const int kSize = kValueOffset + kPointerSize;
6355
6356 private:
6357 DISALLOW_IMPLICIT_CONSTRUCTORS(Box);
6358 };
6359
6360
6361 // Container for metadata stored on each prototype map.
6362 class PrototypeInfo : public Struct {
6363 public:
6364 static const int UNREGISTERED = -1;
6365
6366 // [prototype_users]: WeakFixedArray containing maps using this prototype,
6367 // or Smi(0) if uninitialized.
6368 DECL_ACCESSORS(prototype_users, Object)
6369
6370 // [object_create_map]: A field caching the map for Object.create(prototype).
6371 static inline void SetObjectCreateMap(Handle<PrototypeInfo> info,
6372 Handle<Map> map);
6373 inline Map* ObjectCreateMap();
6374 inline bool HasObjectCreateMap();
6375
6376 // [registry_slot]: Slot in prototype's user registry where this user
6377 // is stored. Returns UNREGISTERED if this prototype has not been registered.
6378 inline int registry_slot() const;
6379 inline void set_registry_slot(int slot);
6380 // [validity_cell]: Cell containing the validity bit for prototype chains
6381 // going through this object, or Smi(0) if uninitialized.
6382 // When a prototype object changes its map, then both its own validity cell
6383 // and those of all "downstream" prototypes are invalidated; handlers for a
6384 // given receiver embed the currently valid cell for that receiver's prototype
6385 // during their compilation and check it on execution.
6386 DECL_ACCESSORS(validity_cell, Object)
6387 // [bit_field]
6388 inline int bit_field() const;
6389 inline void set_bit_field(int bit_field);
6390
6391 DECL_BOOLEAN_ACCESSORS(should_be_fast_map)
6392
6393 DECLARE_CAST(PrototypeInfo)
6394
6395 // Dispatched behavior.
6396 DECLARE_PRINTER(PrototypeInfo)
6397 DECLARE_VERIFIER(PrototypeInfo)
6398
6399 static const int kPrototypeUsersOffset = HeapObject::kHeaderSize;
6400 static const int kRegistrySlotOffset = kPrototypeUsersOffset + kPointerSize;
6401 static const int kValidityCellOffset = kRegistrySlotOffset + kPointerSize;
6402 static const int kObjectCreateMap = kValidityCellOffset + kPointerSize;
6403 static const int kBitFieldOffset = kObjectCreateMap + kPointerSize;
6404 static const int kSize = kBitFieldOffset + kPointerSize;
6405
6406 // Bit field usage.
6407 static const int kShouldBeFastBit = 0;
6408
6409 private:
6410 DECL_ACCESSORS(object_create_map, Object)
6411
6412 DISALLOW_IMPLICIT_CONSTRUCTORS(PrototypeInfo);
6413 };
6414
6415
6416 // Pair used to store both a ScopeInfo and an extension object in the extension
6417 // slot of a block context. Needed in the rare case where a declaration block
6418 // scope (a "varblock" as used to desugar parameter destructuring) also contains
6419 // a sloppy direct eval. (In no other case both are needed at the same time.)
6420 class SloppyBlockWithEvalContextExtension : public Struct {
6421 public:
6422 // [scope_info]: Scope info.
6423 DECL_ACCESSORS(scope_info, ScopeInfo)
6424 // [extension]: Extension object.
6425 DECL_ACCESSORS(extension, JSObject)
6426
6427 DECLARE_CAST(SloppyBlockWithEvalContextExtension)
6428
6429 // Dispatched behavior.
6430 DECLARE_PRINTER(SloppyBlockWithEvalContextExtension)
6431 DECLARE_VERIFIER(SloppyBlockWithEvalContextExtension)
6432
6433 static const int kScopeInfoOffset = HeapObject::kHeaderSize;
6434 static const int kExtensionOffset = kScopeInfoOffset + kPointerSize;
6435 static const int kSize = kExtensionOffset + kPointerSize;
6436
6437 private:
6438 DISALLOW_IMPLICIT_CONSTRUCTORS(SloppyBlockWithEvalContextExtension);
6439 };
6440
6441
6442 // Script describes a script which has been added to the VM.
6443 class Script: public Struct {
6444 public:
6445 // Script types.
6446 enum Type {
6447 TYPE_NATIVE = 0,
6448 TYPE_EXTENSION = 1,
6449 TYPE_NORMAL = 2
6450 };
6451
6452 // Script compilation types.
6453 enum CompilationType {
6454 COMPILATION_TYPE_HOST = 0,
6455 COMPILATION_TYPE_EVAL = 1
6456 };
6457
6458 // Script compilation state.
6459 enum CompilationState {
6460 COMPILATION_STATE_INITIAL = 0,
6461 COMPILATION_STATE_COMPILED = 1
6462 };
6463
6464 // [source]: the script source.
6465 DECL_ACCESSORS(source, Object)
6466
6467 // [name]: the script name.
6468 DECL_ACCESSORS(name, Object)
6469
6470 // [id]: the script id.
6471 DECL_INT_ACCESSORS(id)
6472
6473 // [line_offset]: script line offset in resource from where it was extracted.
6474 DECL_INT_ACCESSORS(line_offset)
6475
6476 // [column_offset]: script column offset in resource from where it was
6477 // extracted.
6478 DECL_INT_ACCESSORS(column_offset)
6479
6480 // [context_data]: context data for the context this script was compiled in.
6481 DECL_ACCESSORS(context_data, Object)
6482
6483 // [wrapper]: the wrapper cache. This is either undefined or a WeakCell.
6484 DECL_ACCESSORS(wrapper, HeapObject)
6485
6486 // [type]: the script type.
6487 DECL_INT_ACCESSORS(type)
6488
6489 // [line_ends]: FixedArray of line ends positions.
6490 DECL_ACCESSORS(line_ends, Object)
6491
6492 // [eval_from_shared]: for eval scripts the shared function info for the
6493 // function from which eval was called.
6494 DECL_ACCESSORS(eval_from_shared, Object)
6495
6496 // [eval_from_position]: the source position in the code for the function
6497 // from which eval was called, as positive integer. Or the code offset in the
6498 // code from which eval was called, as negative integer.
6499 DECL_INT_ACCESSORS(eval_from_position)
6500
6501 // [shared_function_infos]: weak fixed array containing all shared
6502 // function infos created from this script.
6503 DECL_ACCESSORS(shared_function_infos, Object)
6504
6505 // [flags]: Holds an exciting bitfield.
6506 DECL_INT_ACCESSORS(flags)
6507
6508 // [source_url]: sourceURL from magic comment
6509 DECL_ACCESSORS(source_url, Object)
6510
6511 // [source_url]: sourceMappingURL magic comment
6512 DECL_ACCESSORS(source_mapping_url, Object)
6513
6514 // [compilation_type]: how the the script was compiled. Encoded in the
6515 // 'flags' field.
6516 inline CompilationType compilation_type();
6517 inline void set_compilation_type(CompilationType type);
6518
6519 // [compilation_state]: determines whether the script has already been
6520 // compiled. Encoded in the 'flags' field.
6521 inline CompilationState compilation_state();
6522 inline void set_compilation_state(CompilationState state);
6523
6524 // [hide_source]: determines whether the script source can be exposed as
6525 // function source. Encoded in the 'flags' field.
6526 inline bool hide_source();
6527 inline void set_hide_source(bool value);
6528
6529 // [origin_options]: optional attributes set by the embedder via ScriptOrigin,
6530 // and used by the embedder to make decisions about the script. V8 just passes
6531 // this through. Encoded in the 'flags' field.
6532 inline v8::ScriptOriginOptions origin_options();
6533 inline void set_origin_options(ScriptOriginOptions origin_options);
6534
6535 DECLARE_CAST(Script)
6536
6537 // If script source is an external string, check that the underlying
6538 // resource is accessible. Otherwise, always return true.
6539 inline bool HasValidSource();
6540
6541 static Handle<Object> GetNameOrSourceURL(Handle<Script> script);
6542
6543 // Set eval origin for stack trace formatting.
6544 static void SetEvalOrigin(Handle<Script> script,
6545 Handle<SharedFunctionInfo> outer,
6546 int eval_position);
6547 // Retrieve source position from where eval was called.
6548 int GetEvalPosition();
6549
6550 // Init line_ends array with source code positions of line ends.
6551 static void InitLineEnds(Handle<Script> script);
6552
6553 // Convert code offset into column number.
6554 static int GetColumnNumber(Handle<Script> script, int code_offset);
6555
6556 // Convert code offset into (zero-based) line number.
6557 // The non-handlified version does not allocate, but may be much slower.
6558 static int GetLineNumber(Handle<Script> script, int code_offset);
6559 int GetLineNumber(int code_pos);
6560
6561 // Carries information about a source position.
6562 struct PositionInfo {
PositionInfoPositionInfo6563 PositionInfo() : line(-1), column(-1), line_start(-1), line_end(-1) {}
6564
6565 int line; // Zero-based line number.
6566 int column; // Zero-based column number.
6567 int line_start; // Position of first character in line.
6568 int line_end; // Position of last (non-linebreak) character in line.
6569 };
6570
6571 // Specifies whether to add offsets to position infos.
6572 enum OffsetFlag { NO_OFFSET = 0, WITH_OFFSET = 1 };
6573
6574 // Retrieves information about the given position, optionally with an offset.
6575 // Returns false on failure, and otherwise writes into the given info object
6576 // on success.
6577 bool GetPositionInfo(int position, PositionInfo* info,
6578 OffsetFlag offset_flag);
6579
6580 // Get the JS object wrapping the given script; create it if none exists.
6581 static Handle<JSObject> GetWrapper(Handle<Script> script);
6582
6583 // Look through the list of existing shared function infos to find one
6584 // that matches the function literal. Return empty handle if not found.
6585 MaybeHandle<SharedFunctionInfo> FindSharedFunctionInfo(FunctionLiteral* fun);
6586
6587 // Iterate over all script objects on the heap.
6588 class Iterator {
6589 public:
6590 explicit Iterator(Isolate* isolate);
6591 Script* Next();
6592
6593 private:
6594 WeakFixedArray::Iterator iterator_;
6595 DISALLOW_COPY_AND_ASSIGN(Iterator);
6596 };
6597
6598 // Dispatched behavior.
6599 DECLARE_PRINTER(Script)
6600 DECLARE_VERIFIER(Script)
6601
6602 static const int kSourceOffset = HeapObject::kHeaderSize;
6603 static const int kNameOffset = kSourceOffset + kPointerSize;
6604 static const int kLineOffsetOffset = kNameOffset + kPointerSize;
6605 static const int kColumnOffsetOffset = kLineOffsetOffset + kPointerSize;
6606 static const int kContextOffset = kColumnOffsetOffset + kPointerSize;
6607 static const int kWrapperOffset = kContextOffset + kPointerSize;
6608 static const int kTypeOffset = kWrapperOffset + kPointerSize;
6609 static const int kLineEndsOffset = kTypeOffset + kPointerSize;
6610 static const int kIdOffset = kLineEndsOffset + kPointerSize;
6611 static const int kEvalFromSharedOffset = kIdOffset + kPointerSize;
6612 static const int kEvalFromPositionOffset =
6613 kEvalFromSharedOffset + kPointerSize;
6614 static const int kSharedFunctionInfosOffset =
6615 kEvalFromPositionOffset + kPointerSize;
6616 static const int kFlagsOffset = kSharedFunctionInfosOffset + kPointerSize;
6617 static const int kSourceUrlOffset = kFlagsOffset + kPointerSize;
6618 static const int kSourceMappingUrlOffset = kSourceUrlOffset + kPointerSize;
6619 static const int kSize = kSourceMappingUrlOffset + kPointerSize;
6620
6621 private:
6622 int GetLineNumberWithArray(int code_pos);
6623
6624 // Bit positions in the flags field.
6625 static const int kCompilationTypeBit = 0;
6626 static const int kCompilationStateBit = 1;
6627 static const int kHideSourceBit = 2;
6628 static const int kOriginOptionsShift = 3;
6629 static const int kOriginOptionsSize = 3;
6630 static const int kOriginOptionsMask = ((1 << kOriginOptionsSize) - 1)
6631 << kOriginOptionsShift;
6632
6633 DISALLOW_IMPLICIT_CONSTRUCTORS(Script);
6634 };
6635
6636
6637 // List of builtin functions we want to identify to improve code
6638 // generation.
6639 //
6640 // Each entry has a name of a global object property holding an object
6641 // optionally followed by ".prototype", a name of a builtin function
6642 // on the object (the one the id is set for), and a label.
6643 //
6644 // Installation of ids for the selected builtin functions is handled
6645 // by the bootstrapper.
6646 #define FUNCTIONS_WITH_ID_LIST(V) \
6647 V(Array.prototype, indexOf, ArrayIndexOf) \
6648 V(Array.prototype, lastIndexOf, ArrayLastIndexOf) \
6649 V(Array.prototype, push, ArrayPush) \
6650 V(Array.prototype, pop, ArrayPop) \
6651 V(Array.prototype, shift, ArrayShift) \
6652 V(Function.prototype, apply, FunctionApply) \
6653 V(Function.prototype, call, FunctionCall) \
6654 V(Object.prototype, hasOwnProperty, ObjectHasOwnProperty) \
6655 V(String.prototype, charCodeAt, StringCharCodeAt) \
6656 V(String.prototype, charAt, StringCharAt) \
6657 V(String.prototype, concat, StringConcat) \
6658 V(String.prototype, toLowerCase, StringToLowerCase) \
6659 V(String.prototype, toUpperCase, StringToUpperCase) \
6660 V(String, fromCharCode, StringFromCharCode) \
6661 V(Math, random, MathRandom) \
6662 V(Math, floor, MathFloor) \
6663 V(Math, round, MathRound) \
6664 V(Math, ceil, MathCeil) \
6665 V(Math, abs, MathAbs) \
6666 V(Math, log, MathLog) \
6667 V(Math, log1p, MathLog1p) \
6668 V(Math, log2, MathLog2) \
6669 V(Math, log10, MathLog10) \
6670 V(Math, cbrt, MathCbrt) \
6671 V(Math, exp, MathExp) \
6672 V(Math, expm1, MathExpm1) \
6673 V(Math, sqrt, MathSqrt) \
6674 V(Math, pow, MathPow) \
6675 V(Math, max, MathMax) \
6676 V(Math, min, MathMin) \
6677 V(Math, cos, MathCos) \
6678 V(Math, sin, MathSin) \
6679 V(Math, tan, MathTan) \
6680 V(Math, acos, MathAcos) \
6681 V(Math, asin, MathAsin) \
6682 V(Math, atan, MathAtan) \
6683 V(Math, atan2, MathAtan2) \
6684 V(Math, atanh, MathAtanh) \
6685 V(Math, imul, MathImul) \
6686 V(Math, clz32, MathClz32) \
6687 V(Math, fround, MathFround) \
6688 V(Math, trunc, MathTrunc)
6689
6690 #define ATOMIC_FUNCTIONS_WITH_ID_LIST(V) \
6691 V(Atomics, load, AtomicsLoad) \
6692 V(Atomics, store, AtomicsStore)
6693
6694 enum BuiltinFunctionId {
6695 kArrayCode,
6696 #define DECLARE_FUNCTION_ID(ignored1, ignore2, name) \
6697 k##name,
6698 FUNCTIONS_WITH_ID_LIST(DECLARE_FUNCTION_ID)
6699 ATOMIC_FUNCTIONS_WITH_ID_LIST(DECLARE_FUNCTION_ID)
6700 #undef DECLARE_FUNCTION_ID
6701 // Fake id for a special case of Math.pow. Note, it continues the
6702 // list of math functions.
6703 kMathPowHalf,
6704 // These are manually assigned to special getters during bootstrapping.
6705 kDataViewBuffer,
6706 kDataViewByteLength,
6707 kDataViewByteOffset,
6708 kTypedArrayByteLength,
6709 kTypedArrayByteOffset,
6710 kTypedArrayLength,
6711 };
6712
6713
6714 // Result of searching in an optimized code map of a SharedFunctionInfo. Note
6715 // that both {code} and {literals} can be NULL to pass search result status.
6716 struct CodeAndLiterals {
6717 Code* code; // Cached optimized code.
6718 LiteralsArray* literals; // Cached literals array.
6719 };
6720
6721
6722 // SharedFunctionInfo describes the JSFunction information that can be
6723 // shared by multiple instances of the function.
6724 class SharedFunctionInfo: public HeapObject {
6725 public:
6726 // [name]: Function name.
6727 DECL_ACCESSORS(name, Object)
6728
6729 // [code]: Function code.
6730 DECL_ACCESSORS(code, Code)
6731
6732 // Get the abstract code associated with the function, which will either be
6733 // a Code object or a BytecodeArray.
6734 inline AbstractCode* abstract_code();
6735
6736 inline void ReplaceCode(Code* code);
6737
6738 // [optimized_code_map]: Map from native context to optimized code
6739 // and a shared literals array.
6740 DECL_ACCESSORS(optimized_code_map, FixedArray)
6741
6742 // Returns entry from optimized code map for specified context and OSR entry.
6743 // Note that {code == nullptr, literals == nullptr} indicates no matching
6744 // entry has been found, whereas {code, literals == nullptr} indicates that
6745 // code is context-independent.
6746 CodeAndLiterals SearchOptimizedCodeMap(Context* native_context,
6747 BailoutId osr_ast_id);
6748
6749 // Clear optimized code map.
6750 void ClearOptimizedCodeMap();
6751
6752 // Like ClearOptimizedCodeMap, but preserves literals.
6753 void ClearCodeFromOptimizedCodeMap();
6754
6755 // We have a special root FixedArray with the right shape and values
6756 // to represent the cleared optimized code map. This predicate checks
6757 // if that root is installed.
6758 inline bool OptimizedCodeMapIsCleared() const;
6759
6760 // Removes a specific optimized code object from the optimized code map.
6761 // In case of non-OSR the code reference is cleared from the cache entry but
6762 // the entry itself is left in the map in order to proceed sharing literals.
6763 void EvictFromOptimizedCodeMap(Code* optimized_code, const char* reason);
6764
6765 // Trims the optimized code map after entries have been removed.
6766 void TrimOptimizedCodeMap(int shrink_by);
6767
6768 static Handle<LiteralsArray> FindOrCreateLiterals(
6769 Handle<SharedFunctionInfo> shared, Handle<Context> native_context);
6770
6771 // Add or update entry in the optimized code map for context-independent code.
6772 static void AddSharedCodeToOptimizedCodeMap(Handle<SharedFunctionInfo> shared,
6773 Handle<Code> code);
6774
6775 // Add or update entry in the optimized code map for context-dependent code.
6776 // If {code} is not given, then an existing entry's code won't be overwritten.
6777 static void AddToOptimizedCodeMap(Handle<SharedFunctionInfo> shared,
6778 Handle<Context> native_context,
6779 MaybeHandle<Code> code,
6780 Handle<LiteralsArray> literals,
6781 BailoutId osr_ast_id);
6782
6783 // Set up the link between shared function info and the script. The shared
6784 // function info is added to the list on the script.
6785 static void SetScript(Handle<SharedFunctionInfo> shared,
6786 Handle<Object> script_object);
6787
6788 // Layout description of the optimized code map.
6789 static const int kSharedCodeIndex = 0;
6790 static const int kEntriesStart = 1;
6791 static const int kContextOffset = 0;
6792 static const int kCachedCodeOffset = 1;
6793 static const int kLiteralsOffset = 2;
6794 static const int kOsrAstIdOffset = 3;
6795 static const int kEntryLength = 4;
6796 static const int kInitialLength = kEntriesStart + kEntryLength;
6797
6798 static const int kNotFound = -1;
6799
6800 // Helpers for assembly code that does a backwards walk of the optimized code
6801 // map.
6802 static const int kOffsetToPreviousContext =
6803 FixedArray::kHeaderSize + kPointerSize * (kContextOffset - kEntryLength);
6804 static const int kOffsetToPreviousCachedCode =
6805 FixedArray::kHeaderSize +
6806 kPointerSize * (kCachedCodeOffset - kEntryLength);
6807 static const int kOffsetToPreviousLiterals =
6808 FixedArray::kHeaderSize + kPointerSize * (kLiteralsOffset - kEntryLength);
6809 static const int kOffsetToPreviousOsrAstId =
6810 FixedArray::kHeaderSize + kPointerSize * (kOsrAstIdOffset - kEntryLength);
6811
6812 // [scope_info]: Scope info.
6813 DECL_ACCESSORS(scope_info, ScopeInfo)
6814
6815 // [construct stub]: Code stub for constructing instances of this function.
6816 DECL_ACCESSORS(construct_stub, Code)
6817
6818 // Returns if this function has been compiled to native code yet.
6819 inline bool is_compiled();
6820
6821 // [length]: The function length - usually the number of declared parameters.
6822 // Use up to 2^30 parameters.
6823 inline int length() const;
6824 inline void set_length(int value);
6825
6826 // [internal formal parameter count]: The declared number of parameters.
6827 // For subclass constructors, also includes new.target.
6828 // The size of function's frame is internal_formal_parameter_count + 1.
6829 inline int internal_formal_parameter_count() const;
6830 inline void set_internal_formal_parameter_count(int value);
6831
6832 // Set the formal parameter count so the function code will be
6833 // called without using argument adaptor frames.
6834 inline void DontAdaptArguments();
6835
6836 // [expected_nof_properties]: Expected number of properties for the function.
6837 inline int expected_nof_properties() const;
6838 inline void set_expected_nof_properties(int value);
6839
6840 // [feedback_metadata] - describes ast node feedback from full-codegen and
6841 // (increasingly) from crankshafted code where sufficient feedback isn't
6842 // available.
6843 DECL_ACCESSORS(feedback_metadata, TypeFeedbackMetadata)
6844
6845 #if TRACE_MAPS
6846 // [unique_id] - For --trace-maps purposes, an identifier that's persistent
6847 // even if the GC moves this SharedFunctionInfo.
6848 inline int unique_id() const;
6849 inline void set_unique_id(int value);
6850 #endif
6851
6852 // [instance class name]: class name for instances.
6853 DECL_ACCESSORS(instance_class_name, Object)
6854
6855 // [function data]: This field holds some additional data for function.
6856 // Currently it has one of:
6857 // - a FunctionTemplateInfo to make benefit the API [IsApiFunction()].
6858 // - a BytecodeArray for the interpreter [HasBytecodeArray()].
6859 DECL_ACCESSORS(function_data, Object)
6860
6861 inline bool IsApiFunction();
6862 inline FunctionTemplateInfo* get_api_func_data();
6863 inline void set_api_func_data(FunctionTemplateInfo* data);
6864 inline bool HasBytecodeArray();
6865 inline BytecodeArray* bytecode_array();
6866 inline void set_bytecode_array(BytecodeArray* bytecode);
6867 inline void ClearBytecodeArray();
6868
6869 // [function identifier]: This field holds an additional identifier for the
6870 // function.
6871 // - a Smi identifying a builtin function [HasBuiltinFunctionId()].
6872 // - a String identifying the function's inferred name [HasInferredName()].
6873 // The inferred_name is inferred from variable or property
6874 // assignment of this function. It is used to facilitate debugging and
6875 // profiling of JavaScript code written in OO style, where almost
6876 // all functions are anonymous but are assigned to object
6877 // properties.
6878 DECL_ACCESSORS(function_identifier, Object)
6879
6880 inline bool HasBuiltinFunctionId();
6881 inline BuiltinFunctionId builtin_function_id();
6882 inline void set_builtin_function_id(BuiltinFunctionId id);
6883 inline bool HasInferredName();
6884 inline String* inferred_name();
6885 inline void set_inferred_name(String* inferred_name);
6886
6887 // [script info]: Script from which the function originates.
6888 DECL_ACCESSORS(script, Object)
6889
6890 // [num_literals]: Number of literals used by this function.
6891 inline int num_literals() const;
6892 inline void set_num_literals(int value);
6893
6894 // [start_position_and_type]: Field used to store both the source code
6895 // position, whether or not the function is a function expression,
6896 // and whether or not the function is a toplevel function. The two
6897 // least significants bit indicates whether the function is an
6898 // expression and the rest contains the source code position.
6899 inline int start_position_and_type() const;
6900 inline void set_start_position_and_type(int value);
6901
6902 // The function is subject to debugging if a debug info is attached.
6903 inline bool HasDebugInfo();
6904 inline DebugInfo* GetDebugInfo();
6905
6906 // A function has debug code if the compiled code has debug break slots.
6907 inline bool HasDebugCode();
6908
6909 // [debug info]: Debug information.
6910 DECL_ACCESSORS(debug_info, Object)
6911
6912 // The function's name if it is non-empty, otherwise the inferred name.
6913 String* DebugName();
6914
6915 // Used for flags such as --hydrogen-filter.
6916 bool PassesFilter(const char* raw_filter);
6917
6918 // Position of the 'function' token in the script source.
6919 inline int function_token_position() const;
6920 inline void set_function_token_position(int function_token_position);
6921
6922 // Position of this function in the script source.
6923 inline int start_position() const;
6924 inline void set_start_position(int start_position);
6925
6926 // End position of this function in the script source.
6927 inline int end_position() const;
6928 inline void set_end_position(int end_position);
6929
6930 // Is this function a named function expression in the source code.
6931 DECL_BOOLEAN_ACCESSORS(is_named_expression)
6932
6933 // Is this function a top-level function (scripts, evals).
6934 DECL_BOOLEAN_ACCESSORS(is_toplevel)
6935
6936 // Bit field containing various information collected by the compiler to
6937 // drive optimization.
6938 inline int compiler_hints() const;
6939 inline void set_compiler_hints(int value);
6940
6941 inline int ast_node_count() const;
6942 inline void set_ast_node_count(int count);
6943
6944 inline int profiler_ticks() const;
6945 inline void set_profiler_ticks(int ticks);
6946
6947 // Inline cache age is used to infer whether the function survived a context
6948 // disposal or not. In the former case we reset the opt_count.
6949 inline int ic_age();
6950 inline void set_ic_age(int age);
6951
6952 // Indicates if this function can be lazy compiled.
6953 // This is used to determine if we can safely flush code from a function
6954 // when doing GC if we expect that the function will no longer be used.
6955 DECL_BOOLEAN_ACCESSORS(allows_lazy_compilation)
6956
6957 // Indicates if this function can be lazy compiled without a context.
6958 // This is used to determine if we can force compilation without reaching
6959 // the function through program execution but through other means (e.g. heap
6960 // iteration by the debugger).
6961 DECL_BOOLEAN_ACCESSORS(allows_lazy_compilation_without_context)
6962
6963 // Indicates whether optimizations have been disabled for this
6964 // shared function info. If a function is repeatedly optimized or if
6965 // we cannot optimize the function we disable optimization to avoid
6966 // spending time attempting to optimize it again.
6967 DECL_BOOLEAN_ACCESSORS(optimization_disabled)
6968
6969 // Indicates the language mode.
6970 inline LanguageMode language_mode();
6971 inline void set_language_mode(LanguageMode language_mode);
6972
6973 // False if the function definitely does not allocate an arguments object.
6974 DECL_BOOLEAN_ACCESSORS(uses_arguments)
6975
6976 // Indicates that this function uses a super property (or an eval that may
6977 // use a super property).
6978 // This is needed to set up the [[HomeObject]] on the function instance.
6979 DECL_BOOLEAN_ACCESSORS(needs_home_object)
6980
6981 // True if the function has any duplicated parameter names.
6982 DECL_BOOLEAN_ACCESSORS(has_duplicate_parameters)
6983
6984 // Indicates whether the function is a native function.
6985 // These needs special treatment in .call and .apply since
6986 // null passed as the receiver should not be translated to the
6987 // global object.
6988 DECL_BOOLEAN_ACCESSORS(native)
6989
6990 // Indicate that this function should always be inlined in optimized code.
6991 DECL_BOOLEAN_ACCESSORS(force_inline)
6992
6993 // Indicates that the function was created by the Function function.
6994 // Though it's anonymous, toString should treat it as if it had the name
6995 // "anonymous". We don't set the name itself so that the system does not
6996 // see a binding for it.
6997 DECL_BOOLEAN_ACCESSORS(name_should_print_as_anonymous)
6998
6999 // Indicates that the function is either an anonymous expression
7000 // or an arrow function (the name field can be set through the API,
7001 // which does not change this flag).
7002 DECL_BOOLEAN_ACCESSORS(is_anonymous_expression)
7003
7004 // Is this a function or top-level/eval code.
7005 DECL_BOOLEAN_ACCESSORS(is_function)
7006
7007 // Indicates that code for this function cannot be compiled with Crankshaft.
7008 DECL_BOOLEAN_ACCESSORS(dont_crankshaft)
7009
7010 // Indicates that code for this function cannot be flushed.
7011 DECL_BOOLEAN_ACCESSORS(dont_flush)
7012
7013 // Indicates that this function is a generator.
7014 DECL_BOOLEAN_ACCESSORS(is_generator)
7015
7016 // Indicates that this function is an async function.
7017 DECL_BOOLEAN_ACCESSORS(is_async)
7018
7019 // Indicates that this function can be suspended, either via YieldExpressions
7020 // or AwaitExpressions.
7021 inline bool is_resumable() const;
7022
7023 // Indicates that this function is an arrow function.
7024 DECL_BOOLEAN_ACCESSORS(is_arrow)
7025
7026 // Indicates that this function is a concise method.
7027 DECL_BOOLEAN_ACCESSORS(is_concise_method)
7028
7029 // Indicates that this function is a getter.
7030 DECL_BOOLEAN_ACCESSORS(is_getter_function)
7031
7032 // Indicates that this function is a setter.
7033 DECL_BOOLEAN_ACCESSORS(is_setter_function)
7034
7035 // Indicates that this function is a default constructor.
7036 DECL_BOOLEAN_ACCESSORS(is_default_constructor)
7037
7038 // Indicates that this function is an asm function.
7039 DECL_BOOLEAN_ACCESSORS(asm_function)
7040
7041 // Indicates that the the shared function info is deserialized from cache.
7042 DECL_BOOLEAN_ACCESSORS(deserialized)
7043
7044 // Indicates that the the shared function info has never been compiled before.
7045 DECL_BOOLEAN_ACCESSORS(never_compiled)
7046
7047 // Whether this function was created from a FunctionDeclaration.
7048 DECL_BOOLEAN_ACCESSORS(is_declaration)
7049
7050 inline FunctionKind kind();
7051 inline void set_kind(FunctionKind kind);
7052
7053 // Indicates whether or not the code in the shared function support
7054 // deoptimization.
7055 inline bool has_deoptimization_support();
7056
7057 // Enable deoptimization support through recompiled code.
7058 void EnableDeoptimizationSupport(Code* recompiled);
7059
7060 // Disable (further) attempted optimization of all functions sharing this
7061 // shared function info.
7062 void DisableOptimization(BailoutReason reason);
7063
7064 inline BailoutReason disable_optimization_reason();
7065
7066 // Lookup the bailout ID and DCHECK that it exists in the non-optimized
7067 // code, returns whether it asserted (i.e., always true if assertions are
7068 // disabled).
7069 bool VerifyBailoutId(BailoutId id);
7070
7071 // [source code]: Source code for the function.
7072 bool HasSourceCode() const;
7073 Handle<Object> GetSourceCode();
7074
7075 // Number of times the function was optimized.
7076 inline int opt_count();
7077 inline void set_opt_count(int opt_count);
7078
7079 // Number of times the function was deoptimized.
7080 inline void set_deopt_count(int value);
7081 inline int deopt_count();
7082 inline void increment_deopt_count();
7083
7084 // Number of time we tried to re-enable optimization after it
7085 // was disabled due to high number of deoptimizations.
7086 inline void set_opt_reenable_tries(int value);
7087 inline int opt_reenable_tries();
7088
7089 inline void TryReenableOptimization();
7090
7091 // Stores deopt_count, opt_reenable_tries and ic_age as bit-fields.
7092 inline void set_counters(int value);
7093 inline int counters() const;
7094
7095 // Stores opt_count and bailout_reason as bit-fields.
7096 inline void set_opt_count_and_bailout_reason(int value);
7097 inline int opt_count_and_bailout_reason() const;
7098
7099 inline void set_disable_optimization_reason(BailoutReason reason);
7100
7101 // Tells whether this function should be subject to debugging.
7102 inline bool IsSubjectToDebugging();
7103
7104 // Whether this function is defined in native code or extensions.
7105 inline bool IsBuiltin();
7106
7107 // Check whether or not this function is inlineable.
7108 bool IsInlineable();
7109
7110 // Source size of this function.
7111 int SourceSize();
7112
7113 // Returns `false` if formal parameters include rest parameters, optional
7114 // parameters, or destructuring parameters.
7115 // TODO(caitp): make this a flag set during parsing
7116 inline bool has_simple_parameters();
7117
7118 // Initialize a SharedFunctionInfo from a parsed function literal.
7119 static void InitFromFunctionLiteral(Handle<SharedFunctionInfo> shared_info,
7120 FunctionLiteral* lit);
7121
7122 // Dispatched behavior.
7123 DECLARE_PRINTER(SharedFunctionInfo)
7124 DECLARE_VERIFIER(SharedFunctionInfo)
7125
7126 void ResetForNewContext(int new_ic_age);
7127
7128 // Iterate over all shared function infos.
7129 class Iterator {
7130 public:
7131 explicit Iterator(Isolate* isolate);
7132 SharedFunctionInfo* Next();
7133
7134 private:
7135 bool NextScript();
7136
7137 Script::Iterator script_iterator_;
7138 WeakFixedArray::Iterator sfi_iterator_;
7139 DisallowHeapAllocation no_gc_;
7140 DISALLOW_COPY_AND_ASSIGN(Iterator);
7141 };
7142
7143 DECLARE_CAST(SharedFunctionInfo)
7144
7145 // Constants.
7146 static const int kDontAdaptArgumentsSentinel = -1;
7147
7148 // Layout description.
7149 // Pointer fields.
7150 static const int kNameOffset = HeapObject::kHeaderSize;
7151 static const int kCodeOffset = kNameOffset + kPointerSize;
7152 static const int kOptimizedCodeMapOffset = kCodeOffset + kPointerSize;
7153 static const int kScopeInfoOffset = kOptimizedCodeMapOffset + kPointerSize;
7154 static const int kConstructStubOffset = kScopeInfoOffset + kPointerSize;
7155 static const int kInstanceClassNameOffset =
7156 kConstructStubOffset + kPointerSize;
7157 static const int kFunctionDataOffset =
7158 kInstanceClassNameOffset + kPointerSize;
7159 static const int kScriptOffset = kFunctionDataOffset + kPointerSize;
7160 static const int kDebugInfoOffset = kScriptOffset + kPointerSize;
7161 static const int kFunctionIdentifierOffset = kDebugInfoOffset + kPointerSize;
7162 static const int kFeedbackMetadataOffset =
7163 kFunctionIdentifierOffset + kPointerSize;
7164 #if TRACE_MAPS
7165 static const int kUniqueIdOffset = kFeedbackMetadataOffset + kPointerSize;
7166 static const int kLastPointerFieldOffset = kUniqueIdOffset;
7167 #else
7168 // Just to not break the postmortrem support with conditional offsets
7169 static const int kUniqueIdOffset = kFeedbackMetadataOffset;
7170 static const int kLastPointerFieldOffset = kFeedbackMetadataOffset;
7171 #endif
7172
7173 #if V8_HOST_ARCH_32_BIT
7174 // Smi fields.
7175 static const int kLengthOffset = kLastPointerFieldOffset + kPointerSize;
7176 static const int kFormalParameterCountOffset = kLengthOffset + kPointerSize;
7177 static const int kExpectedNofPropertiesOffset =
7178 kFormalParameterCountOffset + kPointerSize;
7179 static const int kNumLiteralsOffset =
7180 kExpectedNofPropertiesOffset + kPointerSize;
7181 static const int kStartPositionAndTypeOffset =
7182 kNumLiteralsOffset + kPointerSize;
7183 static const int kEndPositionOffset =
7184 kStartPositionAndTypeOffset + kPointerSize;
7185 static const int kFunctionTokenPositionOffset =
7186 kEndPositionOffset + kPointerSize;
7187 static const int kCompilerHintsOffset =
7188 kFunctionTokenPositionOffset + kPointerSize;
7189 static const int kOptCountAndBailoutReasonOffset =
7190 kCompilerHintsOffset + kPointerSize;
7191 static const int kCountersOffset =
7192 kOptCountAndBailoutReasonOffset + kPointerSize;
7193 static const int kAstNodeCountOffset =
7194 kCountersOffset + kPointerSize;
7195 static const int kProfilerTicksOffset =
7196 kAstNodeCountOffset + kPointerSize;
7197
7198 // Total size.
7199 static const int kSize = kProfilerTicksOffset + kPointerSize;
7200 #else
7201 // The only reason to use smi fields instead of int fields is to allow
7202 // iteration without maps decoding during garbage collections.
7203 // To avoid wasting space on 64-bit architectures we use the following trick:
7204 // we group integer fields into pairs
7205 // The least significant integer in each pair is shifted left by 1. By doing
7206 // this we guarantee that LSB of each kPointerSize aligned word is not set and
7207 // thus this word cannot be treated as pointer to HeapObject during old space
7208 // traversal.
7209 #if V8_TARGET_LITTLE_ENDIAN
7210 static const int kLengthOffset = kLastPointerFieldOffset + kPointerSize;
7211 static const int kFormalParameterCountOffset =
7212 kLengthOffset + kIntSize;
7213
7214 static const int kExpectedNofPropertiesOffset =
7215 kFormalParameterCountOffset + kIntSize;
7216 static const int kNumLiteralsOffset =
7217 kExpectedNofPropertiesOffset + kIntSize;
7218
7219 static const int kEndPositionOffset =
7220 kNumLiteralsOffset + kIntSize;
7221 static const int kStartPositionAndTypeOffset =
7222 kEndPositionOffset + kIntSize;
7223
7224 static const int kFunctionTokenPositionOffset =
7225 kStartPositionAndTypeOffset + kIntSize;
7226 static const int kCompilerHintsOffset =
7227 kFunctionTokenPositionOffset + kIntSize;
7228
7229 static const int kOptCountAndBailoutReasonOffset =
7230 kCompilerHintsOffset + kIntSize;
7231 static const int kCountersOffset =
7232 kOptCountAndBailoutReasonOffset + kIntSize;
7233
7234 static const int kAstNodeCountOffset =
7235 kCountersOffset + kIntSize;
7236 static const int kProfilerTicksOffset =
7237 kAstNodeCountOffset + kIntSize;
7238
7239 // Total size.
7240 static const int kSize = kProfilerTicksOffset + kIntSize;
7241
7242 #elif V8_TARGET_BIG_ENDIAN
7243 static const int kFormalParameterCountOffset =
7244 kLastPointerFieldOffset + kPointerSize;
7245 static const int kLengthOffset = kFormalParameterCountOffset + kIntSize;
7246
7247 static const int kNumLiteralsOffset = kLengthOffset + kIntSize;
7248 static const int kExpectedNofPropertiesOffset = kNumLiteralsOffset + kIntSize;
7249
7250 static const int kStartPositionAndTypeOffset =
7251 kExpectedNofPropertiesOffset + kIntSize;
7252 static const int kEndPositionOffset = kStartPositionAndTypeOffset + kIntSize;
7253
7254 static const int kCompilerHintsOffset = kEndPositionOffset + kIntSize;
7255 static const int kFunctionTokenPositionOffset =
7256 kCompilerHintsOffset + kIntSize;
7257
7258 static const int kCountersOffset = kFunctionTokenPositionOffset + kIntSize;
7259 static const int kOptCountAndBailoutReasonOffset = kCountersOffset + kIntSize;
7260
7261 static const int kProfilerTicksOffset =
7262 kOptCountAndBailoutReasonOffset + kIntSize;
7263 static const int kAstNodeCountOffset = kProfilerTicksOffset + kIntSize;
7264
7265 // Total size.
7266 static const int kSize = kAstNodeCountOffset + kIntSize;
7267
7268 #else
7269 #error Unknown byte ordering
7270 #endif // Big endian
7271 #endif // 64-bit
7272
7273
7274 static const int kAlignedSize = POINTER_SIZE_ALIGN(kSize);
7275
7276 typedef FixedBodyDescriptor<kNameOffset,
7277 kLastPointerFieldOffset + kPointerSize,
7278 kSize> BodyDescriptor;
7279
7280 // Bit positions in start_position_and_type.
7281 // The source code start position is in the 30 most significant bits of
7282 // the start_position_and_type field.
7283 static const int kIsNamedExpressionBit = 0;
7284 static const int kIsTopLevelBit = 1;
7285 static const int kStartPositionShift = 2;
7286 static const int kStartPositionMask = ~((1 << kStartPositionShift) - 1);
7287
7288 // Bit positions in compiler_hints.
7289 enum CompilerHints {
7290 // byte 0
7291 kAllowLazyCompilation,
7292 kAllowLazyCompilationWithoutContext,
7293 kOptimizationDisabled,
7294 kNeverCompiled,
7295 kNative,
7296 kStrictModeFunction,
7297 kUsesArguments,
7298 kNeedsHomeObject,
7299 // byte 1
7300 kHasDuplicateParameters,
7301 kForceInline,
7302 kIsAsmFunction,
7303 kIsAnonymousExpression,
7304 kNameShouldPrintAsAnonymous,
7305 kIsFunction,
7306 kDontCrankshaft,
7307 kDontFlush,
7308 // byte 2
7309 kFunctionKind,
7310 kIsArrow = kFunctionKind,
7311 kIsGenerator,
7312 kIsConciseMethod,
7313 kIsDefaultConstructor,
7314 kIsSubclassConstructor,
7315 kIsBaseConstructor,
7316 kIsGetterFunction,
7317 kIsSetterFunction,
7318 // byte 3
7319 kIsAsyncFunction,
7320 kDeserialized,
7321 kIsDeclaration,
7322 kCompilerHintsCount, // Pseudo entry
7323 };
7324 // Add hints for other modes when they're added.
7325 STATIC_ASSERT(LANGUAGE_END == 3);
7326 // kFunctionKind has to be byte-aligned
7327 STATIC_ASSERT((kFunctionKind % kBitsPerByte) == 0);
7328 // Make sure that FunctionKind and byte 2 are in sync:
7329 #define ASSERT_FUNCTION_KIND_ORDER(functionKind, compilerFunctionKind) \
7330 STATIC_ASSERT(FunctionKind::functionKind == \
7331 1 << (compilerFunctionKind - kFunctionKind))
7332 ASSERT_FUNCTION_KIND_ORDER(kArrowFunction, kIsArrow);
7333 ASSERT_FUNCTION_KIND_ORDER(kGeneratorFunction, kIsGenerator);
7334 ASSERT_FUNCTION_KIND_ORDER(kConciseMethod, kIsConciseMethod);
7335 ASSERT_FUNCTION_KIND_ORDER(kDefaultConstructor, kIsDefaultConstructor);
7336 ASSERT_FUNCTION_KIND_ORDER(kSubclassConstructor, kIsSubclassConstructor);
7337 ASSERT_FUNCTION_KIND_ORDER(kBaseConstructor, kIsBaseConstructor);
7338 ASSERT_FUNCTION_KIND_ORDER(kGetterFunction, kIsGetterFunction);
7339 ASSERT_FUNCTION_KIND_ORDER(kSetterFunction, kIsSetterFunction);
7340 #undef ASSERT_FUNCTION_KIND_ORDER
7341
7342 class FunctionKindBits : public BitField<FunctionKind, kIsArrow, 9> {};
7343
7344 class DeoptCountBits : public BitField<int, 0, 4> {};
7345 class OptReenableTriesBits : public BitField<int, 4, 18> {};
7346 class ICAgeBits : public BitField<int, 22, 8> {};
7347
7348 class OptCountBits : public BitField<int, 0, 22> {};
7349 class DisabledOptimizationReasonBits : public BitField<int, 22, 8> {};
7350
7351 private:
7352 #if V8_HOST_ARCH_32_BIT
7353 // On 32 bit platforms, compiler hints is a smi.
7354 static const int kCompilerHintsSmiTagSize = kSmiTagSize;
7355 static const int kCompilerHintsSize = kPointerSize;
7356 #else
7357 // On 64 bit platforms, compiler hints is not a smi, see comment above.
7358 static const int kCompilerHintsSmiTagSize = 0;
7359 static const int kCompilerHintsSize = kIntSize;
7360 #endif
7361
7362 STATIC_ASSERT(SharedFunctionInfo::kCompilerHintsCount <=
7363 SharedFunctionInfo::kCompilerHintsSize * kBitsPerByte);
7364
7365 public:
7366 // Constants for optimizing codegen for strict mode function and
7367 // native tests when using integer-width instructions.
7368 static const int kStrictModeBit =
7369 kStrictModeFunction + kCompilerHintsSmiTagSize;
7370 static const int kNativeBit = kNative + kCompilerHintsSmiTagSize;
7371 static const int kHasDuplicateParametersBit =
7372 kHasDuplicateParameters + kCompilerHintsSmiTagSize;
7373
7374 static const int kClassConstructorBits =
7375 FunctionKind::kClassConstructor
7376 << (kFunctionKind + kCompilerHintsSmiTagSize);
7377
7378 // Constants for optimizing codegen for strict mode function and
7379 // native tests.
7380 // Allows to use byte-width instructions.
7381 static const int kStrictModeBitWithinByte = kStrictModeBit % kBitsPerByte;
7382 static const int kNativeBitWithinByte = kNativeBit % kBitsPerByte;
7383 static const int kHasDuplicateParametersBitWithinByte =
7384 kHasDuplicateParametersBit % kBitsPerByte;
7385
7386 static const int kClassConstructorBitsWithinByte =
7387 FunctionKind::kClassConstructor << kCompilerHintsSmiTagSize;
7388 STATIC_ASSERT(kClassConstructorBitsWithinByte < (1 << kBitsPerByte));
7389
7390 #if defined(V8_TARGET_LITTLE_ENDIAN)
7391 #define BYTE_OFFSET(compiler_hint) \
7392 kCompilerHintsOffset + \
7393 (compiler_hint + kCompilerHintsSmiTagSize) / kBitsPerByte
7394 #elif defined(V8_TARGET_BIG_ENDIAN)
7395 #define BYTE_OFFSET(compiler_hint) \
7396 kCompilerHintsOffset + (kCompilerHintsSize - 1) - \
7397 ((compiler_hint + kCompilerHintsSmiTagSize) / kBitsPerByte)
7398 #else
7399 #error Unknown byte ordering
7400 #endif
7401 static const int kStrictModeByteOffset = BYTE_OFFSET(kStrictModeFunction);
7402 static const int kNativeByteOffset = BYTE_OFFSET(kNative);
7403 static const int kFunctionKindByteOffset = BYTE_OFFSET(kFunctionKind);
7404 static const int kHasDuplicateParametersByteOffset =
7405 BYTE_OFFSET(kHasDuplicateParameters);
7406 #undef BYTE_OFFSET
7407
7408 private:
7409 // Returns entry from optimized code map for specified context and OSR entry.
7410 // The result is either kNotFound, kSharedCodeIndex for context-independent
7411 // entry or a start index of the context-dependent entry.
7412 int SearchOptimizedCodeMapEntry(Context* native_context,
7413 BailoutId osr_ast_id);
7414
7415 DISALLOW_IMPLICIT_CONSTRUCTORS(SharedFunctionInfo);
7416 };
7417
7418
7419 // Printing support.
7420 struct SourceCodeOf {
7421 explicit SourceCodeOf(SharedFunctionInfo* v, int max = -1)
valueSourceCodeOf7422 : value(v), max_length(max) {}
7423 const SharedFunctionInfo* value;
7424 int max_length;
7425 };
7426
7427
7428 std::ostream& operator<<(std::ostream& os, const SourceCodeOf& v);
7429
7430
7431 class JSGeneratorObject: public JSObject {
7432 public:
7433 // [function]: The function corresponding to this generator object.
7434 DECL_ACCESSORS(function, JSFunction)
7435
7436 // [context]: The context of the suspended computation.
7437 DECL_ACCESSORS(context, Context)
7438
7439 // [receiver]: The receiver of the suspended computation.
7440 DECL_ACCESSORS(receiver, Object)
7441
7442 // [input_or_debug_pos]
7443 // For executing generators: the most recent input value.
7444 // For suspended new-style generators: debug information (bytecode offset).
7445 // For suspended old-style generators: unused.
7446 // There is currently no need to remember the most recent input value for a
7447 // suspended generator.
7448 DECL_ACCESSORS(input_or_debug_pos, Object)
7449
7450 // [resume_mode]: The most recent resume mode.
7451 enum ResumeMode { kNext, kReturn, kThrow };
7452 DECL_INT_ACCESSORS(resume_mode)
7453
7454 // [continuation]
7455 //
7456 // A positive value indicates a suspended generator. The special
7457 // kGeneratorExecuting and kGeneratorClosed values indicate that a generator
7458 // cannot be resumed.
7459 inline int continuation() const;
7460 inline void set_continuation(int continuation);
7461 inline bool is_closed() const;
7462 inline bool is_executing() const;
7463 inline bool is_suspended() const;
7464
7465 // For suspended generators: the source position at which the generator
7466 // is suspended.
7467 int source_position() const;
7468
7469 // [operand_stack]: Saved operand stack.
7470 DECL_ACCESSORS(operand_stack, FixedArray)
7471
7472 DECLARE_CAST(JSGeneratorObject)
7473
7474 // Dispatched behavior.
7475 DECLARE_VERIFIER(JSGeneratorObject)
7476
7477 // Magic sentinel values for the continuation.
7478 static const int kGeneratorExecuting = -2;
7479 static const int kGeneratorClosed = -1;
7480
7481 // Layout description.
7482 static const int kFunctionOffset = JSObject::kHeaderSize;
7483 static const int kContextOffset = kFunctionOffset + kPointerSize;
7484 static const int kReceiverOffset = kContextOffset + kPointerSize;
7485 static const int kInputOrDebugPosOffset = kReceiverOffset + kPointerSize;
7486 static const int kResumeModeOffset = kInputOrDebugPosOffset + kPointerSize;
7487 static const int kContinuationOffset = kResumeModeOffset + kPointerSize;
7488 static const int kOperandStackOffset = kContinuationOffset + kPointerSize;
7489 static const int kSize = kOperandStackOffset + kPointerSize;
7490
7491 private:
7492 DISALLOW_IMPLICIT_CONSTRUCTORS(JSGeneratorObject);
7493 };
7494
7495
7496 // Representation for module instance objects.
7497 class JSModule: public JSObject {
7498 public:
7499 // [context]: the context holding the module's locals, or undefined if none.
7500 DECL_ACCESSORS(context, Object)
7501
7502 // [scope_info]: Scope info.
7503 DECL_ACCESSORS(scope_info, ScopeInfo)
7504
7505 DECLARE_CAST(JSModule)
7506
7507 // Dispatched behavior.
7508 DECLARE_PRINTER(JSModule)
7509 DECLARE_VERIFIER(JSModule)
7510
7511 // Layout description.
7512 static const int kContextOffset = JSObject::kHeaderSize;
7513 static const int kScopeInfoOffset = kContextOffset + kPointerSize;
7514 static const int kSize = kScopeInfoOffset + kPointerSize;
7515
7516 private:
7517 DISALLOW_IMPLICIT_CONSTRUCTORS(JSModule);
7518 };
7519
7520
7521 // JSBoundFunction describes a bound function exotic object.
7522 class JSBoundFunction : public JSObject {
7523 public:
7524 // [bound_target_function]: The wrapped function object.
7525 DECL_ACCESSORS(bound_target_function, JSReceiver)
7526
7527 // [bound_this]: The value that is always passed as the this value when
7528 // calling the wrapped function.
7529 DECL_ACCESSORS(bound_this, Object)
7530
7531 // [bound_arguments]: A list of values whose elements are used as the first
7532 // arguments to any call to the wrapped function.
7533 DECL_ACCESSORS(bound_arguments, FixedArray)
7534
7535 static MaybeHandle<String> GetName(Isolate* isolate,
7536 Handle<JSBoundFunction> function);
7537 static MaybeHandle<Context> GetFunctionRealm(
7538 Handle<JSBoundFunction> function);
7539
7540 DECLARE_CAST(JSBoundFunction)
7541
7542 // Dispatched behavior.
7543 DECLARE_PRINTER(JSBoundFunction)
7544 DECLARE_VERIFIER(JSBoundFunction)
7545
7546 // The bound function's string representation implemented according
7547 // to ES6 section 19.2.3.5 Function.prototype.toString ( ).
7548 static Handle<String> ToString(Handle<JSBoundFunction> function);
7549
7550 // Layout description.
7551 static const int kBoundTargetFunctionOffset = JSObject::kHeaderSize;
7552 static const int kBoundThisOffset = kBoundTargetFunctionOffset + kPointerSize;
7553 static const int kBoundArgumentsOffset = kBoundThisOffset + kPointerSize;
7554 static const int kSize = kBoundArgumentsOffset + kPointerSize;
7555
7556 private:
7557 DISALLOW_IMPLICIT_CONSTRUCTORS(JSBoundFunction);
7558 };
7559
7560
7561 // JSFunction describes JavaScript functions.
7562 class JSFunction: public JSObject {
7563 public:
7564 // [prototype_or_initial_map]:
7565 DECL_ACCESSORS(prototype_or_initial_map, Object)
7566
7567 // [shared]: The information about the function that
7568 // can be shared by instances.
7569 DECL_ACCESSORS(shared, SharedFunctionInfo)
7570
7571 static const int kLengthDescriptorIndex = 0;
7572 static const int kNameDescriptorIndex = 1;
7573
7574 // [context]: The context for this function.
7575 inline Context* context();
7576 inline void set_context(Object* context);
7577 inline JSObject* global_proxy();
7578 inline Context* native_context();
7579
7580 static Handle<Object> GetName(Isolate* isolate, Handle<JSFunction> function);
7581 static MaybeHandle<Smi> GetLength(Isolate* isolate,
7582 Handle<JSFunction> function);
7583 static Handle<Context> GetFunctionRealm(Handle<JSFunction> function);
7584
7585 // [code]: The generated code object for this function. Executed
7586 // when the function is invoked, e.g. foo() or new foo(). See
7587 // [[Call]] and [[Construct]] description in ECMA-262, section
7588 // 8.6.2, page 27.
7589 inline Code* code();
7590 inline void set_code(Code* code);
7591 inline void set_code_no_write_barrier(Code* code);
7592 inline void ReplaceCode(Code* code);
7593
7594 // Get the abstract code associated with the function, which will either be
7595 // a Code object or a BytecodeArray.
7596 inline AbstractCode* abstract_code();
7597
7598 // Tells whether this function inlines the given shared function info.
7599 bool Inlines(SharedFunctionInfo* candidate);
7600
7601 // Tells whether or not this function has been optimized.
7602 inline bool IsOptimized();
7603
7604 // Mark this function for lazy recompilation. The function will be recompiled
7605 // the next time it is executed.
7606 void MarkForBaseline();
7607 void MarkForOptimization();
7608 void AttemptConcurrentOptimization();
7609
7610 // Tells whether or not the function is already marked for lazy recompilation.
7611 inline bool IsMarkedForBaseline();
7612 inline bool IsMarkedForOptimization();
7613 inline bool IsMarkedForConcurrentOptimization();
7614
7615 // Tells whether or not the function is on the concurrent recompilation queue.
7616 inline bool IsInOptimizationQueue();
7617
7618 // Completes inobject slack tracking on initial map if it is active.
7619 inline void CompleteInobjectSlackTrackingIfActive();
7620
7621 // [literals]: Fixed array holding the materialized literals.
7622 //
7623 // If the function contains object, regexp or array literals, the
7624 // literals array prefix contains the object, regexp, and array
7625 // function to be used when creating these literals. This is
7626 // necessary so that we do not dynamically lookup the object, regexp
7627 // or array functions. Performing a dynamic lookup, we might end up
7628 // using the functions from a new context that we should not have
7629 // access to.
7630 DECL_ACCESSORS(literals, LiteralsArray)
7631
7632 static void EnsureLiterals(Handle<JSFunction> function);
7633 inline TypeFeedbackVector* feedback_vector();
7634
7635 // Unconditionally clear the type feedback vector (including vector ICs).
7636 void ClearTypeFeedbackInfo();
7637
7638 // Clear the type feedback vector with a more subtle policy at GC time.
7639 void ClearTypeFeedbackInfoAtGCTime();
7640
7641 // The initial map for an object created by this constructor.
7642 inline Map* initial_map();
7643 static void SetInitialMap(Handle<JSFunction> function, Handle<Map> map,
7644 Handle<Object> prototype);
7645 inline bool has_initial_map();
7646 static void EnsureHasInitialMap(Handle<JSFunction> function);
7647
7648 // Creates a map that matches the constructor's initial map, but with
7649 // [[prototype]] being new.target.prototype. Because new.target can be a
7650 // JSProxy, this can call back into JavaScript.
7651 static MUST_USE_RESULT MaybeHandle<Map> GetDerivedMap(
7652 Isolate* isolate, Handle<JSFunction> constructor,
7653 Handle<JSReceiver> new_target);
7654
7655 // Get and set the prototype property on a JSFunction. If the
7656 // function has an initial map the prototype is set on the initial
7657 // map. Otherwise, the prototype is put in the initial map field
7658 // until an initial map is needed.
7659 inline bool has_prototype();
7660 inline bool has_instance_prototype();
7661 inline Object* prototype();
7662 inline Object* instance_prototype();
7663 static void SetPrototype(Handle<JSFunction> function,
7664 Handle<Object> value);
7665 static void SetInstancePrototype(Handle<JSFunction> function,
7666 Handle<Object> value);
7667
7668 // After prototype is removed, it will not be created when accessed, and
7669 // [[Construct]] from this function will not be allowed.
7670 bool RemovePrototype();
7671
7672 // Returns if this function has been compiled to native code yet.
7673 inline bool is_compiled();
7674
7675 // [next_function_link]: Links functions into various lists, e.g. the list
7676 // of optimized functions hanging off the native_context. The CodeFlusher
7677 // uses this link to chain together flushing candidates. Treated weakly
7678 // by the garbage collector.
7679 DECL_ACCESSORS(next_function_link, Object)
7680
7681 // Prints the name of the function using PrintF.
7682 void PrintName(FILE* out = stdout);
7683
7684 DECLARE_CAST(JSFunction)
7685
7686 // Calculate the instance size and in-object properties count.
7687 void CalculateInstanceSize(InstanceType instance_type,
7688 int requested_internal_fields, int* instance_size,
7689 int* in_object_properties);
7690 void CalculateInstanceSizeForDerivedClass(InstanceType instance_type,
7691 int requested_internal_fields,
7692 int* instance_size,
7693 int* in_object_properties);
7694 static void CalculateInstanceSizeHelper(InstanceType instance_type,
7695 int requested_internal_fields,
7696 int requested_in_object_properties,
7697 int* instance_size,
7698 int* in_object_properties);
7699 // Visiting policy flags define whether the code entry or next function
7700 // should be visited or not.
7701 enum BodyVisitingPolicy {
7702 kVisitCodeEntry = 1 << 0,
7703 kVisitNextFunction = 1 << 1,
7704
7705 kSkipCodeEntryAndNextFunction = 0,
7706 kVisitCodeEntryAndNextFunction = kVisitCodeEntry | kVisitNextFunction
7707 };
7708 // Iterates the function object according to the visiting policy.
7709 template <BodyVisitingPolicy>
7710 class BodyDescriptorImpl;
7711
7712 // Visit the whole object.
7713 typedef BodyDescriptorImpl<kVisitCodeEntryAndNextFunction> BodyDescriptor;
7714
7715 // Don't visit next function.
7716 typedef BodyDescriptorImpl<kVisitCodeEntry> BodyDescriptorStrongCode;
7717 typedef BodyDescriptorImpl<kSkipCodeEntryAndNextFunction>
7718 BodyDescriptorWeakCode;
7719
7720 // Dispatched behavior.
7721 DECLARE_PRINTER(JSFunction)
7722 DECLARE_VERIFIER(JSFunction)
7723
7724 // The function's name if it is configured, otherwise shared function info
7725 // debug name.
7726 static Handle<String> GetName(Handle<JSFunction> function);
7727
7728 // ES6 section 9.2.11 SetFunctionName
7729 // Because of the way this abstract operation is used in the spec,
7730 // it should never fail.
7731 static void SetName(Handle<JSFunction> function, Handle<Name> name,
7732 Handle<String> prefix);
7733
7734 // The function's displayName if it is set, otherwise name if it is
7735 // configured, otherwise shared function info
7736 // debug name.
7737 static Handle<String> GetDebugName(Handle<JSFunction> function);
7738
7739 // The function's string representation implemented according to
7740 // ES6 section 19.2.3.5 Function.prototype.toString ( ).
7741 static Handle<String> ToString(Handle<JSFunction> function);
7742
7743 // Layout descriptors. The last property (from kNonWeakFieldsEndOffset to
7744 // kSize) is weak and has special handling during garbage collection.
7745 static const int kPrototypeOrInitialMapOffset = JSObject::kHeaderSize;
7746 static const int kSharedFunctionInfoOffset =
7747 kPrototypeOrInitialMapOffset + kPointerSize;
7748 static const int kContextOffset = kSharedFunctionInfoOffset + kPointerSize;
7749 static const int kLiteralsOffset = kContextOffset + kPointerSize;
7750 static const int kNonWeakFieldsEndOffset = kLiteralsOffset + kPointerSize;
7751 static const int kCodeEntryOffset = kNonWeakFieldsEndOffset;
7752 static const int kNextFunctionLinkOffset = kCodeEntryOffset + kPointerSize;
7753 static const int kSize = kNextFunctionLinkOffset + kPointerSize;
7754
7755 private:
7756 DISALLOW_IMPLICIT_CONSTRUCTORS(JSFunction);
7757 };
7758
7759
7760 // JSGlobalProxy's prototype must be a JSGlobalObject or null,
7761 // and the prototype is hidden. JSGlobalProxy always delegates
7762 // property accesses to its prototype if the prototype is not null.
7763 //
7764 // A JSGlobalProxy can be reinitialized which will preserve its identity.
7765 //
7766 // Accessing a JSGlobalProxy requires security check.
7767
7768 class JSGlobalProxy : public JSObject {
7769 public:
7770 // [native_context]: the owner native context of this global proxy object.
7771 // It is null value if this object is not used by any context.
7772 DECL_ACCESSORS(native_context, Object)
7773
7774 // [hash]: The hash code property (undefined if not initialized yet).
7775 DECL_ACCESSORS(hash, Object)
7776
7777 DECLARE_CAST(JSGlobalProxy)
7778
7779 inline bool IsDetachedFrom(JSGlobalObject* global) const;
7780
7781 // Dispatched behavior.
7782 DECLARE_PRINTER(JSGlobalProxy)
7783 DECLARE_VERIFIER(JSGlobalProxy)
7784
7785 // Layout description.
7786 static const int kNativeContextOffset = JSObject::kHeaderSize;
7787 static const int kHashOffset = kNativeContextOffset + kPointerSize;
7788 static const int kSize = kHashOffset + kPointerSize;
7789
7790 private:
7791 DISALLOW_IMPLICIT_CONSTRUCTORS(JSGlobalProxy);
7792 };
7793
7794
7795 // JavaScript global object.
7796 class JSGlobalObject : public JSObject {
7797 public:
7798 // [native context]: the natives corresponding to this global object.
7799 DECL_ACCESSORS(native_context, Context)
7800
7801 // [global proxy]: the global proxy object of the context
7802 DECL_ACCESSORS(global_proxy, JSObject)
7803
7804
7805 static void InvalidatePropertyCell(Handle<JSGlobalObject> object,
7806 Handle<Name> name);
7807 // Ensure that the global object has a cell for the given property name.
7808 static Handle<PropertyCell> EnsurePropertyCell(Handle<JSGlobalObject> global,
7809 Handle<Name> name);
7810
7811 DECLARE_CAST(JSGlobalObject)
7812
7813 inline bool IsDetached();
7814
7815 // Dispatched behavior.
7816 DECLARE_PRINTER(JSGlobalObject)
7817 DECLARE_VERIFIER(JSGlobalObject)
7818
7819 // Layout description.
7820 static const int kNativeContextOffset = JSObject::kHeaderSize;
7821 static const int kGlobalProxyOffset = kNativeContextOffset + kPointerSize;
7822 static const int kHeaderSize = kGlobalProxyOffset + kPointerSize;
7823 static const int kSize = kHeaderSize;
7824
7825 private:
7826 DISALLOW_IMPLICIT_CONSTRUCTORS(JSGlobalObject);
7827 };
7828
7829
7830 // Representation for JS Wrapper objects, String, Number, Boolean, etc.
7831 class JSValue: public JSObject {
7832 public:
7833 // [value]: the object being wrapped.
7834 DECL_ACCESSORS(value, Object)
7835
7836 DECLARE_CAST(JSValue)
7837
7838 // Dispatched behavior.
7839 DECLARE_PRINTER(JSValue)
7840 DECLARE_VERIFIER(JSValue)
7841
7842 // Layout description.
7843 static const int kValueOffset = JSObject::kHeaderSize;
7844 static const int kSize = kValueOffset + kPointerSize;
7845
7846 private:
7847 DISALLOW_IMPLICIT_CONSTRUCTORS(JSValue);
7848 };
7849
7850
7851 class DateCache;
7852
7853 // Representation for JS date objects.
7854 class JSDate: public JSObject {
7855 public:
7856 static MUST_USE_RESULT MaybeHandle<JSDate> New(Handle<JSFunction> constructor,
7857 Handle<JSReceiver> new_target,
7858 double tv);
7859
7860 // If one component is NaN, all of them are, indicating a NaN time value.
7861 // [value]: the time value.
7862 DECL_ACCESSORS(value, Object)
7863 // [year]: caches year. Either undefined, smi, or NaN.
7864 DECL_ACCESSORS(year, Object)
7865 // [month]: caches month. Either undefined, smi, or NaN.
7866 DECL_ACCESSORS(month, Object)
7867 // [day]: caches day. Either undefined, smi, or NaN.
7868 DECL_ACCESSORS(day, Object)
7869 // [weekday]: caches day of week. Either undefined, smi, or NaN.
7870 DECL_ACCESSORS(weekday, Object)
7871 // [hour]: caches hours. Either undefined, smi, or NaN.
7872 DECL_ACCESSORS(hour, Object)
7873 // [min]: caches minutes. Either undefined, smi, or NaN.
7874 DECL_ACCESSORS(min, Object)
7875 // [sec]: caches seconds. Either undefined, smi, or NaN.
7876 DECL_ACCESSORS(sec, Object)
7877 // [cache stamp]: sample of the date cache stamp at the
7878 // moment when chached fields were cached.
7879 DECL_ACCESSORS(cache_stamp, Object)
7880
7881 DECLARE_CAST(JSDate)
7882
7883 // Returns the time value (UTC) identifying the current time.
7884 static double CurrentTimeValue(Isolate* isolate);
7885
7886 // Returns the date field with the specified index.
7887 // See FieldIndex for the list of date fields.
7888 static Object* GetField(Object* date, Smi* index);
7889
7890 static Handle<Object> SetValue(Handle<JSDate> date, double v);
7891
7892 void SetValue(Object* value, bool is_value_nan);
7893
7894 // ES6 section 20.3.4.45 Date.prototype [ @@toPrimitive ]
7895 static MUST_USE_RESULT MaybeHandle<Object> ToPrimitive(
7896 Handle<JSReceiver> receiver, Handle<Object> hint);
7897
7898 // Dispatched behavior.
7899 DECLARE_PRINTER(JSDate)
7900 DECLARE_VERIFIER(JSDate)
7901
7902 // The order is important. It must be kept in sync with date macros
7903 // in macros.py.
7904 enum FieldIndex {
7905 kDateValue,
7906 kYear,
7907 kMonth,
7908 kDay,
7909 kWeekday,
7910 kHour,
7911 kMinute,
7912 kSecond,
7913 kFirstUncachedField,
7914 kMillisecond = kFirstUncachedField,
7915 kDays,
7916 kTimeInDay,
7917 kFirstUTCField,
7918 kYearUTC = kFirstUTCField,
7919 kMonthUTC,
7920 kDayUTC,
7921 kWeekdayUTC,
7922 kHourUTC,
7923 kMinuteUTC,
7924 kSecondUTC,
7925 kMillisecondUTC,
7926 kDaysUTC,
7927 kTimeInDayUTC,
7928 kTimezoneOffset
7929 };
7930
7931 // Layout description.
7932 static const int kValueOffset = JSObject::kHeaderSize;
7933 static const int kYearOffset = kValueOffset + kPointerSize;
7934 static const int kMonthOffset = kYearOffset + kPointerSize;
7935 static const int kDayOffset = kMonthOffset + kPointerSize;
7936 static const int kWeekdayOffset = kDayOffset + kPointerSize;
7937 static const int kHourOffset = kWeekdayOffset + kPointerSize;
7938 static const int kMinOffset = kHourOffset + kPointerSize;
7939 static const int kSecOffset = kMinOffset + kPointerSize;
7940 static const int kCacheStampOffset = kSecOffset + kPointerSize;
7941 static const int kSize = kCacheStampOffset + kPointerSize;
7942
7943 private:
7944 inline Object* DoGetField(FieldIndex index);
7945
7946 Object* GetUTCField(FieldIndex index, double value, DateCache* date_cache);
7947
7948 // Computes and caches the cacheable fields of the date.
7949 inline void SetCachedFields(int64_t local_time_ms, DateCache* date_cache);
7950
7951
7952 DISALLOW_IMPLICIT_CONSTRUCTORS(JSDate);
7953 };
7954
7955
7956 // Representation of message objects used for error reporting through
7957 // the API. The messages are formatted in JavaScript so this object is
7958 // a real JavaScript object. The information used for formatting the
7959 // error messages are not directly accessible from JavaScript to
7960 // prevent leaking information to user code called during error
7961 // formatting.
7962 class JSMessageObject: public JSObject {
7963 public:
7964 // [type]: the type of error message.
7965 inline int type() const;
7966 inline void set_type(int value);
7967
7968 // [arguments]: the arguments for formatting the error message.
7969 DECL_ACCESSORS(argument, Object)
7970
7971 // [script]: the script from which the error message originated.
7972 DECL_ACCESSORS(script, Object)
7973
7974 // [stack_frames]: an array of stack frames for this error object.
7975 DECL_ACCESSORS(stack_frames, Object)
7976
7977 // [start_position]: the start position in the script for the error message.
7978 inline int start_position() const;
7979 inline void set_start_position(int value);
7980
7981 // [end_position]: the end position in the script for the error message.
7982 inline int end_position() const;
7983 inline void set_end_position(int value);
7984
7985 DECLARE_CAST(JSMessageObject)
7986
7987 // Dispatched behavior.
7988 DECLARE_PRINTER(JSMessageObject)
7989 DECLARE_VERIFIER(JSMessageObject)
7990
7991 // Layout description.
7992 static const int kTypeOffset = JSObject::kHeaderSize;
7993 static const int kArgumentsOffset = kTypeOffset + kPointerSize;
7994 static const int kScriptOffset = kArgumentsOffset + kPointerSize;
7995 static const int kStackFramesOffset = kScriptOffset + kPointerSize;
7996 static const int kStartPositionOffset = kStackFramesOffset + kPointerSize;
7997 static const int kEndPositionOffset = kStartPositionOffset + kPointerSize;
7998 static const int kSize = kEndPositionOffset + kPointerSize;
7999
8000 typedef FixedBodyDescriptor<HeapObject::kMapOffset,
8001 kStackFramesOffset + kPointerSize,
8002 kSize> BodyDescriptor;
8003 };
8004
8005
8006 // Regular expressions
8007 // The regular expression holds a single reference to a FixedArray in
8008 // the kDataOffset field.
8009 // The FixedArray contains the following data:
8010 // - tag : type of regexp implementation (not compiled yet, atom or irregexp)
8011 // - reference to the original source string
8012 // - reference to the original flag string
8013 // If it is an atom regexp
8014 // - a reference to a literal string to search for
8015 // If it is an irregexp regexp:
8016 // - a reference to code for Latin1 inputs (bytecode or compiled), or a smi
8017 // used for tracking the last usage (used for code flushing).
8018 // - a reference to code for UC16 inputs (bytecode or compiled), or a smi
8019 // used for tracking the last usage (used for code flushing)..
8020 // - max number of registers used by irregexp implementations.
8021 // - number of capture registers (output values) of the regexp.
8022 class JSRegExp: public JSObject {
8023 public:
8024 // Meaning of Type:
8025 // NOT_COMPILED: Initial value. No data has been stored in the JSRegExp yet.
8026 // ATOM: A simple string to match against using an indexOf operation.
8027 // IRREGEXP: Compiled with Irregexp.
8028 enum Type { NOT_COMPILED, ATOM, IRREGEXP };
8029 enum Flag {
8030 kNone = 0,
8031 kGlobal = 1 << 0,
8032 kIgnoreCase = 1 << 1,
8033 kMultiline = 1 << 2,
8034 kSticky = 1 << 3,
8035 kUnicode = 1 << 4,
8036 };
8037 typedef base::Flags<Flag> Flags;
8038
8039 DECL_ACCESSORS(data, Object)
8040 DECL_ACCESSORS(flags, Object)
8041 DECL_ACCESSORS(source, Object)
8042
8043 static MaybeHandle<JSRegExp> New(Handle<String> source, Flags flags);
8044 static Handle<JSRegExp> Copy(Handle<JSRegExp> regexp);
8045
8046 static MaybeHandle<JSRegExp> Initialize(Handle<JSRegExp> regexp,
8047 Handle<String> source, Flags flags);
8048 static MaybeHandle<JSRegExp> Initialize(Handle<JSRegExp> regexp,
8049 Handle<String> source,
8050 Handle<String> flags_string);
8051
8052 inline Type TypeTag();
8053 inline int CaptureCount();
8054 inline Flags GetFlags();
8055 inline String* Pattern();
8056 inline Object* DataAt(int index);
8057 // Set implementation data after the object has been prepared.
8058 inline void SetDataAt(int index, Object* value);
8059
code_index(bool is_latin1)8060 static int code_index(bool is_latin1) {
8061 if (is_latin1) {
8062 return kIrregexpLatin1CodeIndex;
8063 } else {
8064 return kIrregexpUC16CodeIndex;
8065 }
8066 }
8067
saved_code_index(bool is_latin1)8068 static int saved_code_index(bool is_latin1) {
8069 if (is_latin1) {
8070 return kIrregexpLatin1CodeSavedIndex;
8071 } else {
8072 return kIrregexpUC16CodeSavedIndex;
8073 }
8074 }
8075
8076 DECLARE_CAST(JSRegExp)
8077
8078 // Dispatched behavior.
8079 DECLARE_PRINTER(JSRegExp)
8080 DECLARE_VERIFIER(JSRegExp)
8081
8082 static const int kDataOffset = JSObject::kHeaderSize;
8083 static const int kSourceOffset = kDataOffset + kPointerSize;
8084 static const int kFlagsOffset = kSourceOffset + kPointerSize;
8085 static const int kSize = kFlagsOffset + kPointerSize;
8086
8087 // Indices in the data array.
8088 static const int kTagIndex = 0;
8089 static const int kSourceIndex = kTagIndex + 1;
8090 static const int kFlagsIndex = kSourceIndex + 1;
8091 static const int kDataIndex = kFlagsIndex + 1;
8092 // The data fields are used in different ways depending on the
8093 // value of the tag.
8094 // Atom regexps (literal strings).
8095 static const int kAtomPatternIndex = kDataIndex;
8096
8097 static const int kAtomDataSize = kAtomPatternIndex + 1;
8098
8099 // Irregexp compiled code or bytecode for Latin1. If compilation
8100 // fails, this fields hold an exception object that should be
8101 // thrown if the regexp is used again.
8102 static const int kIrregexpLatin1CodeIndex = kDataIndex;
8103 // Irregexp compiled code or bytecode for UC16. If compilation
8104 // fails, this fields hold an exception object that should be
8105 // thrown if the regexp is used again.
8106 static const int kIrregexpUC16CodeIndex = kDataIndex + 1;
8107
8108 // Saved instance of Irregexp compiled code or bytecode for Latin1 that
8109 // is a potential candidate for flushing.
8110 static const int kIrregexpLatin1CodeSavedIndex = kDataIndex + 2;
8111 // Saved instance of Irregexp compiled code or bytecode for UC16 that is
8112 // a potential candidate for flushing.
8113 static const int kIrregexpUC16CodeSavedIndex = kDataIndex + 3;
8114
8115 // Maximal number of registers used by either Latin1 or UC16.
8116 // Only used to check that there is enough stack space
8117 static const int kIrregexpMaxRegisterCountIndex = kDataIndex + 4;
8118 // Number of captures in the compiled regexp.
8119 static const int kIrregexpCaptureCountIndex = kDataIndex + 5;
8120 // Maps names of named capture groups (at indices 2i) to their corresponding
8121 // capture group indices (at indices 2i + 1).
8122 static const int kIrregexpCaptureNameMapIndex = kDataIndex + 6;
8123
8124 static const int kIrregexpDataSize = kIrregexpCaptureNameMapIndex + 1;
8125
8126 // Offsets directly into the data fixed array.
8127 static const int kDataTagOffset =
8128 FixedArray::kHeaderSize + kTagIndex * kPointerSize;
8129 static const int kDataOneByteCodeOffset =
8130 FixedArray::kHeaderSize + kIrregexpLatin1CodeIndex * kPointerSize;
8131 static const int kDataUC16CodeOffset =
8132 FixedArray::kHeaderSize + kIrregexpUC16CodeIndex * kPointerSize;
8133 static const int kIrregexpCaptureCountOffset =
8134 FixedArray::kHeaderSize + kIrregexpCaptureCountIndex * kPointerSize;
8135
8136 // In-object fields.
8137 static const int kLastIndexFieldIndex = 0;
8138 static const int kInObjectFieldCount = 1;
8139
8140 // The uninitialized value for a regexp code object.
8141 static const int kUninitializedValue = -1;
8142
8143 // The compilation error value for the regexp code object. The real error
8144 // object is in the saved code field.
8145 static const int kCompilationErrorValue = -2;
8146
8147 // When we store the sweep generation at which we moved the code from the
8148 // code index to the saved code index we mask it of to be in the [0:255]
8149 // range.
8150 static const int kCodeAgeMask = 0xff;
8151 };
8152
DEFINE_OPERATORS_FOR_FLAGS(JSRegExp::Flags)8153 DEFINE_OPERATORS_FOR_FLAGS(JSRegExp::Flags)
8154
8155
8156 class CompilationCacheShape : public BaseShape<HashTableKey*> {
8157 public:
8158 static inline bool IsMatch(HashTableKey* key, Object* value) {
8159 return key->IsMatch(value);
8160 }
8161
8162 static inline uint32_t Hash(HashTableKey* key) {
8163 return key->Hash();
8164 }
8165
8166 static inline uint32_t HashForObject(HashTableKey* key, Object* object) {
8167 return key->HashForObject(object);
8168 }
8169
8170 static inline Handle<Object> AsHandle(Isolate* isolate, HashTableKey* key);
8171
8172 static const int kPrefixSize = 0;
8173 static const int kEntrySize = 2;
8174 };
8175
8176
8177 // This cache is used in two different variants. For regexp caching, it simply
8178 // maps identifying info of the regexp to the cached regexp object. Scripts and
8179 // eval code only gets cached after a second probe for the code object. To do
8180 // so, on first "put" only a hash identifying the source is entered into the
8181 // cache, mapping it to a lifetime count of the hash. On each call to Age all
8182 // such lifetimes get reduced, and removed once they reach zero. If a second put
8183 // is called while such a hash is live in the cache, the hash gets replaced by
8184 // an actual cache entry. Age also removes stale live entries from the cache.
8185 // Such entries are identified by SharedFunctionInfos pointing to either the
8186 // recompilation stub, or to "old" code. This avoids memory leaks due to
8187 // premature caching of scripts and eval strings that are never needed later.
8188 class CompilationCacheTable: public HashTable<CompilationCacheTable,
8189 CompilationCacheShape,
8190 HashTableKey*> {
8191 public:
8192 // Find cached value for a string key, otherwise return null.
8193 Handle<Object> Lookup(
8194 Handle<String> src, Handle<Context> context, LanguageMode language_mode);
8195 Handle<Object> LookupEval(
8196 Handle<String> src, Handle<SharedFunctionInfo> shared,
8197 LanguageMode language_mode, int scope_position);
8198 Handle<Object> LookupRegExp(Handle<String> source, JSRegExp::Flags flags);
8199 static Handle<CompilationCacheTable> Put(
8200 Handle<CompilationCacheTable> cache, Handle<String> src,
8201 Handle<Context> context, LanguageMode language_mode,
8202 Handle<Object> value);
8203 static Handle<CompilationCacheTable> PutEval(
8204 Handle<CompilationCacheTable> cache, Handle<String> src,
8205 Handle<SharedFunctionInfo> context, Handle<SharedFunctionInfo> value,
8206 int scope_position);
8207 static Handle<CompilationCacheTable> PutRegExp(
8208 Handle<CompilationCacheTable> cache, Handle<String> src,
8209 JSRegExp::Flags flags, Handle<FixedArray> value);
8210 void Remove(Object* value);
8211 void Age();
8212 static const int kHashGenerations = 10;
8213
8214 DECLARE_CAST(CompilationCacheTable)
8215
8216 private:
8217 DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationCacheTable);
8218 };
8219
8220
8221 class CodeCacheHashTableShape : public BaseShape<HashTableKey*> {
8222 public:
IsMatch(HashTableKey * key,Object * value)8223 static inline bool IsMatch(HashTableKey* key, Object* value) {
8224 return key->IsMatch(value);
8225 }
8226
Hash(HashTableKey * key)8227 static inline uint32_t Hash(HashTableKey* key) {
8228 return key->Hash();
8229 }
8230
HashForObject(HashTableKey * key,Object * object)8231 static inline uint32_t HashForObject(HashTableKey* key, Object* object) {
8232 return key->HashForObject(object);
8233 }
8234
8235 static inline Handle<Object> AsHandle(Isolate* isolate, HashTableKey* key);
8236
8237 static const int kPrefixSize = 0;
8238 // The both the key (name + flags) and value (code object) can be derived from
8239 // the fixed array that stores both the name and code.
8240 // TODO(verwaest): Don't allocate a fixed array but inline name and code.
8241 // Rewrite IsMatch to get table + index as input rather than just the raw key.
8242 static const int kEntrySize = 1;
8243 };
8244
8245
8246 class CodeCacheHashTable: public HashTable<CodeCacheHashTable,
8247 CodeCacheHashTableShape,
8248 HashTableKey*> {
8249 public:
8250 static Handle<CodeCacheHashTable> Put(
8251 Handle<CodeCacheHashTable> table,
8252 Handle<Name> name,
8253 Handle<Code> code);
8254
8255 Code* Lookup(Name* name, Code::Flags flags);
8256
8257 DECLARE_CAST(CodeCacheHashTable)
8258
8259 private:
8260 DISALLOW_IMPLICIT_CONSTRUCTORS(CodeCacheHashTable);
8261 };
8262
8263
8264 class TypeFeedbackInfo: public Struct {
8265 public:
8266 inline int ic_total_count();
8267 inline void set_ic_total_count(int count);
8268
8269 inline int ic_with_type_info_count();
8270 inline void change_ic_with_type_info_count(int delta);
8271
8272 inline int ic_generic_count();
8273 inline void change_ic_generic_count(int delta);
8274
8275 inline void initialize_storage();
8276
8277 inline void change_own_type_change_checksum();
8278 inline int own_type_change_checksum();
8279
8280 inline void set_inlined_type_change_checksum(int checksum);
8281 inline bool matches_inlined_type_change_checksum(int checksum);
8282
8283 DECLARE_CAST(TypeFeedbackInfo)
8284
8285 // Dispatched behavior.
8286 DECLARE_PRINTER(TypeFeedbackInfo)
8287 DECLARE_VERIFIER(TypeFeedbackInfo)
8288
8289 static const int kStorage1Offset = HeapObject::kHeaderSize;
8290 static const int kStorage2Offset = kStorage1Offset + kPointerSize;
8291 static const int kStorage3Offset = kStorage2Offset + kPointerSize;
8292 static const int kSize = kStorage3Offset + kPointerSize;
8293
8294 private:
8295 static const int kTypeChangeChecksumBits = 7;
8296
8297 class ICTotalCountField: public BitField<int, 0,
8298 kSmiValueSize - kTypeChangeChecksumBits> {}; // NOLINT
8299 class OwnTypeChangeChecksum: public BitField<int,
8300 kSmiValueSize - kTypeChangeChecksumBits,
8301 kTypeChangeChecksumBits> {}; // NOLINT
8302 class ICsWithTypeInfoCountField: public BitField<int, 0,
8303 kSmiValueSize - kTypeChangeChecksumBits> {}; // NOLINT
8304 class InlinedTypeChangeChecksum: public BitField<int,
8305 kSmiValueSize - kTypeChangeChecksumBits,
8306 kTypeChangeChecksumBits> {}; // NOLINT
8307
8308 DISALLOW_IMPLICIT_CONSTRUCTORS(TypeFeedbackInfo);
8309 };
8310
8311
8312 enum AllocationSiteMode {
8313 DONT_TRACK_ALLOCATION_SITE,
8314 TRACK_ALLOCATION_SITE,
8315 LAST_ALLOCATION_SITE_MODE = TRACK_ALLOCATION_SITE
8316 };
8317
8318
8319 class AllocationSite: public Struct {
8320 public:
8321 static const uint32_t kMaximumArrayBytesToPretransition = 8 * 1024;
8322 static const double kPretenureRatio;
8323 static const int kPretenureMinimumCreated = 100;
8324
8325 // Values for pretenure decision field.
8326 enum PretenureDecision {
8327 kUndecided = 0,
8328 kDontTenure = 1,
8329 kMaybeTenure = 2,
8330 kTenure = 3,
8331 kZombie = 4,
8332 kLastPretenureDecisionValue = kZombie
8333 };
8334
8335 const char* PretenureDecisionName(PretenureDecision decision);
8336
8337 DECL_ACCESSORS(transition_info, Object)
8338 // nested_site threads a list of sites that represent nested literals
8339 // walked in a particular order. So [[1, 2], 1, 2] will have one
8340 // nested_site, but [[1, 2], 3, [4]] will have a list of two.
8341 DECL_ACCESSORS(nested_site, Object)
8342 DECL_INT_ACCESSORS(pretenure_data)
8343 DECL_INT_ACCESSORS(pretenure_create_count)
8344 DECL_ACCESSORS(dependent_code, DependentCode)
8345 DECL_ACCESSORS(weak_next, Object)
8346
8347 inline void Initialize();
8348
8349 // This method is expensive, it should only be called for reporting.
8350 bool IsNestedSite();
8351
8352 // transition_info bitfields, for constructed array transition info.
8353 class ElementsKindBits: public BitField<ElementsKind, 0, 15> {};
8354 class UnusedBits: public BitField<int, 15, 14> {};
8355 class DoNotInlineBit: public BitField<bool, 29, 1> {};
8356
8357 // Bitfields for pretenure_data
8358 class MementoFoundCountBits: public BitField<int, 0, 26> {};
8359 class PretenureDecisionBits: public BitField<PretenureDecision, 26, 3> {};
8360 class DeoptDependentCodeBit: public BitField<bool, 29, 1> {};
8361 STATIC_ASSERT(PretenureDecisionBits::kMax >= kLastPretenureDecisionValue);
8362
8363 // Increments the mementos found counter and returns true when the first
8364 // memento was found for a given allocation site.
8365 inline bool IncrementMementoFoundCount(int increment = 1);
8366
8367 inline void IncrementMementoCreateCount();
8368
8369 PretenureFlag GetPretenureMode();
8370
8371 void ResetPretenureDecision();
8372
8373 inline PretenureDecision pretenure_decision();
8374 inline void set_pretenure_decision(PretenureDecision decision);
8375
8376 inline bool deopt_dependent_code();
8377 inline void set_deopt_dependent_code(bool deopt);
8378
8379 inline int memento_found_count();
8380 inline void set_memento_found_count(int count);
8381
8382 inline int memento_create_count();
8383 inline void set_memento_create_count(int count);
8384
8385 // The pretenuring decision is made during gc, and the zombie state allows
8386 // us to recognize when an allocation site is just being kept alive because
8387 // a later traversal of new space may discover AllocationMementos that point
8388 // to this AllocationSite.
8389 inline bool IsZombie();
8390
8391 inline bool IsMaybeTenure();
8392
8393 inline void MarkZombie();
8394
8395 inline bool MakePretenureDecision(PretenureDecision current_decision,
8396 double ratio,
8397 bool maximum_size_scavenge);
8398
8399 inline bool DigestPretenuringFeedback(bool maximum_size_scavenge);
8400
8401 inline ElementsKind GetElementsKind();
8402 inline void SetElementsKind(ElementsKind kind);
8403
8404 inline bool CanInlineCall();
8405 inline void SetDoNotInlineCall();
8406
8407 inline bool SitePointsToLiteral();
8408
8409 static void DigestTransitionFeedback(Handle<AllocationSite> site,
8410 ElementsKind to_kind);
8411
8412 DECLARE_PRINTER(AllocationSite)
8413 DECLARE_VERIFIER(AllocationSite)
8414
8415 DECLARE_CAST(AllocationSite)
8416 static inline AllocationSiteMode GetMode(
8417 ElementsKind boilerplate_elements_kind);
8418 static inline AllocationSiteMode GetMode(ElementsKind from, ElementsKind to);
8419 static inline bool CanTrack(InstanceType type);
8420
8421 static const int kTransitionInfoOffset = HeapObject::kHeaderSize;
8422 static const int kNestedSiteOffset = kTransitionInfoOffset + kPointerSize;
8423 static const int kPretenureDataOffset = kNestedSiteOffset + kPointerSize;
8424 static const int kPretenureCreateCountOffset =
8425 kPretenureDataOffset + kPointerSize;
8426 static const int kDependentCodeOffset =
8427 kPretenureCreateCountOffset + kPointerSize;
8428 static const int kWeakNextOffset = kDependentCodeOffset + kPointerSize;
8429 static const int kSize = kWeakNextOffset + kPointerSize;
8430
8431 // During mark compact we need to take special care for the dependent code
8432 // field.
8433 static const int kPointerFieldsBeginOffset = kTransitionInfoOffset;
8434 static const int kPointerFieldsEndOffset = kWeakNextOffset;
8435
8436 // For other visitors, use the fixed body descriptor below.
8437 typedef FixedBodyDescriptor<HeapObject::kHeaderSize, kSize, kSize>
8438 BodyDescriptor;
8439
8440 private:
8441 inline bool PretenuringDecisionMade();
8442
8443 DISALLOW_IMPLICIT_CONSTRUCTORS(AllocationSite);
8444 };
8445
8446
8447 class AllocationMemento: public Struct {
8448 public:
8449 static const int kAllocationSiteOffset = HeapObject::kHeaderSize;
8450 static const int kSize = kAllocationSiteOffset + kPointerSize;
8451
8452 DECL_ACCESSORS(allocation_site, Object)
8453
8454 inline bool IsValid();
8455 inline AllocationSite* GetAllocationSite();
8456 inline Address GetAllocationSiteUnchecked();
8457
8458 DECLARE_PRINTER(AllocationMemento)
8459 DECLARE_VERIFIER(AllocationMemento)
8460
8461 DECLARE_CAST(AllocationMemento)
8462
8463 private:
8464 DISALLOW_IMPLICIT_CONSTRUCTORS(AllocationMemento);
8465 };
8466
8467
8468 // Representation of a slow alias as part of a sloppy arguments objects.
8469 // For fast aliases (if HasSloppyArgumentsElements()):
8470 // - the parameter map contains an index into the context
8471 // - all attributes of the element have default values
8472 // For slow aliases (if HasDictionaryArgumentsElements()):
8473 // - the parameter map contains no fast alias mapping (i.e. the hole)
8474 // - this struct (in the slow backing store) contains an index into the context
8475 // - all attributes are available as part if the property details
8476 class AliasedArgumentsEntry: public Struct {
8477 public:
8478 inline int aliased_context_slot() const;
8479 inline void set_aliased_context_slot(int count);
8480
8481 DECLARE_CAST(AliasedArgumentsEntry)
8482
8483 // Dispatched behavior.
8484 DECLARE_PRINTER(AliasedArgumentsEntry)
8485 DECLARE_VERIFIER(AliasedArgumentsEntry)
8486
8487 static const int kAliasedContextSlot = HeapObject::kHeaderSize;
8488 static const int kSize = kAliasedContextSlot + kPointerSize;
8489
8490 private:
8491 DISALLOW_IMPLICIT_CONSTRUCTORS(AliasedArgumentsEntry);
8492 };
8493
8494
8495 enum AllowNullsFlag {ALLOW_NULLS, DISALLOW_NULLS};
8496 enum RobustnessFlag {ROBUST_STRING_TRAVERSAL, FAST_STRING_TRAVERSAL};
8497
8498
8499 class StringHasher {
8500 public:
8501 explicit inline StringHasher(int length, uint32_t seed);
8502
8503 template <typename schar>
8504 static inline uint32_t HashSequentialString(const schar* chars,
8505 int length,
8506 uint32_t seed);
8507
8508 // Reads all the data, even for long strings and computes the utf16 length.
8509 static uint32_t ComputeUtf8Hash(Vector<const char> chars,
8510 uint32_t seed,
8511 int* utf16_length_out);
8512
8513 // Calculated hash value for a string consisting of 1 to
8514 // String::kMaxArrayIndexSize digits with no leading zeros (except "0").
8515 // value is represented decimal value.
8516 static uint32_t MakeArrayIndexHash(uint32_t value, int length);
8517
8518 // No string is allowed to have a hash of zero. That value is reserved
8519 // for internal properties. If the hash calculation yields zero then we
8520 // use 27 instead.
8521 static const int kZeroHash = 27;
8522
8523 // Reusable parts of the hashing algorithm.
8524 INLINE(static uint32_t AddCharacterCore(uint32_t running_hash, uint16_t c));
8525 INLINE(static uint32_t GetHashCore(uint32_t running_hash));
8526 INLINE(static uint32_t ComputeRunningHash(uint32_t running_hash,
8527 const uc16* chars, int length));
8528 INLINE(static uint32_t ComputeRunningHashOneByte(uint32_t running_hash,
8529 const char* chars,
8530 int length));
8531
8532 protected:
8533 // Returns the value to store in the hash field of a string with
8534 // the given length and contents.
8535 uint32_t GetHashField();
8536 // Returns true if the hash of this string can be computed without
8537 // looking at the contents.
8538 inline bool has_trivial_hash();
8539 // Adds a block of characters to the hash.
8540 template<typename Char>
8541 inline void AddCharacters(const Char* chars, int len);
8542
8543 private:
8544 // Add a character to the hash.
8545 inline void AddCharacter(uint16_t c);
8546 // Update index. Returns true if string is still an index.
8547 inline bool UpdateIndex(uint16_t c);
8548
8549 int length_;
8550 uint32_t raw_running_hash_;
8551 uint32_t array_index_;
8552 bool is_array_index_;
8553 bool is_first_char_;
8554 DISALLOW_COPY_AND_ASSIGN(StringHasher);
8555 };
8556
8557
8558 class IteratingStringHasher : public StringHasher {
8559 public:
8560 static inline uint32_t Hash(String* string, uint32_t seed);
8561 inline void VisitOneByteString(const uint8_t* chars, int length);
8562 inline void VisitTwoByteString(const uint16_t* chars, int length);
8563
8564 private:
8565 inline IteratingStringHasher(int len, uint32_t seed);
8566 void VisitConsString(ConsString* cons_string);
8567 DISALLOW_COPY_AND_ASSIGN(IteratingStringHasher);
8568 };
8569
8570
8571 // The characteristics of a string are stored in its map. Retrieving these
8572 // few bits of information is moderately expensive, involving two memory
8573 // loads where the second is dependent on the first. To improve efficiency
8574 // the shape of the string is given its own class so that it can be retrieved
8575 // once and used for several string operations. A StringShape is small enough
8576 // to be passed by value and is immutable, but be aware that flattening a
8577 // string can potentially alter its shape. Also be aware that a GC caused by
8578 // something else can alter the shape of a string due to ConsString
8579 // shortcutting. Keeping these restrictions in mind has proven to be error-
8580 // prone and so we no longer put StringShapes in variables unless there is a
8581 // concrete performance benefit at that particular point in the code.
8582 class StringShape BASE_EMBEDDED {
8583 public:
8584 inline explicit StringShape(const String* s);
8585 inline explicit StringShape(Map* s);
8586 inline explicit StringShape(InstanceType t);
8587 inline bool IsSequential();
8588 inline bool IsExternal();
8589 inline bool IsCons();
8590 inline bool IsSliced();
8591 inline bool IsIndirect();
8592 inline bool IsExternalOneByte();
8593 inline bool IsExternalTwoByte();
8594 inline bool IsSequentialOneByte();
8595 inline bool IsSequentialTwoByte();
8596 inline bool IsInternalized();
8597 inline StringRepresentationTag representation_tag();
8598 inline uint32_t encoding_tag();
8599 inline uint32_t full_representation_tag();
8600 inline uint32_t size_tag();
8601 #ifdef DEBUG
type()8602 inline uint32_t type() { return type_; }
invalidate()8603 inline void invalidate() { valid_ = false; }
valid()8604 inline bool valid() { return valid_; }
8605 #else
invalidate()8606 inline void invalidate() { }
8607 #endif
8608
8609 private:
8610 uint32_t type_;
8611 #ifdef DEBUG
set_valid()8612 inline void set_valid() { valid_ = true; }
8613 bool valid_;
8614 #else
set_valid()8615 inline void set_valid() { }
8616 #endif
8617 };
8618
8619
8620 // The Name abstract class captures anything that can be used as a property
8621 // name, i.e., strings and symbols. All names store a hash value.
8622 class Name: public HeapObject {
8623 public:
8624 // Get and set the hash field of the name.
8625 inline uint32_t hash_field();
8626 inline void set_hash_field(uint32_t value);
8627
8628 // Tells whether the hash code has been computed.
8629 inline bool HasHashCode();
8630
8631 // Returns a hash value used for the property table
8632 inline uint32_t Hash();
8633
8634 // Equality operations.
8635 inline bool Equals(Name* other);
8636 inline static bool Equals(Handle<Name> one, Handle<Name> two);
8637
8638 // Conversion.
8639 inline bool AsArrayIndex(uint32_t* index);
8640
8641 // If the name is private, it can only name own properties.
8642 inline bool IsPrivate();
8643
8644 inline bool IsUniqueName() const;
8645
8646 // Return a string version of this name that is converted according to the
8647 // rules described in ES6 section 9.2.11.
8648 MUST_USE_RESULT static MaybeHandle<String> ToFunctionName(Handle<Name> name);
8649 MUST_USE_RESULT static MaybeHandle<String> ToFunctionName(
8650 Handle<Name> name, Handle<String> prefix);
8651
8652 DECLARE_CAST(Name)
8653
8654 DECLARE_PRINTER(Name)
8655 #if TRACE_MAPS
8656 void NameShortPrint();
8657 int NameShortPrint(Vector<char> str);
8658 #endif
8659
8660 // Layout description.
8661 static const int kHashFieldSlot = HeapObject::kHeaderSize;
8662 #if V8_TARGET_LITTLE_ENDIAN || !V8_HOST_ARCH_64_BIT
8663 static const int kHashFieldOffset = kHashFieldSlot;
8664 #else
8665 static const int kHashFieldOffset = kHashFieldSlot + kIntSize;
8666 #endif
8667 static const int kSize = kHashFieldSlot + kPointerSize;
8668
8669 // Mask constant for checking if a name has a computed hash code
8670 // and if it is a string that is an array index. The least significant bit
8671 // indicates whether a hash code has been computed. If the hash code has
8672 // been computed the 2nd bit tells whether the string can be used as an
8673 // array index.
8674 static const int kHashNotComputedMask = 1;
8675 static const int kIsNotArrayIndexMask = 1 << 1;
8676 static const int kNofHashBitFields = 2;
8677
8678 // Shift constant retrieving hash code from hash field.
8679 static const int kHashShift = kNofHashBitFields;
8680
8681 // Only these bits are relevant in the hash, since the top two are shifted
8682 // out.
8683 static const uint32_t kHashBitMask = 0xffffffffu >> kHashShift;
8684
8685 // Array index strings this short can keep their index in the hash field.
8686 static const int kMaxCachedArrayIndexLength = 7;
8687
8688 // Maximum number of characters to consider when trying to convert a string
8689 // value into an array index.
8690 static const int kMaxArrayIndexSize = 10;
8691
8692 // For strings which are array indexes the hash value has the string length
8693 // mixed into the hash, mainly to avoid a hash value of zero which would be
8694 // the case for the string '0'. 24 bits are used for the array index value.
8695 static const int kArrayIndexValueBits = 24;
8696 static const int kArrayIndexLengthBits =
8697 kBitsPerInt - kArrayIndexValueBits - kNofHashBitFields;
8698
8699 STATIC_ASSERT(kArrayIndexLengthBits > 0);
8700 STATIC_ASSERT(kMaxArrayIndexSize < (1 << kArrayIndexLengthBits));
8701
8702 class ArrayIndexValueBits : public BitField<unsigned int, kNofHashBitFields,
8703 kArrayIndexValueBits> {}; // NOLINT
8704 class ArrayIndexLengthBits : public BitField<unsigned int,
8705 kNofHashBitFields + kArrayIndexValueBits,
8706 kArrayIndexLengthBits> {}; // NOLINT
8707
8708 // Check that kMaxCachedArrayIndexLength + 1 is a power of two so we
8709 // could use a mask to test if the length of string is less than or equal to
8710 // kMaxCachedArrayIndexLength.
8711 STATIC_ASSERT(IS_POWER_OF_TWO(kMaxCachedArrayIndexLength + 1));
8712
8713 static const unsigned int kContainsCachedArrayIndexMask =
8714 (~static_cast<unsigned>(kMaxCachedArrayIndexLength)
8715 << ArrayIndexLengthBits::kShift) |
8716 kIsNotArrayIndexMask;
8717
8718 // Value of empty hash field indicating that the hash is not computed.
8719 static const int kEmptyHashField =
8720 kIsNotArrayIndexMask | kHashNotComputedMask;
8721
8722 protected:
8723 static inline bool IsHashFieldComputed(uint32_t field);
8724
8725 private:
8726 DISALLOW_IMPLICIT_CONSTRUCTORS(Name);
8727 };
8728
8729
8730 // ES6 symbols.
8731 class Symbol: public Name {
8732 public:
8733 // [name]: The print name of a symbol, or undefined if none.
8734 DECL_ACCESSORS(name, Object)
8735
8736 DECL_INT_ACCESSORS(flags)
8737
8738 // [is_private]: Whether this is a private symbol. Private symbols can only
8739 // be used to designate own properties of objects.
8740 DECL_BOOLEAN_ACCESSORS(is_private)
8741
8742 // [is_well_known_symbol]: Whether this is a spec-defined well-known symbol,
8743 // or not. Well-known symbols do not throw when an access check fails during
8744 // a load.
8745 DECL_BOOLEAN_ACCESSORS(is_well_known_symbol)
8746
8747 DECLARE_CAST(Symbol)
8748
8749 // Dispatched behavior.
8750 DECLARE_PRINTER(Symbol)
8751 DECLARE_VERIFIER(Symbol)
8752
8753 // Layout description.
8754 static const int kNameOffset = Name::kSize;
8755 static const int kFlagsOffset = kNameOffset + kPointerSize;
8756 static const int kSize = kFlagsOffset + kPointerSize;
8757
8758 typedef FixedBodyDescriptor<kNameOffset, kFlagsOffset, kSize> BodyDescriptor;
8759
8760 void SymbolShortPrint(std::ostream& os);
8761
8762 private:
8763 static const int kPrivateBit = 0;
8764 static const int kWellKnownSymbolBit = 1;
8765
8766 const char* PrivateSymbolToName() const;
8767
8768 #if TRACE_MAPS
8769 friend class Name; // For PrivateSymbolToName.
8770 #endif
8771
8772 DISALLOW_IMPLICIT_CONSTRUCTORS(Symbol);
8773 };
8774
8775
8776 class ConsString;
8777
8778 // The String abstract class captures JavaScript string values:
8779 //
8780 // Ecma-262:
8781 // 4.3.16 String Value
8782 // A string value is a member of the type String and is a finite
8783 // ordered sequence of zero or more 16-bit unsigned integer values.
8784 //
8785 // All string values have a length field.
8786 class String: public Name {
8787 public:
8788 enum Encoding { ONE_BYTE_ENCODING, TWO_BYTE_ENCODING };
8789
8790 class SubStringRange {
8791 public:
8792 explicit inline SubStringRange(String* string, int first = 0,
8793 int length = -1);
8794 class iterator;
8795 inline iterator begin();
8796 inline iterator end();
8797
8798 private:
8799 String* string_;
8800 int first_;
8801 int length_;
8802 };
8803
8804 // Representation of the flat content of a String.
8805 // A non-flat string doesn't have flat content.
8806 // A flat string has content that's encoded as a sequence of either
8807 // one-byte chars or two-byte UC16.
8808 // Returned by String::GetFlatContent().
8809 class FlatContent {
8810 public:
8811 // Returns true if the string is flat and this structure contains content.
IsFlat()8812 bool IsFlat() const { return state_ != NON_FLAT; }
8813 // Returns true if the structure contains one-byte content.
IsOneByte()8814 bool IsOneByte() const { return state_ == ONE_BYTE; }
8815 // Returns true if the structure contains two-byte content.
IsTwoByte()8816 bool IsTwoByte() const { return state_ == TWO_BYTE; }
8817
8818 // Return the one byte content of the string. Only use if IsOneByte()
8819 // returns true.
ToOneByteVector()8820 Vector<const uint8_t> ToOneByteVector() const {
8821 DCHECK_EQ(ONE_BYTE, state_);
8822 return Vector<const uint8_t>(onebyte_start, length_);
8823 }
8824 // Return the two-byte content of the string. Only use if IsTwoByte()
8825 // returns true.
ToUC16Vector()8826 Vector<const uc16> ToUC16Vector() const {
8827 DCHECK_EQ(TWO_BYTE, state_);
8828 return Vector<const uc16>(twobyte_start, length_);
8829 }
8830
Get(int i)8831 uc16 Get(int i) const {
8832 DCHECK(i < length_);
8833 DCHECK(state_ != NON_FLAT);
8834 if (state_ == ONE_BYTE) return onebyte_start[i];
8835 return twobyte_start[i];
8836 }
8837
UsesSameString(const FlatContent & other)8838 bool UsesSameString(const FlatContent& other) const {
8839 return onebyte_start == other.onebyte_start;
8840 }
8841
8842 private:
8843 enum State { NON_FLAT, ONE_BYTE, TWO_BYTE };
8844
8845 // Constructors only used by String::GetFlatContent().
FlatContent(const uint8_t * start,int length)8846 explicit FlatContent(const uint8_t* start, int length)
8847 : onebyte_start(start), length_(length), state_(ONE_BYTE) {}
FlatContent(const uc16 * start,int length)8848 explicit FlatContent(const uc16* start, int length)
8849 : twobyte_start(start), length_(length), state_(TWO_BYTE) { }
FlatContent()8850 FlatContent() : onebyte_start(NULL), length_(0), state_(NON_FLAT) { }
8851
8852 union {
8853 const uint8_t* onebyte_start;
8854 const uc16* twobyte_start;
8855 };
8856 int length_;
8857 State state_;
8858
8859 friend class String;
8860 friend class IterableSubString;
8861 };
8862
8863 template <typename Char>
8864 INLINE(Vector<const Char> GetCharVector());
8865
8866 // Get and set the length of the string.
8867 inline int length() const;
8868 inline void set_length(int value);
8869
8870 // Get and set the length of the string using acquire loads and release
8871 // stores.
8872 inline int synchronized_length() const;
8873 inline void synchronized_set_length(int value);
8874
8875 // Returns whether this string has only one-byte chars, i.e. all of them can
8876 // be one-byte encoded. This might be the case even if the string is
8877 // two-byte. Such strings may appear when the embedder prefers
8878 // two-byte external representations even for one-byte data.
8879 inline bool IsOneByteRepresentation() const;
8880 inline bool IsTwoByteRepresentation() const;
8881
8882 // Cons and slices have an encoding flag that may not represent the actual
8883 // encoding of the underlying string. This is taken into account here.
8884 // Requires: this->IsFlat()
8885 inline bool IsOneByteRepresentationUnderneath();
8886 inline bool IsTwoByteRepresentationUnderneath();
8887
8888 // NOTE: this should be considered only a hint. False negatives are
8889 // possible.
8890 inline bool HasOnlyOneByteChars();
8891
8892 // Get and set individual two byte chars in the string.
8893 inline void Set(int index, uint16_t value);
8894 // Get individual two byte char in the string. Repeated calls
8895 // to this method are not efficient unless the string is flat.
8896 INLINE(uint16_t Get(int index));
8897
8898 // ES6 section 7.1.3.1 ToNumber Applied to the String Type
8899 static Handle<Object> ToNumber(Handle<String> subject);
8900
8901 // Flattens the string. Checks first inline to see if it is
8902 // necessary. Does nothing if the string is not a cons string.
8903 // Flattening allocates a sequential string with the same data as
8904 // the given string and mutates the cons string to a degenerate
8905 // form, where the first component is the new sequential string and
8906 // the second component is the empty string. If allocation fails,
8907 // this function returns a failure. If flattening succeeds, this
8908 // function returns the sequential string that is now the first
8909 // component of the cons string.
8910 //
8911 // Degenerate cons strings are handled specially by the garbage
8912 // collector (see IsShortcutCandidate).
8913
8914 static inline Handle<String> Flatten(Handle<String> string,
8915 PretenureFlag pretenure = NOT_TENURED);
8916
8917 // Tries to return the content of a flat string as a structure holding either
8918 // a flat vector of char or of uc16.
8919 // If the string isn't flat, and therefore doesn't have flat content, the
8920 // returned structure will report so, and can't provide a vector of either
8921 // kind.
8922 FlatContent GetFlatContent();
8923
8924 // Returns the parent of a sliced string or first part of a flat cons string.
8925 // Requires: StringShape(this).IsIndirect() && this->IsFlat()
8926 inline String* GetUnderlying();
8927
8928 // String relational comparison, implemented according to ES6 section 7.2.11
8929 // Abstract Relational Comparison (step 5): The comparison of Strings uses a
8930 // simple lexicographic ordering on sequences of code unit values. There is no
8931 // attempt to use the more complex, semantically oriented definitions of
8932 // character or string equality and collating order defined in the Unicode
8933 // specification. Therefore String values that are canonically equal according
8934 // to the Unicode standard could test as unequal. In effect this algorithm
8935 // assumes that both Strings are already in normalized form. Also, note that
8936 // for strings containing supplementary characters, lexicographic ordering on
8937 // sequences of UTF-16 code unit values differs from that on sequences of code
8938 // point values.
8939 MUST_USE_RESULT static ComparisonResult Compare(Handle<String> x,
8940 Handle<String> y);
8941
8942 // String equality operations.
8943 inline bool Equals(String* other);
8944 inline static bool Equals(Handle<String> one, Handle<String> two);
8945 bool IsUtf8EqualTo(Vector<const char> str, bool allow_prefix_match = false);
8946 bool IsOneByteEqualTo(Vector<const uint8_t> str);
8947 bool IsTwoByteEqualTo(Vector<const uc16> str);
8948
8949 // Return a UTF8 representation of the string. The string is null
8950 // terminated but may optionally contain nulls. Length is returned
8951 // in length_output if length_output is not a null pointer The string
8952 // should be nearly flat, otherwise the performance of this method may
8953 // be very slow (quadratic in the length). Setting robustness_flag to
8954 // ROBUST_STRING_TRAVERSAL invokes behaviour that is robust This means it
8955 // handles unexpected data without causing assert failures and it does not
8956 // do any heap allocations. This is useful when printing stack traces.
8957 base::SmartArrayPointer<char> ToCString(AllowNullsFlag allow_nulls,
8958 RobustnessFlag robustness_flag,
8959 int offset, int length,
8960 int* length_output = 0);
8961 base::SmartArrayPointer<char> ToCString(
8962 AllowNullsFlag allow_nulls = DISALLOW_NULLS,
8963 RobustnessFlag robustness_flag = FAST_STRING_TRAVERSAL,
8964 int* length_output = 0);
8965
8966 bool ComputeArrayIndex(uint32_t* index);
8967
8968 // Externalization.
8969 bool MakeExternal(v8::String::ExternalStringResource* resource);
8970 bool MakeExternal(v8::String::ExternalOneByteStringResource* resource);
8971
8972 // Conversion.
8973 inline bool AsArrayIndex(uint32_t* index);
8974
8975 // Trimming.
8976 enum TrimMode { kTrim, kTrimLeft, kTrimRight };
8977 static Handle<String> Trim(Handle<String> string, TrimMode mode);
8978
8979 DECLARE_CAST(String)
8980
8981 void PrintOn(FILE* out);
8982
8983 // For use during stack traces. Performs rudimentary sanity check.
8984 bool LooksValid();
8985
8986 // Dispatched behavior.
8987 void StringShortPrint(StringStream* accumulator, bool show_details = true);
8988 void PrintUC16(std::ostream& os, int start = 0, int end = -1); // NOLINT
8989 #if defined(DEBUG) || defined(OBJECT_PRINT)
8990 char* ToAsciiArray();
8991 #endif
8992 DECLARE_PRINTER(String)
8993 DECLARE_VERIFIER(String)
8994
8995 inline bool IsFlat();
8996
8997 // Layout description.
8998 static const int kLengthOffset = Name::kSize;
8999 static const int kSize = kLengthOffset + kPointerSize;
9000
9001 // Max char codes.
9002 static const int32_t kMaxOneByteCharCode = unibrow::Latin1::kMaxChar;
9003 static const uint32_t kMaxOneByteCharCodeU = unibrow::Latin1::kMaxChar;
9004 static const int kMaxUtf16CodeUnit = 0xffff;
9005 static const uint32_t kMaxUtf16CodeUnitU = kMaxUtf16CodeUnit;
9006 static const uc32 kMaxCodePoint = 0x10ffff;
9007
9008 // Maximal string length.
9009 static const int kMaxLength = (1 << 28) - 16;
9010
9011 // Max length for computing hash. For strings longer than this limit the
9012 // string length is used as the hash value.
9013 static const int kMaxHashCalcLength = 16383;
9014
9015 // Limit for truncation in short printing.
9016 static const int kMaxShortPrintLength = 1024;
9017
9018 // Support for regular expressions.
9019 const uc16* GetTwoByteData(unsigned start);
9020
9021 // Helper function for flattening strings.
9022 template <typename sinkchar>
9023 static void WriteToFlat(String* source,
9024 sinkchar* sink,
9025 int from,
9026 int to);
9027
9028 // The return value may point to the first aligned word containing the first
9029 // non-one-byte character, rather than directly to the non-one-byte character.
9030 // If the return value is >= the passed length, the entire string was
9031 // one-byte.
NonAsciiStart(const char * chars,int length)9032 static inline int NonAsciiStart(const char* chars, int length) {
9033 const char* start = chars;
9034 const char* limit = chars + length;
9035
9036 if (length >= kIntptrSize) {
9037 // Check unaligned bytes.
9038 while (!IsAligned(reinterpret_cast<intptr_t>(chars), sizeof(uintptr_t))) {
9039 if (static_cast<uint8_t>(*chars) > unibrow::Utf8::kMaxOneByteChar) {
9040 return static_cast<int>(chars - start);
9041 }
9042 ++chars;
9043 }
9044 // Check aligned words.
9045 DCHECK(unibrow::Utf8::kMaxOneByteChar == 0x7F);
9046 const uintptr_t non_one_byte_mask = kUintptrAllBitsSet / 0xFF * 0x80;
9047 while (chars + sizeof(uintptr_t) <= limit) {
9048 if (*reinterpret_cast<const uintptr_t*>(chars) & non_one_byte_mask) {
9049 return static_cast<int>(chars - start);
9050 }
9051 chars += sizeof(uintptr_t);
9052 }
9053 }
9054 // Check remaining unaligned bytes.
9055 while (chars < limit) {
9056 if (static_cast<uint8_t>(*chars) > unibrow::Utf8::kMaxOneByteChar) {
9057 return static_cast<int>(chars - start);
9058 }
9059 ++chars;
9060 }
9061
9062 return static_cast<int>(chars - start);
9063 }
9064
IsAscii(const char * chars,int length)9065 static inline bool IsAscii(const char* chars, int length) {
9066 return NonAsciiStart(chars, length) >= length;
9067 }
9068
IsAscii(const uint8_t * chars,int length)9069 static inline bool IsAscii(const uint8_t* chars, int length) {
9070 return
9071 NonAsciiStart(reinterpret_cast<const char*>(chars), length) >= length;
9072 }
9073
NonOneByteStart(const uc16 * chars,int length)9074 static inline int NonOneByteStart(const uc16* chars, int length) {
9075 const uc16* limit = chars + length;
9076 const uc16* start = chars;
9077 while (chars < limit) {
9078 if (*chars > kMaxOneByteCharCodeU) return static_cast<int>(chars - start);
9079 ++chars;
9080 }
9081 return static_cast<int>(chars - start);
9082 }
9083
IsOneByte(const uc16 * chars,int length)9084 static inline bool IsOneByte(const uc16* chars, int length) {
9085 return NonOneByteStart(chars, length) >= length;
9086 }
9087
9088 template<class Visitor>
9089 static inline ConsString* VisitFlat(Visitor* visitor,
9090 String* string,
9091 int offset = 0);
9092
9093 static Handle<FixedArray> CalculateLineEnds(Handle<String> string,
9094 bool include_ending_line);
9095
9096 // Use the hash field to forward to the canonical internalized string
9097 // when deserializing an internalized string.
9098 inline void SetForwardedInternalizedString(String* string);
9099 inline String* GetForwardedInternalizedString();
9100
9101 private:
9102 friend class Name;
9103 friend class StringTableInsertionKey;
9104
9105 static Handle<String> SlowFlatten(Handle<ConsString> cons,
9106 PretenureFlag tenure);
9107
9108 // Slow case of String::Equals. This implementation works on any strings
9109 // but it is most efficient on strings that are almost flat.
9110 bool SlowEquals(String* other);
9111
9112 static bool SlowEquals(Handle<String> one, Handle<String> two);
9113
9114 // Slow case of AsArrayIndex.
9115 bool SlowAsArrayIndex(uint32_t* index);
9116
9117 // Compute and set the hash code.
9118 uint32_t ComputeAndSetHash();
9119
9120 DISALLOW_IMPLICIT_CONSTRUCTORS(String);
9121 };
9122
9123
9124 // The SeqString abstract class captures sequential string values.
9125 class SeqString: public String {
9126 public:
9127 DECLARE_CAST(SeqString)
9128
9129 // Layout description.
9130 static const int kHeaderSize = String::kSize;
9131
9132 // Truncate the string in-place if possible and return the result.
9133 // In case of new_length == 0, the empty string is returned without
9134 // truncating the original string.
9135 MUST_USE_RESULT static Handle<String> Truncate(Handle<SeqString> string,
9136 int new_length);
9137 private:
9138 DISALLOW_IMPLICIT_CONSTRUCTORS(SeqString);
9139 };
9140
9141
9142 // The OneByteString class captures sequential one-byte string objects.
9143 // Each character in the OneByteString is an one-byte character.
9144 class SeqOneByteString: public SeqString {
9145 public:
9146 static const bool kHasOneByteEncoding = true;
9147
9148 // Dispatched behavior.
9149 inline uint16_t SeqOneByteStringGet(int index);
9150 inline void SeqOneByteStringSet(int index, uint16_t value);
9151
9152 // Get the address of the characters in this string.
9153 inline Address GetCharsAddress();
9154
9155 inline uint8_t* GetChars();
9156
9157 DECLARE_CAST(SeqOneByteString)
9158
9159 // Garbage collection support. This method is called by the
9160 // garbage collector to compute the actual size of an OneByteString
9161 // instance.
9162 inline int SeqOneByteStringSize(InstanceType instance_type);
9163
9164 // Computes the size for an OneByteString instance of a given length.
SizeFor(int length)9165 static int SizeFor(int length) {
9166 return OBJECT_POINTER_ALIGN(kHeaderSize + length * kCharSize);
9167 }
9168
9169 // Maximal memory usage for a single sequential one-byte string.
9170 static const int kMaxSize = 512 * MB - 1;
9171 STATIC_ASSERT((kMaxSize - kHeaderSize) >= String::kMaxLength);
9172
9173 private:
9174 DISALLOW_IMPLICIT_CONSTRUCTORS(SeqOneByteString);
9175 };
9176
9177
9178 // The TwoByteString class captures sequential unicode string objects.
9179 // Each character in the TwoByteString is a two-byte uint16_t.
9180 class SeqTwoByteString: public SeqString {
9181 public:
9182 static const bool kHasOneByteEncoding = false;
9183
9184 // Dispatched behavior.
9185 inline uint16_t SeqTwoByteStringGet(int index);
9186 inline void SeqTwoByteStringSet(int index, uint16_t value);
9187
9188 // Get the address of the characters in this string.
9189 inline Address GetCharsAddress();
9190
9191 inline uc16* GetChars();
9192
9193 // For regexp code.
9194 const uint16_t* SeqTwoByteStringGetData(unsigned start);
9195
9196 DECLARE_CAST(SeqTwoByteString)
9197
9198 // Garbage collection support. This method is called by the
9199 // garbage collector to compute the actual size of a TwoByteString
9200 // instance.
9201 inline int SeqTwoByteStringSize(InstanceType instance_type);
9202
9203 // Computes the size for a TwoByteString instance of a given length.
SizeFor(int length)9204 static int SizeFor(int length) {
9205 return OBJECT_POINTER_ALIGN(kHeaderSize + length * kShortSize);
9206 }
9207
9208 // Maximal memory usage for a single sequential two-byte string.
9209 static const int kMaxSize = 512 * MB - 1;
9210 STATIC_ASSERT(static_cast<int>((kMaxSize - kHeaderSize)/sizeof(uint16_t)) >=
9211 String::kMaxLength);
9212
9213 private:
9214 DISALLOW_IMPLICIT_CONSTRUCTORS(SeqTwoByteString);
9215 };
9216
9217
9218 // The ConsString class describes string values built by using the
9219 // addition operator on strings. A ConsString is a pair where the
9220 // first and second components are pointers to other string values.
9221 // One or both components of a ConsString can be pointers to other
9222 // ConsStrings, creating a binary tree of ConsStrings where the leaves
9223 // are non-ConsString string values. The string value represented by
9224 // a ConsString can be obtained by concatenating the leaf string
9225 // values in a left-to-right depth-first traversal of the tree.
9226 class ConsString: public String {
9227 public:
9228 // First string of the cons cell.
9229 inline String* first();
9230 // Doesn't check that the result is a string, even in debug mode. This is
9231 // useful during GC where the mark bits confuse the checks.
9232 inline Object* unchecked_first();
9233 inline void set_first(String* first,
9234 WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
9235
9236 // Second string of the cons cell.
9237 inline String* second();
9238 // Doesn't check that the result is a string, even in debug mode. This is
9239 // useful during GC where the mark bits confuse the checks.
9240 inline Object* unchecked_second();
9241 inline void set_second(String* second,
9242 WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
9243
9244 // Dispatched behavior.
9245 uint16_t ConsStringGet(int index);
9246
9247 DECLARE_CAST(ConsString)
9248
9249 // Layout description.
9250 static const int kFirstOffset = POINTER_SIZE_ALIGN(String::kSize);
9251 static const int kSecondOffset = kFirstOffset + kPointerSize;
9252 static const int kSize = kSecondOffset + kPointerSize;
9253
9254 // Minimum length for a cons string.
9255 static const int kMinLength = 13;
9256
9257 typedef FixedBodyDescriptor<kFirstOffset, kSecondOffset + kPointerSize, kSize>
9258 BodyDescriptor;
9259
9260 DECLARE_VERIFIER(ConsString)
9261
9262 private:
9263 DISALLOW_IMPLICIT_CONSTRUCTORS(ConsString);
9264 };
9265
9266
9267 // The Sliced String class describes strings that are substrings of another
9268 // sequential string. The motivation is to save time and memory when creating
9269 // a substring. A Sliced String is described as a pointer to the parent,
9270 // the offset from the start of the parent string and the length. Using
9271 // a Sliced String therefore requires unpacking of the parent string and
9272 // adding the offset to the start address. A substring of a Sliced String
9273 // are not nested since the double indirection is simplified when creating
9274 // such a substring.
9275 // Currently missing features are:
9276 // - handling externalized parent strings
9277 // - external strings as parent
9278 // - truncating sliced string to enable otherwise unneeded parent to be GC'ed.
9279 class SlicedString: public String {
9280 public:
9281 inline String* parent();
9282 inline void set_parent(String* parent,
9283 WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
9284 inline int offset() const;
9285 inline void set_offset(int offset);
9286
9287 // Dispatched behavior.
9288 uint16_t SlicedStringGet(int index);
9289
9290 DECLARE_CAST(SlicedString)
9291
9292 // Layout description.
9293 static const int kParentOffset = POINTER_SIZE_ALIGN(String::kSize);
9294 static const int kOffsetOffset = kParentOffset + kPointerSize;
9295 static const int kSize = kOffsetOffset + kPointerSize;
9296
9297 // Minimum length for a sliced string.
9298 static const int kMinLength = 13;
9299
9300 typedef FixedBodyDescriptor<kParentOffset,
9301 kOffsetOffset + kPointerSize, kSize>
9302 BodyDescriptor;
9303
9304 DECLARE_VERIFIER(SlicedString)
9305
9306 private:
9307 DISALLOW_IMPLICIT_CONSTRUCTORS(SlicedString);
9308 };
9309
9310
9311 // The ExternalString class describes string values that are backed by
9312 // a string resource that lies outside the V8 heap. ExternalStrings
9313 // consist of the length field common to all strings, a pointer to the
9314 // external resource. It is important to ensure (externally) that the
9315 // resource is not deallocated while the ExternalString is live in the
9316 // V8 heap.
9317 //
9318 // The API expects that all ExternalStrings are created through the
9319 // API. Therefore, ExternalStrings should not be used internally.
9320 class ExternalString: public String {
9321 public:
9322 DECLARE_CAST(ExternalString)
9323
9324 // Layout description.
9325 static const int kResourceOffset = POINTER_SIZE_ALIGN(String::kSize);
9326 static const int kShortSize = kResourceOffset + kPointerSize;
9327 static const int kResourceDataOffset = kResourceOffset + kPointerSize;
9328 static const int kSize = kResourceDataOffset + kPointerSize;
9329
9330 // Return whether external string is short (data pointer is not cached).
9331 inline bool is_short();
9332
9333 STATIC_ASSERT(kResourceOffset == Internals::kStringResourceOffset);
9334
9335 private:
9336 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalString);
9337 };
9338
9339
9340 // The ExternalOneByteString class is an external string backed by an
9341 // one-byte string.
9342 class ExternalOneByteString : public ExternalString {
9343 public:
9344 static const bool kHasOneByteEncoding = true;
9345
9346 typedef v8::String::ExternalOneByteStringResource Resource;
9347
9348 // The underlying resource.
9349 inline const Resource* resource();
9350 inline void set_resource(const Resource* buffer);
9351
9352 // Update the pointer cache to the external character array.
9353 // The cached pointer is always valid, as the external character array does =
9354 // not move during lifetime. Deserialization is the only exception, after
9355 // which the pointer cache has to be refreshed.
9356 inline void update_data_cache();
9357
9358 inline const uint8_t* GetChars();
9359
9360 // Dispatched behavior.
9361 inline uint16_t ExternalOneByteStringGet(int index);
9362
9363 DECLARE_CAST(ExternalOneByteString)
9364
9365 class BodyDescriptor;
9366
9367 private:
9368 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalOneByteString);
9369 };
9370
9371
9372 // The ExternalTwoByteString class is an external string backed by a UTF-16
9373 // encoded string.
9374 class ExternalTwoByteString: public ExternalString {
9375 public:
9376 static const bool kHasOneByteEncoding = false;
9377
9378 typedef v8::String::ExternalStringResource Resource;
9379
9380 // The underlying string resource.
9381 inline const Resource* resource();
9382 inline void set_resource(const Resource* buffer);
9383
9384 // Update the pointer cache to the external character array.
9385 // The cached pointer is always valid, as the external character array does =
9386 // not move during lifetime. Deserialization is the only exception, after
9387 // which the pointer cache has to be refreshed.
9388 inline void update_data_cache();
9389
9390 inline const uint16_t* GetChars();
9391
9392 // Dispatched behavior.
9393 inline uint16_t ExternalTwoByteStringGet(int index);
9394
9395 // For regexp code.
9396 inline const uint16_t* ExternalTwoByteStringGetData(unsigned start);
9397
9398 DECLARE_CAST(ExternalTwoByteString)
9399
9400 class BodyDescriptor;
9401
9402 private:
9403 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalTwoByteString);
9404 };
9405
9406
9407 // Utility superclass for stack-allocated objects that must be updated
9408 // on gc. It provides two ways for the gc to update instances, either
9409 // iterating or updating after gc.
9410 class Relocatable BASE_EMBEDDED {
9411 public:
9412 explicit inline Relocatable(Isolate* isolate);
9413 inline virtual ~Relocatable();
IterateInstance(ObjectVisitor * v)9414 virtual void IterateInstance(ObjectVisitor* v) { }
PostGarbageCollection()9415 virtual void PostGarbageCollection() { }
9416
9417 static void PostGarbageCollectionProcessing(Isolate* isolate);
9418 static int ArchiveSpacePerThread();
9419 static char* ArchiveState(Isolate* isolate, char* to);
9420 static char* RestoreState(Isolate* isolate, char* from);
9421 static void Iterate(Isolate* isolate, ObjectVisitor* v);
9422 static void Iterate(ObjectVisitor* v, Relocatable* top);
9423 static char* Iterate(ObjectVisitor* v, char* t);
9424
9425 private:
9426 Isolate* isolate_;
9427 Relocatable* prev_;
9428 };
9429
9430
9431 // A flat string reader provides random access to the contents of a
9432 // string independent of the character width of the string. The handle
9433 // must be valid as long as the reader is being used.
9434 class FlatStringReader : public Relocatable {
9435 public:
9436 FlatStringReader(Isolate* isolate, Handle<String> str);
9437 FlatStringReader(Isolate* isolate, Vector<const char> input);
9438 void PostGarbageCollection();
9439 inline uc32 Get(int index);
9440 template <typename Char>
9441 inline Char Get(int index);
length()9442 int length() { return length_; }
9443 private:
9444 String** str_;
9445 bool is_one_byte_;
9446 int length_;
9447 const void* start_;
9448 };
9449
9450
9451 // This maintains an off-stack representation of the stack frames required
9452 // to traverse a ConsString, allowing an entirely iterative and restartable
9453 // traversal of the entire string
9454 class ConsStringIterator {
9455 public:
ConsStringIterator()9456 inline ConsStringIterator() {}
9457 inline explicit ConsStringIterator(ConsString* cons_string, int offset = 0) {
9458 Reset(cons_string, offset);
9459 }
9460 inline void Reset(ConsString* cons_string, int offset = 0) {
9461 depth_ = 0;
9462 // Next will always return NULL.
9463 if (cons_string == NULL) return;
9464 Initialize(cons_string, offset);
9465 }
9466 // Returns NULL when complete.
Next(int * offset_out)9467 inline String* Next(int* offset_out) {
9468 *offset_out = 0;
9469 if (depth_ == 0) return NULL;
9470 return Continue(offset_out);
9471 }
9472
9473 private:
9474 static const int kStackSize = 32;
9475 // Use a mask instead of doing modulo operations for stack wrapping.
9476 static const int kDepthMask = kStackSize-1;
9477 STATIC_ASSERT(IS_POWER_OF_TWO(kStackSize));
9478 static inline int OffsetForDepth(int depth);
9479
9480 inline void PushLeft(ConsString* string);
9481 inline void PushRight(ConsString* string);
9482 inline void AdjustMaximumDepth();
9483 inline void Pop();
StackBlown()9484 inline bool StackBlown() { return maximum_depth_ - depth_ == kStackSize; }
9485 void Initialize(ConsString* cons_string, int offset);
9486 String* Continue(int* offset_out);
9487 String* NextLeaf(bool* blew_stack);
9488 String* Search(int* offset_out);
9489
9490 // Stack must always contain only frames for which right traversal
9491 // has not yet been performed.
9492 ConsString* frames_[kStackSize];
9493 ConsString* root_;
9494 int depth_;
9495 int maximum_depth_;
9496 int consumed_;
9497 DISALLOW_COPY_AND_ASSIGN(ConsStringIterator);
9498 };
9499
9500
9501 class StringCharacterStream {
9502 public:
9503 inline StringCharacterStream(String* string,
9504 int offset = 0);
9505 inline uint16_t GetNext();
9506 inline bool HasMore();
9507 inline void Reset(String* string, int offset = 0);
9508 inline void VisitOneByteString(const uint8_t* chars, int length);
9509 inline void VisitTwoByteString(const uint16_t* chars, int length);
9510
9511 private:
9512 ConsStringIterator iter_;
9513 bool is_one_byte_;
9514 union {
9515 const uint8_t* buffer8_;
9516 const uint16_t* buffer16_;
9517 };
9518 const uint8_t* end_;
9519 DISALLOW_COPY_AND_ASSIGN(StringCharacterStream);
9520 };
9521
9522
9523 template <typename T>
9524 class VectorIterator {
9525 public:
VectorIterator(T * d,int l)9526 VectorIterator(T* d, int l) : data_(Vector<const T>(d, l)), index_(0) { }
VectorIterator(Vector<const T> data)9527 explicit VectorIterator(Vector<const T> data) : data_(data), index_(0) { }
GetNext()9528 T GetNext() { return data_[index_++]; }
has_more()9529 bool has_more() { return index_ < data_.length(); }
9530 private:
9531 Vector<const T> data_;
9532 int index_;
9533 };
9534
9535
9536 // The Oddball describes objects null, undefined, true, and false.
9537 class Oddball: public HeapObject {
9538 public:
9539 // [to_number_raw]: Cached raw to_number computed at startup.
9540 inline double to_number_raw() const;
9541 inline void set_to_number_raw(double value);
9542
9543 // [to_string]: Cached to_string computed at startup.
9544 DECL_ACCESSORS(to_string, String)
9545
9546 // [to_number]: Cached to_number computed at startup.
9547 DECL_ACCESSORS(to_number, Object)
9548
9549 // [to_number]: Cached to_boolean computed at startup.
9550 DECL_ACCESSORS(to_boolean, Oddball)
9551
9552 // [typeof]: Cached type_of computed at startup.
9553 DECL_ACCESSORS(type_of, String)
9554
9555 inline byte kind() const;
9556 inline void set_kind(byte kind);
9557
9558 // ES6 section 7.1.3 ToNumber for Boolean, Null, Undefined.
9559 MUST_USE_RESULT static inline Handle<Object> ToNumber(Handle<Oddball> input);
9560
9561 DECLARE_CAST(Oddball)
9562
9563 // Dispatched behavior.
9564 DECLARE_VERIFIER(Oddball)
9565
9566 // Initialize the fields.
9567 static void Initialize(Isolate* isolate, Handle<Oddball> oddball,
9568 const char* to_string, Handle<Object> to_number,
9569 bool to_boolean, const char* type_of, byte kind);
9570
9571 // Layout description.
9572 static const int kToNumberRawOffset = HeapObject::kHeaderSize;
9573 static const int kToStringOffset = kToNumberRawOffset + kDoubleSize;
9574 static const int kToNumberOffset = kToStringOffset + kPointerSize;
9575 static const int kToBooleanOffset = kToNumberOffset + kPointerSize;
9576 static const int kTypeOfOffset = kToBooleanOffset + kPointerSize;
9577 static const int kKindOffset = kTypeOfOffset + kPointerSize;
9578 static const int kSize = kKindOffset + kPointerSize;
9579
9580 static const byte kFalse = 0;
9581 static const byte kTrue = 1;
9582 static const byte kNotBooleanMask = ~1;
9583 static const byte kTheHole = 2;
9584 static const byte kNull = 3;
9585 static const byte kArgumentsMarker = 4;
9586 static const byte kUndefined = 5;
9587 static const byte kUninitialized = 6;
9588 static const byte kOther = 7;
9589 static const byte kException = 8;
9590 static const byte kOptimizedOut = 9;
9591 static const byte kStaleRegister = 10;
9592
9593 typedef FixedBodyDescriptor<kToStringOffset, kTypeOfOffset + kPointerSize,
9594 kSize> BodyDescriptor;
9595
9596 STATIC_ASSERT(kToNumberRawOffset == HeapNumber::kValueOffset);
9597 STATIC_ASSERT(kKindOffset == Internals::kOddballKindOffset);
9598 STATIC_ASSERT(kNull == Internals::kNullOddballKind);
9599 STATIC_ASSERT(kUndefined == Internals::kUndefinedOddballKind);
9600
9601 private:
9602 DISALLOW_IMPLICIT_CONSTRUCTORS(Oddball);
9603 };
9604
9605
9606 class Cell: public HeapObject {
9607 public:
9608 // [value]: value of the cell.
DECL_ACCESSORS(value,Object)9609 DECL_ACCESSORS(value, Object)
9610
9611 DECLARE_CAST(Cell)
9612
9613 static inline Cell* FromValueAddress(Address value) {
9614 Object* result = FromAddress(value - kValueOffset);
9615 return static_cast<Cell*>(result);
9616 }
9617
ValueAddress()9618 inline Address ValueAddress() {
9619 return address() + kValueOffset;
9620 }
9621
9622 // Dispatched behavior.
9623 DECLARE_PRINTER(Cell)
9624 DECLARE_VERIFIER(Cell)
9625
9626 // Layout description.
9627 static const int kValueOffset = HeapObject::kHeaderSize;
9628 static const int kSize = kValueOffset + kPointerSize;
9629
9630 typedef FixedBodyDescriptor<kValueOffset,
9631 kValueOffset + kPointerSize,
9632 kSize> BodyDescriptor;
9633
9634 private:
9635 DISALLOW_IMPLICIT_CONSTRUCTORS(Cell);
9636 };
9637
9638
9639 class PropertyCell : public HeapObject {
9640 public:
9641 // [property_details]: details of the global property.
9642 DECL_ACCESSORS(property_details_raw, Object)
9643 // [value]: value of the global property.
9644 DECL_ACCESSORS(value, Object)
9645 // [dependent_code]: dependent code that depends on the type of the global
9646 // property.
9647 DECL_ACCESSORS(dependent_code, DependentCode)
9648
9649 inline PropertyDetails property_details();
9650 inline void set_property_details(PropertyDetails details);
9651
9652 PropertyCellConstantType GetConstantType();
9653
9654 // Computes the new type of the cell's contents for the given value, but
9655 // without actually modifying the details.
9656 static PropertyCellType UpdatedType(Handle<PropertyCell> cell,
9657 Handle<Object> value,
9658 PropertyDetails details);
9659 static void UpdateCell(Handle<GlobalDictionary> dictionary, int entry,
9660 Handle<Object> value, PropertyDetails details);
9661
9662 static Handle<PropertyCell> InvalidateEntry(
9663 Handle<GlobalDictionary> dictionary, int entry);
9664
9665 static void SetValueWithInvalidation(Handle<PropertyCell> cell,
9666 Handle<Object> new_value);
9667
9668 DECLARE_CAST(PropertyCell)
9669
9670 // Dispatched behavior.
9671 DECLARE_PRINTER(PropertyCell)
9672 DECLARE_VERIFIER(PropertyCell)
9673
9674 // Layout description.
9675 static const int kDetailsOffset = HeapObject::kHeaderSize;
9676 static const int kValueOffset = kDetailsOffset + kPointerSize;
9677 static const int kDependentCodeOffset = kValueOffset + kPointerSize;
9678 static const int kSize = kDependentCodeOffset + kPointerSize;
9679
9680 static const int kPointerFieldsBeginOffset = kValueOffset;
9681 static const int kPointerFieldsEndOffset = kSize;
9682
9683 typedef FixedBodyDescriptor<kValueOffset,
9684 kSize,
9685 kSize> BodyDescriptor;
9686
9687 private:
9688 DISALLOW_IMPLICIT_CONSTRUCTORS(PropertyCell);
9689 };
9690
9691
9692 class WeakCell : public HeapObject {
9693 public:
9694 inline Object* value() const;
9695
9696 // This should not be called by anyone except GC.
9697 inline void clear();
9698
9699 // This should not be called by anyone except allocator.
9700 inline void initialize(HeapObject* value);
9701
9702 inline bool cleared() const;
9703
9704 DECL_ACCESSORS(next, Object)
9705
9706 inline void clear_next(Object* the_hole_value);
9707
9708 inline bool next_cleared();
9709
9710 DECLARE_CAST(WeakCell)
9711
9712 DECLARE_PRINTER(WeakCell)
9713 DECLARE_VERIFIER(WeakCell)
9714
9715 // Layout description.
9716 static const int kValueOffset = HeapObject::kHeaderSize;
9717 static const int kNextOffset = kValueOffset + kPointerSize;
9718 static const int kSize = kNextOffset + kPointerSize;
9719
9720 typedef FixedBodyDescriptor<kValueOffset, kSize, kSize> BodyDescriptor;
9721
9722 private:
9723 DISALLOW_IMPLICIT_CONSTRUCTORS(WeakCell);
9724 };
9725
9726
9727 // The JSProxy describes EcmaScript Harmony proxies
9728 class JSProxy: public JSReceiver {
9729 public:
9730 MUST_USE_RESULT static MaybeHandle<JSProxy> New(Isolate* isolate,
9731 Handle<Object>,
9732 Handle<Object>);
9733
9734 // [handler]: The handler property.
9735 DECL_ACCESSORS(handler, Object)
9736 // [target]: The target property.
9737 DECL_ACCESSORS(target, JSReceiver)
9738 // [hash]: The hash code property (undefined if not initialized yet).
9739 DECL_ACCESSORS(hash, Object)
9740
9741 static MaybeHandle<Context> GetFunctionRealm(Handle<JSProxy> proxy);
9742
9743 DECLARE_CAST(JSProxy)
9744
9745 INLINE(bool IsRevoked() const);
9746 static void Revoke(Handle<JSProxy> proxy);
9747
9748 // ES6 9.5.1
9749 static MaybeHandle<Object> GetPrototype(Handle<JSProxy> receiver);
9750
9751 // ES6 9.5.2
9752 MUST_USE_RESULT static Maybe<bool> SetPrototype(Handle<JSProxy> proxy,
9753 Handle<Object> value,
9754 bool from_javascript,
9755 ShouldThrow should_throw);
9756 // ES6 9.5.3
9757 MUST_USE_RESULT static Maybe<bool> IsExtensible(Handle<JSProxy> proxy);
9758
9759 // ES6 9.5.4 (when passed DONT_THROW)
9760 MUST_USE_RESULT static Maybe<bool> PreventExtensions(
9761 Handle<JSProxy> proxy, ShouldThrow should_throw);
9762
9763 // ES6 9.5.5
9764 MUST_USE_RESULT static Maybe<bool> GetOwnPropertyDescriptor(
9765 Isolate* isolate, Handle<JSProxy> proxy, Handle<Name> name,
9766 PropertyDescriptor* desc);
9767
9768 // ES6 9.5.6
9769 MUST_USE_RESULT static Maybe<bool> DefineOwnProperty(
9770 Isolate* isolate, Handle<JSProxy> object, Handle<Object> key,
9771 PropertyDescriptor* desc, ShouldThrow should_throw);
9772
9773 // ES6 9.5.7
9774 MUST_USE_RESULT static Maybe<bool> HasProperty(Isolate* isolate,
9775 Handle<JSProxy> proxy,
9776 Handle<Name> name);
9777
9778 // ES6 9.5.8
9779 MUST_USE_RESULT static MaybeHandle<Object> GetProperty(
9780 Isolate* isolate, Handle<JSProxy> proxy, Handle<Name> name,
9781 Handle<Object> receiver, bool* was_found);
9782
9783 // ES6 9.5.9
9784 MUST_USE_RESULT static Maybe<bool> SetProperty(Handle<JSProxy> proxy,
9785 Handle<Name> name,
9786 Handle<Object> value,
9787 Handle<Object> receiver,
9788 LanguageMode language_mode);
9789
9790 // ES6 9.5.10 (when passed SLOPPY)
9791 MUST_USE_RESULT static Maybe<bool> DeletePropertyOrElement(
9792 Handle<JSProxy> proxy, Handle<Name> name, LanguageMode language_mode);
9793
9794 // ES6 9.5.12
9795 MUST_USE_RESULT static Maybe<bool> OwnPropertyKeys(
9796 Isolate* isolate, Handle<JSReceiver> receiver, Handle<JSProxy> proxy,
9797 PropertyFilter filter, KeyAccumulator* accumulator);
9798
9799 MUST_USE_RESULT static Maybe<PropertyAttributes> GetPropertyAttributes(
9800 LookupIterator* it);
9801
9802 // Dispatched behavior.
9803 DECLARE_PRINTER(JSProxy)
9804 DECLARE_VERIFIER(JSProxy)
9805
9806 // Layout description.
9807 static const int kTargetOffset = JSReceiver::kHeaderSize;
9808 static const int kHandlerOffset = kTargetOffset + kPointerSize;
9809 static const int kHashOffset = kHandlerOffset + kPointerSize;
9810 static const int kSize = kHashOffset + kPointerSize;
9811
9812 typedef FixedBodyDescriptor<JSReceiver::kPropertiesOffset, kSize, kSize>
9813 BodyDescriptor;
9814
9815 static Object* GetIdentityHash(Handle<JSProxy> receiver);
9816
9817 static Smi* GetOrCreateIdentityHash(Isolate* isolate, Handle<JSProxy> proxy);
9818
9819 static Maybe<bool> SetPrivateProperty(Isolate* isolate, Handle<JSProxy> proxy,
9820 Handle<Symbol> private_name,
9821 PropertyDescriptor* desc,
9822 ShouldThrow should_throw);
9823
9824 private:
9825 DISALLOW_IMPLICIT_CONSTRUCTORS(JSProxy);
9826 };
9827
9828
9829 class JSCollection : public JSObject {
9830 public:
9831 // [table]: the backing hash table
9832 DECL_ACCESSORS(table, Object)
9833
9834 static const int kTableOffset = JSObject::kHeaderSize;
9835 static const int kSize = kTableOffset + kPointerSize;
9836
9837 private:
9838 DISALLOW_IMPLICIT_CONSTRUCTORS(JSCollection);
9839 };
9840
9841
9842 // The JSSet describes EcmaScript Harmony sets
9843 class JSSet : public JSCollection {
9844 public:
9845 DECLARE_CAST(JSSet)
9846
9847 static void Initialize(Handle<JSSet> set, Isolate* isolate);
9848 static void Clear(Handle<JSSet> set);
9849
9850 // Dispatched behavior.
9851 DECLARE_PRINTER(JSSet)
9852 DECLARE_VERIFIER(JSSet)
9853
9854 private:
9855 DISALLOW_IMPLICIT_CONSTRUCTORS(JSSet);
9856 };
9857
9858
9859 // The JSMap describes EcmaScript Harmony maps
9860 class JSMap : public JSCollection {
9861 public:
9862 DECLARE_CAST(JSMap)
9863
9864 static void Initialize(Handle<JSMap> map, Isolate* isolate);
9865 static void Clear(Handle<JSMap> map);
9866
9867 // Dispatched behavior.
9868 DECLARE_PRINTER(JSMap)
9869 DECLARE_VERIFIER(JSMap)
9870
9871 private:
9872 DISALLOW_IMPLICIT_CONSTRUCTORS(JSMap);
9873 };
9874
9875
9876 // OrderedHashTableIterator is an iterator that iterates over the keys and
9877 // values of an OrderedHashTable.
9878 //
9879 // The iterator has a reference to the underlying OrderedHashTable data,
9880 // [table], as well as the current [index] the iterator is at.
9881 //
9882 // When the OrderedHashTable is rehashed it adds a reference from the old table
9883 // to the new table as well as storing enough data about the changes so that the
9884 // iterator [index] can be adjusted accordingly.
9885 //
9886 // When the [Next] result from the iterator is requested, the iterator checks if
9887 // there is a newer table that it needs to transition to.
9888 template<class Derived, class TableType>
9889 class OrderedHashTableIterator: public JSObject {
9890 public:
9891 // [table]: the backing hash table mapping keys to values.
9892 DECL_ACCESSORS(table, Object)
9893
9894 // [index]: The index into the data table.
9895 DECL_ACCESSORS(index, Object)
9896
9897 // [kind]: The kind of iteration this is. One of the [Kind] enum values.
9898 DECL_ACCESSORS(kind, Object)
9899
9900 #ifdef OBJECT_PRINT
9901 void OrderedHashTableIteratorPrint(std::ostream& os); // NOLINT
9902 #endif
9903
9904 static const int kTableOffset = JSObject::kHeaderSize;
9905 static const int kIndexOffset = kTableOffset + kPointerSize;
9906 static const int kKindOffset = kIndexOffset + kPointerSize;
9907 static const int kSize = kKindOffset + kPointerSize;
9908
9909 enum Kind {
9910 kKindKeys = 1,
9911 kKindValues = 2,
9912 kKindEntries = 3
9913 };
9914
9915 // Whether the iterator has more elements. This needs to be called before
9916 // calling |CurrentKey| and/or |CurrentValue|.
9917 bool HasMore();
9918
9919 // Move the index forward one.
MoveNext()9920 void MoveNext() {
9921 set_index(Smi::FromInt(Smi::cast(index())->value() + 1));
9922 }
9923
9924 // Populates the array with the next key and value and then moves the iterator
9925 // forward.
9926 // This returns the |kind| or 0 if the iterator is already at the end.
9927 Smi* Next(JSArray* value_array);
9928
9929 // Returns the current key of the iterator. This should only be called when
9930 // |HasMore| returns true.
9931 inline Object* CurrentKey();
9932
9933 private:
9934 // Transitions the iterator to the non obsolete backing store. This is a NOP
9935 // if the [table] is not obsolete.
9936 void Transition();
9937
9938 DISALLOW_IMPLICIT_CONSTRUCTORS(OrderedHashTableIterator);
9939 };
9940
9941
9942 class JSSetIterator: public OrderedHashTableIterator<JSSetIterator,
9943 OrderedHashSet> {
9944 public:
9945 // Dispatched behavior.
9946 DECLARE_PRINTER(JSSetIterator)
9947 DECLARE_VERIFIER(JSSetIterator)
9948
9949 DECLARE_CAST(JSSetIterator)
9950
9951 // Called by |Next| to populate the array. This allows the subclasses to
9952 // populate the array differently.
9953 inline void PopulateValueArray(FixedArray* array);
9954
9955 private:
9956 DISALLOW_IMPLICIT_CONSTRUCTORS(JSSetIterator);
9957 };
9958
9959
9960 class JSMapIterator: public OrderedHashTableIterator<JSMapIterator,
9961 OrderedHashMap> {
9962 public:
9963 // Dispatched behavior.
9964 DECLARE_PRINTER(JSMapIterator)
9965 DECLARE_VERIFIER(JSMapIterator)
9966
9967 DECLARE_CAST(JSMapIterator)
9968
9969 // Called by |Next| to populate the array. This allows the subclasses to
9970 // populate the array differently.
9971 inline void PopulateValueArray(FixedArray* array);
9972
9973 private:
9974 // Returns the current value of the iterator. This should only be called when
9975 // |HasMore| returns true.
9976 inline Object* CurrentValue();
9977
9978 DISALLOW_IMPLICIT_CONSTRUCTORS(JSMapIterator);
9979 };
9980
9981
9982 // Base class for both JSWeakMap and JSWeakSet
9983 class JSWeakCollection: public JSObject {
9984 public:
9985 // [table]: the backing hash table mapping keys to values.
9986 DECL_ACCESSORS(table, Object)
9987
9988 // [next]: linked list of encountered weak maps during GC.
9989 DECL_ACCESSORS(next, Object)
9990
9991 static void Initialize(Handle<JSWeakCollection> collection, Isolate* isolate);
9992 static void Set(Handle<JSWeakCollection> collection, Handle<Object> key,
9993 Handle<Object> value, int32_t hash);
9994 static bool Delete(Handle<JSWeakCollection> collection, Handle<Object> key,
9995 int32_t hash);
9996
9997 static const int kTableOffset = JSObject::kHeaderSize;
9998 static const int kNextOffset = kTableOffset + kPointerSize;
9999 static const int kSize = kNextOffset + kPointerSize;
10000
10001 // Visiting policy defines whether the table and next collection fields
10002 // should be visited or not.
10003 enum BodyVisitingPolicy { kVisitStrong, kVisitWeak };
10004
10005 // Iterates the function object according to the visiting policy.
10006 template <BodyVisitingPolicy>
10007 class BodyDescriptorImpl;
10008
10009 // Visit the whole object.
10010 typedef BodyDescriptorImpl<kVisitStrong> BodyDescriptor;
10011
10012 // Don't visit table and next collection fields.
10013 typedef BodyDescriptorImpl<kVisitWeak> BodyDescriptorWeak;
10014
10015 private:
10016 DISALLOW_IMPLICIT_CONSTRUCTORS(JSWeakCollection);
10017 };
10018
10019
10020 // The JSWeakMap describes EcmaScript Harmony weak maps
10021 class JSWeakMap: public JSWeakCollection {
10022 public:
10023 DECLARE_CAST(JSWeakMap)
10024
10025 // Dispatched behavior.
10026 DECLARE_PRINTER(JSWeakMap)
10027 DECLARE_VERIFIER(JSWeakMap)
10028
10029 private:
10030 DISALLOW_IMPLICIT_CONSTRUCTORS(JSWeakMap);
10031 };
10032
10033
10034 // The JSWeakSet describes EcmaScript Harmony weak sets
10035 class JSWeakSet: public JSWeakCollection {
10036 public:
10037 DECLARE_CAST(JSWeakSet)
10038
10039 // Dispatched behavior.
10040 DECLARE_PRINTER(JSWeakSet)
10041 DECLARE_VERIFIER(JSWeakSet)
10042
10043 private:
10044 DISALLOW_IMPLICIT_CONSTRUCTORS(JSWeakSet);
10045 };
10046
10047
10048 // Whether a JSArrayBuffer is a SharedArrayBuffer or not.
10049 enum class SharedFlag { kNotShared, kShared };
10050
10051
10052 class JSArrayBuffer: public JSObject {
10053 public:
10054 // [backing_store]: backing memory for this array
10055 DECL_ACCESSORS(backing_store, void)
10056
10057 // [byte_length]: length in bytes
10058 DECL_ACCESSORS(byte_length, Object)
10059
10060 inline uint32_t bit_field() const;
10061 inline void set_bit_field(uint32_t bits);
10062
10063 inline bool is_external();
10064 inline void set_is_external(bool value);
10065
10066 inline bool is_neuterable();
10067 inline void set_is_neuterable(bool value);
10068
10069 inline bool was_neutered();
10070 inline void set_was_neutered(bool value);
10071
10072 inline bool is_shared();
10073 inline void set_is_shared(bool value);
10074
10075 DECLARE_CAST(JSArrayBuffer)
10076
10077 void Neuter();
10078
10079 static void Setup(Handle<JSArrayBuffer> array_buffer, Isolate* isolate,
10080 bool is_external, void* data, size_t allocated_length,
10081 SharedFlag shared = SharedFlag::kNotShared);
10082
10083 static bool SetupAllocatingData(Handle<JSArrayBuffer> array_buffer,
10084 Isolate* isolate, size_t allocated_length,
10085 bool initialize = true,
10086 SharedFlag shared = SharedFlag::kNotShared);
10087
10088 // Dispatched behavior.
10089 DECLARE_PRINTER(JSArrayBuffer)
10090 DECLARE_VERIFIER(JSArrayBuffer)
10091
10092 static const int kByteLengthOffset = JSObject::kHeaderSize;
10093 static const int kBackingStoreOffset = kByteLengthOffset + kPointerSize;
10094 static const int kBitFieldSlot = kBackingStoreOffset + kPointerSize;
10095 #if V8_TARGET_LITTLE_ENDIAN || !V8_HOST_ARCH_64_BIT
10096 static const int kBitFieldOffset = kBitFieldSlot;
10097 #else
10098 static const int kBitFieldOffset = kBitFieldSlot + kIntSize;
10099 #endif
10100 static const int kSize = kBitFieldSlot + kPointerSize;
10101
10102 static const int kSizeWithInternalFields =
10103 kSize + v8::ArrayBuffer::kInternalFieldCount * kPointerSize;
10104
10105 // Iterates all fields in the object including internal ones except
10106 // kBackingStoreOffset and kBitFieldSlot.
10107 class BodyDescriptor;
10108
10109 class IsExternal : public BitField<bool, 1, 1> {};
10110 class IsNeuterable : public BitField<bool, 2, 1> {};
10111 class WasNeutered : public BitField<bool, 3, 1> {};
10112 class IsShared : public BitField<bool, 4, 1> {};
10113
10114 private:
10115 DISALLOW_IMPLICIT_CONSTRUCTORS(JSArrayBuffer);
10116 };
10117
10118
10119 class JSArrayBufferView: public JSObject {
10120 public:
10121 // [buffer]: ArrayBuffer that this typed array views.
10122 DECL_ACCESSORS(buffer, Object)
10123
10124 // [byte_offset]: offset of typed array in bytes.
10125 DECL_ACCESSORS(byte_offset, Object)
10126
10127 // [byte_length]: length of typed array in bytes.
10128 DECL_ACCESSORS(byte_length, Object)
10129
10130 DECLARE_CAST(JSArrayBufferView)
10131
10132 DECLARE_VERIFIER(JSArrayBufferView)
10133
10134 inline bool WasNeutered() const;
10135
10136 static const int kBufferOffset = JSObject::kHeaderSize;
10137 static const int kByteOffsetOffset = kBufferOffset + kPointerSize;
10138 static const int kByteLengthOffset = kByteOffsetOffset + kPointerSize;
10139 static const int kViewSize = kByteLengthOffset + kPointerSize;
10140
10141 private:
10142 #ifdef VERIFY_HEAP
10143 DECL_ACCESSORS(raw_byte_offset, Object)
10144 DECL_ACCESSORS(raw_byte_length, Object)
10145 #endif
10146
10147 DISALLOW_IMPLICIT_CONSTRUCTORS(JSArrayBufferView);
10148 };
10149
10150
10151 class JSTypedArray: public JSArrayBufferView {
10152 public:
10153 // [length]: length of typed array in elements.
10154 DECL_ACCESSORS(length, Object)
10155 inline uint32_t length_value() const;
10156
10157 DECLARE_CAST(JSTypedArray)
10158
10159 ExternalArrayType type();
10160 size_t element_size();
10161
10162 Handle<JSArrayBuffer> GetBuffer();
10163
10164 // Dispatched behavior.
10165 DECLARE_PRINTER(JSTypedArray)
10166 DECLARE_VERIFIER(JSTypedArray)
10167
10168 static const int kLengthOffset = kViewSize + kPointerSize;
10169 static const int kSize = kLengthOffset + kPointerSize;
10170
10171 static const int kSizeWithInternalFields =
10172 kSize + v8::ArrayBufferView::kInternalFieldCount * kPointerSize;
10173
10174 private:
10175 static Handle<JSArrayBuffer> MaterializeArrayBuffer(
10176 Handle<JSTypedArray> typed_array);
10177 #ifdef VERIFY_HEAP
10178 DECL_ACCESSORS(raw_length, Object)
10179 #endif
10180
10181 DISALLOW_IMPLICIT_CONSTRUCTORS(JSTypedArray);
10182 };
10183
10184
10185 class JSDataView: public JSArrayBufferView {
10186 public:
10187 DECLARE_CAST(JSDataView)
10188
10189 // Dispatched behavior.
10190 DECLARE_PRINTER(JSDataView)
10191 DECLARE_VERIFIER(JSDataView)
10192
10193 static const int kSize = kViewSize;
10194
10195 static const int kSizeWithInternalFields =
10196 kSize + v8::ArrayBufferView::kInternalFieldCount * kPointerSize;
10197
10198 private:
10199 DISALLOW_IMPLICIT_CONSTRUCTORS(JSDataView);
10200 };
10201
10202
10203 // Foreign describes objects pointing from JavaScript to C structures.
10204 class Foreign: public HeapObject {
10205 public:
10206 // [address]: field containing the address.
10207 inline Address foreign_address();
10208 inline void set_foreign_address(Address value);
10209
10210 DECLARE_CAST(Foreign)
10211
10212 // Dispatched behavior.
10213 DECLARE_PRINTER(Foreign)
10214 DECLARE_VERIFIER(Foreign)
10215
10216 // Layout description.
10217
10218 static const int kForeignAddressOffset = HeapObject::kHeaderSize;
10219 static const int kSize = kForeignAddressOffset + kPointerSize;
10220
10221 STATIC_ASSERT(kForeignAddressOffset == Internals::kForeignAddressOffset);
10222
10223 class BodyDescriptor;
10224
10225 private:
10226 DISALLOW_IMPLICIT_CONSTRUCTORS(Foreign);
10227 };
10228
10229
10230 // The JSArray describes JavaScript Arrays
10231 // Such an array can be in one of two modes:
10232 // - fast, backing storage is a FixedArray and length <= elements.length();
10233 // Please note: push and pop can be used to grow and shrink the array.
10234 // - slow, backing storage is a HashTable with numbers as keys.
10235 class JSArray: public JSObject {
10236 public:
10237 // [length]: The length property.
10238 DECL_ACCESSORS(length, Object)
10239
10240 // Overload the length setter to skip write barrier when the length
10241 // is set to a smi. This matches the set function on FixedArray.
10242 inline void set_length(Smi* length);
10243
10244 static bool HasReadOnlyLength(Handle<JSArray> array);
10245 static bool WouldChangeReadOnlyLength(Handle<JSArray> array, uint32_t index);
10246
10247 // Initialize the array with the given capacity. The function may
10248 // fail due to out-of-memory situations, but only if the requested
10249 // capacity is non-zero.
10250 static void Initialize(Handle<JSArray> array, int capacity, int length = 0);
10251
10252 // If the JSArray has fast elements, and new_length would result in
10253 // normalization, returns true.
10254 bool SetLengthWouldNormalize(uint32_t new_length);
10255 static inline bool SetLengthWouldNormalize(Heap* heap, uint32_t new_length);
10256
10257 // Initializes the array to a certain length.
10258 inline bool AllowsSetLength();
10259
10260 static void SetLength(Handle<JSArray> array, uint32_t length);
10261
10262 // Set the content of the array to the content of storage.
10263 static inline void SetContent(Handle<JSArray> array,
10264 Handle<FixedArrayBase> storage);
10265
10266 // ES6 9.4.2.1
10267 MUST_USE_RESULT static Maybe<bool> DefineOwnProperty(
10268 Isolate* isolate, Handle<JSArray> o, Handle<Object> name,
10269 PropertyDescriptor* desc, ShouldThrow should_throw);
10270
10271 static bool AnythingToArrayLength(Isolate* isolate,
10272 Handle<Object> length_object,
10273 uint32_t* output);
10274 MUST_USE_RESULT static Maybe<bool> ArraySetLength(Isolate* isolate,
10275 Handle<JSArray> a,
10276 PropertyDescriptor* desc,
10277 ShouldThrow should_throw);
10278
10279 // Checks whether the Array has the current realm's Array.prototype as its
10280 // prototype. This function is best-effort and only gives a conservative
10281 // approximation, erring on the side of false, in particular with respect
10282 // to Proxies and objects with a hidden prototype.
10283 inline bool HasArrayPrototype(Isolate* isolate);
10284
10285 DECLARE_CAST(JSArray)
10286
10287 // Dispatched behavior.
10288 DECLARE_PRINTER(JSArray)
10289 DECLARE_VERIFIER(JSArray)
10290
10291 // Number of element slots to pre-allocate for an empty array.
10292 static const int kPreallocatedArrayElements = 4;
10293
10294 // Layout description.
10295 static const int kLengthOffset = JSObject::kHeaderSize;
10296 static const int kSize = kLengthOffset + kPointerSize;
10297
10298 // 600 * KB is the Page::kMaxRegularHeapObjectSize defined in spaces.h which
10299 // we do not want to include in objects.h
10300 // Note that Page::kMaxRegularHeapObjectSize has to be in sync with
10301 // kInitialMaxFastElementArray which is checked in a DCHECK in heap.cc.
10302 static const int kInitialMaxFastElementArray =
10303 (600 * KB - FixedArray::kHeaderSize - kSize - AllocationMemento::kSize) /
10304 kPointerSize;
10305
10306 private:
10307 DISALLOW_IMPLICIT_CONSTRUCTORS(JSArray);
10308 };
10309
10310
10311 Handle<Object> CacheInitialJSArrayMaps(Handle<Context> native_context,
10312 Handle<Map> initial_map);
10313
10314
10315 // JSRegExpResult is just a JSArray with a specific initial map.
10316 // This initial map adds in-object properties for "index" and "input"
10317 // properties, as assigned by RegExp.prototype.exec, which allows
10318 // faster creation of RegExp exec results.
10319 // This class just holds constants used when creating the result.
10320 // After creation the result must be treated as a JSArray in all regards.
10321 class JSRegExpResult: public JSArray {
10322 public:
10323 // Offsets of object fields.
10324 static const int kIndexOffset = JSArray::kSize;
10325 static const int kInputOffset = kIndexOffset + kPointerSize;
10326 static const int kSize = kInputOffset + kPointerSize;
10327 // Indices of in-object properties.
10328 static const int kIndexIndex = 0;
10329 static const int kInputIndex = 1;
10330 private:
10331 DISALLOW_IMPLICIT_CONSTRUCTORS(JSRegExpResult);
10332 };
10333
10334
10335 // An accessor must have a getter, but can have no setter.
10336 //
10337 // When setting a property, V8 searches accessors in prototypes.
10338 // If an accessor was found and it does not have a setter,
10339 // the request is ignored.
10340 //
10341 // If the accessor in the prototype has the READ_ONLY property attribute, then
10342 // a new value is added to the derived object when the property is set.
10343 // This shadows the accessor in the prototype.
10344 class AccessorInfo: public Struct {
10345 public:
10346 DECL_ACCESSORS(name, Object)
10347 DECL_INT_ACCESSORS(flag)
10348 DECL_ACCESSORS(expected_receiver_type, Object)
10349 // This directly points at a foreign C function to be used from the runtime.
10350 DECL_ACCESSORS(getter, Object)
10351 DECL_ACCESSORS(setter, Object)
10352 // This either points at the same as above, or a trampoline in case we are
10353 // running with the simulator. Use these entries from generated code.
10354 DECL_ACCESSORS(js_getter, Object)
10355 DECL_ACCESSORS(data, Object)
10356
10357 static Address redirect(Isolate* isolate, Address address,
10358 AccessorComponent component);
10359 Address redirected_getter() const;
10360
10361 // Dispatched behavior.
10362 DECLARE_PRINTER(AccessorInfo)
10363
10364 inline bool all_can_read();
10365 inline void set_all_can_read(bool value);
10366
10367 inline bool all_can_write();
10368 inline void set_all_can_write(bool value);
10369
10370 inline bool is_special_data_property();
10371 inline void set_is_special_data_property(bool value);
10372
10373 inline bool is_sloppy();
10374 inline void set_is_sloppy(bool value);
10375
10376 inline PropertyAttributes property_attributes();
10377 inline void set_property_attributes(PropertyAttributes attributes);
10378
10379 // Checks whether the given receiver is compatible with this accessor.
10380 static bool IsCompatibleReceiverMap(Isolate* isolate,
10381 Handle<AccessorInfo> info,
10382 Handle<Map> map);
10383 inline bool IsCompatibleReceiver(Object* receiver);
10384
10385 DECLARE_CAST(AccessorInfo)
10386
10387 // Dispatched behavior.
10388 DECLARE_VERIFIER(AccessorInfo)
10389
10390 // Append all descriptors to the array that are not already there.
10391 // Return number added.
10392 static int AppendUnique(Handle<Object> descriptors,
10393 Handle<FixedArray> array,
10394 int valid_descriptors);
10395
10396 static const int kNameOffset = HeapObject::kHeaderSize;
10397 static const int kFlagOffset = kNameOffset + kPointerSize;
10398 static const int kExpectedReceiverTypeOffset = kFlagOffset + kPointerSize;
10399 static const int kSetterOffset = kExpectedReceiverTypeOffset + kPointerSize;
10400 static const int kGetterOffset = kSetterOffset + kPointerSize;
10401 static const int kJsGetterOffset = kGetterOffset + kPointerSize;
10402 static const int kDataOffset = kJsGetterOffset + kPointerSize;
10403 static const int kSize = kDataOffset + kPointerSize;
10404
10405
10406 private:
10407 inline bool HasExpectedReceiverType();
10408
10409 // Bit positions in flag.
10410 static const int kAllCanReadBit = 0;
10411 static const int kAllCanWriteBit = 1;
10412 static const int kSpecialDataProperty = 2;
10413 static const int kIsSloppy = 3;
10414 class AttributesField : public BitField<PropertyAttributes, 4, 3> {};
10415
10416 DISALLOW_IMPLICIT_CONSTRUCTORS(AccessorInfo);
10417 };
10418
10419
10420 // Support for JavaScript accessors: A pair of a getter and a setter. Each
10421 // accessor can either be
10422 // * a pointer to a JavaScript function or proxy: a real accessor
10423 // * undefined: considered an accessor by the spec, too, strangely enough
10424 // * the hole: an accessor which has not been set
10425 // * a pointer to a map: a transition used to ensure map sharing
10426 class AccessorPair: public Struct {
10427 public:
10428 DECL_ACCESSORS(getter, Object)
10429 DECL_ACCESSORS(setter, Object)
10430
10431 DECLARE_CAST(AccessorPair)
10432
10433 static Handle<AccessorPair> Copy(Handle<AccessorPair> pair);
10434
10435 inline Object* get(AccessorComponent component);
10436 inline void set(AccessorComponent component, Object* value);
10437
10438 // Note: Returns undefined instead in case of a hole.
10439 static Handle<Object> GetComponent(Handle<AccessorPair> accessor_pair,
10440 AccessorComponent component);
10441
10442 // Set both components, skipping arguments which are a JavaScript null.
10443 inline void SetComponents(Object* getter, Object* setter);
10444
10445 inline bool Equals(AccessorPair* pair);
10446 inline bool Equals(Object* getter_value, Object* setter_value);
10447
10448 inline bool ContainsAccessor();
10449
10450 // Dispatched behavior.
10451 DECLARE_PRINTER(AccessorPair)
10452 DECLARE_VERIFIER(AccessorPair)
10453
10454 static const int kGetterOffset = HeapObject::kHeaderSize;
10455 static const int kSetterOffset = kGetterOffset + kPointerSize;
10456 static const int kSize = kSetterOffset + kPointerSize;
10457
10458 private:
10459 // Strangely enough, in addition to functions and harmony proxies, the spec
10460 // requires us to consider undefined as a kind of accessor, too:
10461 // var obj = {};
10462 // Object.defineProperty(obj, "foo", {get: undefined});
10463 // assertTrue("foo" in obj);
10464 inline bool IsJSAccessor(Object* obj);
10465
10466 DISALLOW_IMPLICIT_CONSTRUCTORS(AccessorPair);
10467 };
10468
10469
10470 class AccessCheckInfo: public Struct {
10471 public:
10472 DECL_ACCESSORS(callback, Object)
10473 DECL_ACCESSORS(named_interceptor, Object)
10474 DECL_ACCESSORS(indexed_interceptor, Object)
10475 DECL_ACCESSORS(data, Object)
10476
10477 DECLARE_CAST(AccessCheckInfo)
10478
10479 // Dispatched behavior.
10480 DECLARE_PRINTER(AccessCheckInfo)
10481 DECLARE_VERIFIER(AccessCheckInfo)
10482
10483 static AccessCheckInfo* Get(Isolate* isolate, Handle<JSObject> receiver);
10484
10485 static const int kCallbackOffset = HeapObject::kHeaderSize;
10486 static const int kNamedInterceptorOffset = kCallbackOffset + kPointerSize;
10487 static const int kIndexedInterceptorOffset =
10488 kNamedInterceptorOffset + kPointerSize;
10489 static const int kDataOffset = kIndexedInterceptorOffset + kPointerSize;
10490 static const int kSize = kDataOffset + kPointerSize;
10491
10492 private:
10493 DISALLOW_IMPLICIT_CONSTRUCTORS(AccessCheckInfo);
10494 };
10495
10496
10497 class InterceptorInfo: public Struct {
10498 public:
10499 DECL_ACCESSORS(getter, Object)
10500 DECL_ACCESSORS(setter, Object)
10501 DECL_ACCESSORS(query, Object)
10502 DECL_ACCESSORS(deleter, Object)
10503 DECL_ACCESSORS(enumerator, Object)
10504 DECL_ACCESSORS(data, Object)
10505 DECL_BOOLEAN_ACCESSORS(can_intercept_symbols)
10506 DECL_BOOLEAN_ACCESSORS(all_can_read)
10507 DECL_BOOLEAN_ACCESSORS(non_masking)
10508
10509 inline int flags() const;
10510 inline void set_flags(int flags);
10511
10512 DECLARE_CAST(InterceptorInfo)
10513
10514 // Dispatched behavior.
10515 DECLARE_PRINTER(InterceptorInfo)
10516 DECLARE_VERIFIER(InterceptorInfo)
10517
10518 static const int kGetterOffset = HeapObject::kHeaderSize;
10519 static const int kSetterOffset = kGetterOffset + kPointerSize;
10520 static const int kQueryOffset = kSetterOffset + kPointerSize;
10521 static const int kDeleterOffset = kQueryOffset + kPointerSize;
10522 static const int kEnumeratorOffset = kDeleterOffset + kPointerSize;
10523 static const int kDataOffset = kEnumeratorOffset + kPointerSize;
10524 static const int kFlagsOffset = kDataOffset + kPointerSize;
10525 static const int kSize = kFlagsOffset + kPointerSize;
10526
10527 static const int kCanInterceptSymbolsBit = 0;
10528 static const int kAllCanReadBit = 1;
10529 static const int kNonMasking = 2;
10530
10531 private:
10532 DISALLOW_IMPLICIT_CONSTRUCTORS(InterceptorInfo);
10533 };
10534
10535
10536 class CallHandlerInfo: public Struct {
10537 public:
10538 DECL_ACCESSORS(callback, Object)
10539 DECL_ACCESSORS(data, Object)
10540 DECL_ACCESSORS(fast_handler, Object)
10541
10542 DECLARE_CAST(CallHandlerInfo)
10543
10544 // Dispatched behavior.
10545 DECLARE_PRINTER(CallHandlerInfo)
10546 DECLARE_VERIFIER(CallHandlerInfo)
10547
10548 static const int kCallbackOffset = HeapObject::kHeaderSize;
10549 static const int kDataOffset = kCallbackOffset + kPointerSize;
10550 static const int kFastHandlerOffset = kDataOffset + kPointerSize;
10551 static const int kSize = kFastHandlerOffset + kPointerSize;
10552
10553 private:
10554 DISALLOW_IMPLICIT_CONSTRUCTORS(CallHandlerInfo);
10555 };
10556
10557
10558 class TemplateInfo: public Struct {
10559 public:
10560 DECL_ACCESSORS(tag, Object)
10561 DECL_ACCESSORS(serial_number, Object)
10562 DECL_INT_ACCESSORS(number_of_properties)
10563 DECL_ACCESSORS(property_list, Object)
10564 DECL_ACCESSORS(property_accessors, Object)
10565
10566 DECLARE_VERIFIER(TemplateInfo)
10567
10568 static const int kTagOffset = HeapObject::kHeaderSize;
10569 static const int kSerialNumberOffset = kTagOffset + kPointerSize;
10570 static const int kNumberOfProperties = kSerialNumberOffset + kPointerSize;
10571 static const int kPropertyListOffset = kNumberOfProperties + kPointerSize;
10572 static const int kPropertyAccessorsOffset =
10573 kPropertyListOffset + kPointerSize;
10574 static const int kPropertyIntrinsicsOffset =
10575 kPropertyAccessorsOffset + kPointerSize;
10576 static const int kHeaderSize = kPropertyIntrinsicsOffset + kPointerSize;
10577
10578 private:
10579 DISALLOW_IMPLICIT_CONSTRUCTORS(TemplateInfo);
10580 };
10581
10582
10583 class FunctionTemplateInfo: public TemplateInfo {
10584 public:
10585 DECL_ACCESSORS(call_code, Object)
10586 DECL_ACCESSORS(prototype_template, Object)
10587 DECL_ACCESSORS(parent_template, Object)
10588 DECL_ACCESSORS(named_property_handler, Object)
10589 DECL_ACCESSORS(indexed_property_handler, Object)
10590 DECL_ACCESSORS(instance_template, Object)
10591 DECL_ACCESSORS(class_name, Object)
10592 DECL_ACCESSORS(signature, Object)
10593 DECL_ACCESSORS(instance_call_handler, Object)
10594 DECL_ACCESSORS(access_check_info, Object)
10595 DECL_ACCESSORS(shared_function_info, Object)
10596 DECL_INT_ACCESSORS(flag)
10597
10598 inline int length() const;
10599 inline void set_length(int value);
10600
10601 // Following properties use flag bits.
10602 DECL_BOOLEAN_ACCESSORS(hidden_prototype)
10603 DECL_BOOLEAN_ACCESSORS(undetectable)
10604 // If the bit is set, object instances created by this function
10605 // requires access check.
10606 DECL_BOOLEAN_ACCESSORS(needs_access_check)
10607 DECL_BOOLEAN_ACCESSORS(read_only_prototype)
10608 DECL_BOOLEAN_ACCESSORS(remove_prototype)
10609 DECL_BOOLEAN_ACCESSORS(do_not_cache)
10610 DECL_BOOLEAN_ACCESSORS(accept_any_receiver)
10611
10612 DECLARE_CAST(FunctionTemplateInfo)
10613
10614 // Dispatched behavior.
10615 DECLARE_PRINTER(FunctionTemplateInfo)
10616 DECLARE_VERIFIER(FunctionTemplateInfo)
10617
10618 static const int kCallCodeOffset = TemplateInfo::kHeaderSize;
10619 static const int kPrototypeTemplateOffset =
10620 kCallCodeOffset + kPointerSize;
10621 static const int kParentTemplateOffset =
10622 kPrototypeTemplateOffset + kPointerSize;
10623 static const int kNamedPropertyHandlerOffset =
10624 kParentTemplateOffset + kPointerSize;
10625 static const int kIndexedPropertyHandlerOffset =
10626 kNamedPropertyHandlerOffset + kPointerSize;
10627 static const int kInstanceTemplateOffset =
10628 kIndexedPropertyHandlerOffset + kPointerSize;
10629 static const int kClassNameOffset = kInstanceTemplateOffset + kPointerSize;
10630 static const int kSignatureOffset = kClassNameOffset + kPointerSize;
10631 static const int kInstanceCallHandlerOffset = kSignatureOffset + kPointerSize;
10632 static const int kAccessCheckInfoOffset =
10633 kInstanceCallHandlerOffset + kPointerSize;
10634 static const int kSharedFunctionInfoOffset =
10635 kAccessCheckInfoOffset + kPointerSize;
10636 static const int kFlagOffset = kSharedFunctionInfoOffset + kPointerSize;
10637 static const int kLengthOffset = kFlagOffset + kPointerSize;
10638 static const int kSize = kLengthOffset + kPointerSize;
10639
10640 static Handle<SharedFunctionInfo> GetOrCreateSharedFunctionInfo(
10641 Isolate* isolate, Handle<FunctionTemplateInfo> info);
10642 // Returns true if |object| is an instance of this function template.
10643 inline bool IsTemplateFor(JSObject* object);
10644 bool IsTemplateFor(Map* map);
10645 inline bool instantiated();
10646
10647 private:
10648 // Bit position in the flag, from least significant bit position.
10649 static const int kHiddenPrototypeBit = 0;
10650 static const int kUndetectableBit = 1;
10651 static const int kNeedsAccessCheckBit = 2;
10652 static const int kReadOnlyPrototypeBit = 3;
10653 static const int kRemovePrototypeBit = 4;
10654 static const int kDoNotCacheBit = 5;
10655 static const int kAcceptAnyReceiver = 6;
10656
10657 DISALLOW_IMPLICIT_CONSTRUCTORS(FunctionTemplateInfo);
10658 };
10659
10660
10661 class ObjectTemplateInfo: public TemplateInfo {
10662 public:
10663 DECL_ACCESSORS(constructor, Object)
10664 DECL_ACCESSORS(internal_field_count, Object)
10665
10666 DECLARE_CAST(ObjectTemplateInfo)
10667
10668 // Dispatched behavior.
10669 DECLARE_PRINTER(ObjectTemplateInfo)
10670 DECLARE_VERIFIER(ObjectTemplateInfo)
10671
10672 static const int kConstructorOffset = TemplateInfo::kHeaderSize;
10673 static const int kInternalFieldCountOffset =
10674 kConstructorOffset + kPointerSize;
10675 static const int kSize = kInternalFieldCountOffset + kPointerSize;
10676 };
10677
10678
10679 // The DebugInfo class holds additional information for a function being
10680 // debugged.
10681 class DebugInfo: public Struct {
10682 public:
10683 // The shared function info for the source being debugged.
10684 DECL_ACCESSORS(shared, SharedFunctionInfo)
10685 // Code object for the patched code. This code object is the code object
10686 // currently active for the function.
10687 DECL_ACCESSORS(abstract_code, AbstractCode)
10688 // Fixed array holding status information for each active break point.
10689 DECL_ACCESSORS(break_points, FixedArray)
10690
10691 // Check if there is a break point at a code offset.
10692 bool HasBreakPoint(int code_offset);
10693 // Get the break point info object for a code offset.
10694 Object* GetBreakPointInfo(int code_offset);
10695 // Clear a break point.
10696 static void ClearBreakPoint(Handle<DebugInfo> debug_info, int code_offset,
10697 Handle<Object> break_point_object);
10698 // Set a break point.
10699 static void SetBreakPoint(Handle<DebugInfo> debug_info, int code_offset,
10700 int source_position, int statement_position,
10701 Handle<Object> break_point_object);
10702 // Get the break point objects for a code offset.
10703 Handle<Object> GetBreakPointObjects(int code_offset);
10704 // Find the break point info holding this break point object.
10705 static Handle<Object> FindBreakPointInfo(Handle<DebugInfo> debug_info,
10706 Handle<Object> break_point_object);
10707 // Get the number of break points for this function.
10708 int GetBreakPointCount();
10709
uninitialized()10710 static Smi* uninitialized() { return Smi::FromInt(0); }
10711
10712 inline BytecodeArray* original_bytecode_array();
10713
10714 DECLARE_CAST(DebugInfo)
10715
10716 // Dispatched behavior.
10717 DECLARE_PRINTER(DebugInfo)
10718 DECLARE_VERIFIER(DebugInfo)
10719
10720 static const int kSharedFunctionInfoIndex = Struct::kHeaderSize;
10721 static const int kAbstractCodeIndex = kSharedFunctionInfoIndex + kPointerSize;
10722 static const int kBreakPointsStateIndex = kAbstractCodeIndex + kPointerSize;
10723 static const int kSize = kBreakPointsStateIndex + kPointerSize;
10724
10725 static const int kEstimatedNofBreakPointsInFunction = 16;
10726
10727 private:
10728 static const int kNoBreakPointInfo = -1;
10729
10730 // Lookup the index in the break_points array for a code offset.
10731 int GetBreakPointInfoIndex(int code_offset);
10732
10733 DISALLOW_IMPLICIT_CONSTRUCTORS(DebugInfo);
10734 };
10735
10736
10737 // The BreakPointInfo class holds information for break points set in a
10738 // function. The DebugInfo object holds a BreakPointInfo object for each code
10739 // position with one or more break points.
10740 class BreakPointInfo: public Struct {
10741 public:
10742 // The code offset for the break point.
10743 DECL_INT_ACCESSORS(code_offset)
10744 // The position in the source for the break position.
10745 DECL_INT_ACCESSORS(source_position)
10746 // The position in the source for the last statement before this break
10747 // position.
10748 DECL_INT_ACCESSORS(statement_position)
10749 // List of related JavaScript break points.
10750 DECL_ACCESSORS(break_point_objects, Object)
10751
10752 // Removes a break point.
10753 static void ClearBreakPoint(Handle<BreakPointInfo> info,
10754 Handle<Object> break_point_object);
10755 // Set a break point.
10756 static void SetBreakPoint(Handle<BreakPointInfo> info,
10757 Handle<Object> break_point_object);
10758 // Check if break point info has this break point object.
10759 static bool HasBreakPointObject(Handle<BreakPointInfo> info,
10760 Handle<Object> break_point_object);
10761 // Get the number of break points for this code offset.
10762 int GetBreakPointCount();
10763
10764 DECLARE_CAST(BreakPointInfo)
10765
10766 // Dispatched behavior.
10767 DECLARE_PRINTER(BreakPointInfo)
10768 DECLARE_VERIFIER(BreakPointInfo)
10769
10770 static const int kCodeOffsetIndex = Struct::kHeaderSize;
10771 static const int kSourcePositionIndex = kCodeOffsetIndex + kPointerSize;
10772 static const int kStatementPositionIndex =
10773 kSourcePositionIndex + kPointerSize;
10774 static const int kBreakPointObjectsIndex =
10775 kStatementPositionIndex + kPointerSize;
10776 static const int kSize = kBreakPointObjectsIndex + kPointerSize;
10777
10778 private:
10779 DISALLOW_IMPLICIT_CONSTRUCTORS(BreakPointInfo);
10780 };
10781
10782
10783 #undef DECL_BOOLEAN_ACCESSORS
10784 #undef DECL_ACCESSORS
10785 #undef DECLARE_CAST
10786 #undef DECLARE_VERIFIER
10787
10788 #define VISITOR_SYNCHRONIZATION_TAGS_LIST(V) \
10789 V(kStringTable, "string_table", "(Internalized strings)") \
10790 V(kExternalStringsTable, "external_strings_table", "(External strings)") \
10791 V(kStrongRootList, "strong_root_list", "(Strong roots)") \
10792 V(kSmiRootList, "smi_root_list", "(Smi roots)") \
10793 V(kBootstrapper, "bootstrapper", "(Bootstrapper)") \
10794 V(kTop, "top", "(Isolate)") \
10795 V(kRelocatable, "relocatable", "(Relocatable)") \
10796 V(kDebug, "debug", "(Debugger)") \
10797 V(kCompilationCache, "compilationcache", "(Compilation cache)") \
10798 V(kHandleScope, "handlescope", "(Handle scope)") \
10799 V(kDispatchTable, "dispatchtable", "(Dispatch table)") \
10800 V(kBuiltins, "builtins", "(Builtins)") \
10801 V(kGlobalHandles, "globalhandles", "(Global handles)") \
10802 V(kEternalHandles, "eternalhandles", "(Eternal handles)") \
10803 V(kThreadManager, "threadmanager", "(Thread manager)") \
10804 V(kStrongRoots, "strong roots", "(Strong roots)") \
10805 V(kExtensions, "Extensions", "(Extensions)")
10806
10807 class VisitorSynchronization : public AllStatic {
10808 public:
10809 #define DECLARE_ENUM(enum_item, ignore1, ignore2) enum_item,
10810 enum SyncTag {
10811 VISITOR_SYNCHRONIZATION_TAGS_LIST(DECLARE_ENUM)
10812 kNumberOfSyncTags
10813 };
10814 #undef DECLARE_ENUM
10815
10816 static const char* const kTags[kNumberOfSyncTags];
10817 static const char* const kTagNames[kNumberOfSyncTags];
10818 };
10819
10820 // Abstract base class for visiting, and optionally modifying, the
10821 // pointers contained in Objects. Used in GC and serialization/deserialization.
10822 class ObjectVisitor BASE_EMBEDDED {
10823 public:
~ObjectVisitor()10824 virtual ~ObjectVisitor() {}
10825
10826 // Visits a contiguous arrays of pointers in the half-open range
10827 // [start, end). Any or all of the values may be modified on return.
10828 virtual void VisitPointers(Object** start, Object** end) = 0;
10829
10830 // Handy shorthand for visiting a single pointer.
VisitPointer(Object ** p)10831 virtual void VisitPointer(Object** p) { VisitPointers(p, p + 1); }
10832
10833 // Visit weak next_code_link in Code object.
VisitNextCodeLink(Object ** p)10834 virtual void VisitNextCodeLink(Object** p) { VisitPointers(p, p + 1); }
10835
10836 // To allow lazy clearing of inline caches the visitor has
10837 // a rich interface for iterating over Code objects..
10838
10839 // Visits a code target in the instruction stream.
10840 virtual void VisitCodeTarget(RelocInfo* rinfo);
10841
10842 // Visits a code entry in a JS function.
10843 virtual void VisitCodeEntry(Address entry_address);
10844
10845 // Visits a global property cell reference in the instruction stream.
10846 virtual void VisitCell(RelocInfo* rinfo);
10847
10848 // Visits a runtime entry in the instruction stream.
VisitRuntimeEntry(RelocInfo * rinfo)10849 virtual void VisitRuntimeEntry(RelocInfo* rinfo) {}
10850
10851 // Visits the resource of an one-byte or two-byte string.
VisitExternalOneByteString(v8::String::ExternalOneByteStringResource ** resource)10852 virtual void VisitExternalOneByteString(
10853 v8::String::ExternalOneByteStringResource** resource) {}
VisitExternalTwoByteString(v8::String::ExternalStringResource ** resource)10854 virtual void VisitExternalTwoByteString(
10855 v8::String::ExternalStringResource** resource) {}
10856
10857 // Visits a debug call target in the instruction stream.
10858 virtual void VisitDebugTarget(RelocInfo* rinfo);
10859
10860 // Visits the byte sequence in a function's prologue that contains information
10861 // about the code's age.
10862 virtual void VisitCodeAgeSequence(RelocInfo* rinfo);
10863
10864 // Visit pointer embedded into a code object.
10865 virtual void VisitEmbeddedPointer(RelocInfo* rinfo);
10866
10867 // Visits an external reference embedded into a code object.
10868 virtual void VisitExternalReference(RelocInfo* rinfo);
10869
10870 // Visits an external reference.
VisitExternalReference(Address * p)10871 virtual void VisitExternalReference(Address* p) {}
10872
10873 // Visits an (encoded) internal reference.
VisitInternalReference(RelocInfo * rinfo)10874 virtual void VisitInternalReference(RelocInfo* rinfo) {}
10875
10876 // Visits a handle that has an embedder-assigned class ID.
VisitEmbedderReference(Object ** p,uint16_t class_id)10877 virtual void VisitEmbedderReference(Object** p, uint16_t class_id) {}
10878
10879 // Intended for serialization/deserialization checking: insert, or
10880 // check for the presence of, a tag at this position in the stream.
10881 // Also used for marking up GC roots in heap snapshots.
Synchronize(VisitorSynchronization::SyncTag tag)10882 virtual void Synchronize(VisitorSynchronization::SyncTag tag) {}
10883 };
10884
10885
10886 // BooleanBit is a helper class for setting and getting a bit in an integer.
10887 class BooleanBit : public AllStatic {
10888 public:
get(int value,int bit_position)10889 static inline bool get(int value, int bit_position) {
10890 return (value & (1 << bit_position)) != 0;
10891 }
10892
set(int value,int bit_position,bool v)10893 static inline int set(int value, int bit_position, bool v) {
10894 if (v) {
10895 value |= (1 << bit_position);
10896 } else {
10897 value &= ~(1 << bit_position);
10898 }
10899 return value;
10900 }
10901 };
10902
10903
10904 } // NOLINT, false-positive due to second-order macros.
10905 } // NOLINT, false-positive due to second-order macros.
10906
10907 #endif // V8_OBJECTS_H_
10908