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