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