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 static const int kMaxInObjectProperties =
2548 (kMaxInstanceSize - kHeaderSize) >> kPointerSizeLog2;
2549 STATIC_ASSERT(kMaxInObjectProperties <= kMaxNumberOfDescriptors);
2550
2551 typedef FlexibleBodyDescriptor<JSReceiver::kPropertiesOffset> BodyDescriptor;
2552
2553 // Gets the number of currently used elements.
2554 int GetFastElementsUsage();
2555
2556 static bool AllCanRead(LookupIterator* it);
2557 static bool AllCanWrite(LookupIterator* it);
2558
2559 private:
2560 friend class JSReceiver;
2561 friend class Object;
2562
2563 // Used from Object::GetProperty().
2564 MUST_USE_RESULT static MaybeHandle<Object> GetPropertyWithFailedAccessCheck(
2565 LookupIterator* it);
2566
2567 MUST_USE_RESULT static Maybe<bool> SetPropertyWithFailedAccessCheck(
2568 LookupIterator* it, Handle<Object> value, ShouldThrow should_throw);
2569
2570 MUST_USE_RESULT static Maybe<bool> DeletePropertyWithInterceptor(
2571 LookupIterator* it, ShouldThrow should_throw);
2572
2573 bool ReferencesObjectFromElements(FixedArray* elements,
2574 ElementsKind kind,
2575 Object* object);
2576
2577 static Object* GetIdentityHash(Isolate* isolate, Handle<JSObject> object);
2578
2579 static Smi* GetOrCreateIdentityHash(Isolate* isolate,
2580 Handle<JSObject> object);
2581
2582 // Helper for fast versions of preventExtensions, seal, and freeze.
2583 // attrs is one of NONE, SEALED, or FROZEN (depending on the operation).
2584 template <PropertyAttributes attrs>
2585 MUST_USE_RESULT static Maybe<bool> PreventExtensionsWithTransition(
2586 Handle<JSObject> object, ShouldThrow should_throw);
2587
2588 DISALLOW_IMPLICIT_CONSTRUCTORS(JSObject);
2589 };
2590
2591
2592 // JSAccessorPropertyDescriptor is just a JSObject with a specific initial
2593 // map. This initial map adds in-object properties for "get", "set",
2594 // "enumerable" and "configurable" properties, as assigned by the
2595 // FromPropertyDescriptor function for regular accessor properties.
2596 class JSAccessorPropertyDescriptor: public JSObject {
2597 public:
2598 // Offsets of object fields.
2599 static const int kGetOffset = JSObject::kHeaderSize;
2600 static const int kSetOffset = kGetOffset + kPointerSize;
2601 static const int kEnumerableOffset = kSetOffset + kPointerSize;
2602 static const int kConfigurableOffset = kEnumerableOffset + kPointerSize;
2603 static const int kSize = kConfigurableOffset + kPointerSize;
2604 // Indices of in-object properties.
2605 static const int kGetIndex = 0;
2606 static const int kSetIndex = 1;
2607 static const int kEnumerableIndex = 2;
2608 static const int kConfigurableIndex = 3;
2609
2610 private:
2611 DISALLOW_IMPLICIT_CONSTRUCTORS(JSAccessorPropertyDescriptor);
2612 };
2613
2614
2615 // JSDataPropertyDescriptor is just a JSObject with a specific initial map.
2616 // This initial map adds in-object properties for "value", "writable",
2617 // "enumerable" and "configurable" properties, as assigned by the
2618 // FromPropertyDescriptor function for regular data properties.
2619 class JSDataPropertyDescriptor: public JSObject {
2620 public:
2621 // Offsets of object fields.
2622 static const int kValueOffset = JSObject::kHeaderSize;
2623 static const int kWritableOffset = kValueOffset + kPointerSize;
2624 static const int kEnumerableOffset = kWritableOffset + kPointerSize;
2625 static const int kConfigurableOffset = kEnumerableOffset + kPointerSize;
2626 static const int kSize = kConfigurableOffset + kPointerSize;
2627 // Indices of in-object properties.
2628 static const int kValueIndex = 0;
2629 static const int kWritableIndex = 1;
2630 static const int kEnumerableIndex = 2;
2631 static const int kConfigurableIndex = 3;
2632
2633 private:
2634 DISALLOW_IMPLICIT_CONSTRUCTORS(JSDataPropertyDescriptor);
2635 };
2636
2637
2638 // JSIteratorResult is just a JSObject with a specific initial map.
2639 // This initial map adds in-object properties for "done" and "value",
2640 // as specified by ES6 section 25.1.1.3 The IteratorResult Interface
2641 class JSIteratorResult: public JSObject {
2642 public:
2643 DECL_ACCESSORS(value, Object)
2644
2645 DECL_ACCESSORS(done, Object)
2646
2647 // Offsets of object fields.
2648 static const int kValueOffset = JSObject::kHeaderSize;
2649 static const int kDoneOffset = kValueOffset + kPointerSize;
2650 static const int kSize = kDoneOffset + kPointerSize;
2651 // Indices of in-object properties.
2652 static const int kValueIndex = 0;
2653 static const int kDoneIndex = 1;
2654
2655 private:
2656 DISALLOW_IMPLICIT_CONSTRUCTORS(JSIteratorResult);
2657 };
2658
2659
2660 // Common superclass for JSSloppyArgumentsObject and JSStrictArgumentsObject.
2661 class JSArgumentsObject: public JSObject {
2662 public:
2663 // Offsets of object fields.
2664 static const int kLengthOffset = JSObject::kHeaderSize;
2665 static const int kHeaderSize = kLengthOffset + kPointerSize;
2666 // Indices of in-object properties.
2667 static const int kLengthIndex = 0;
2668
2669 private:
2670 DISALLOW_IMPLICIT_CONSTRUCTORS(JSArgumentsObject);
2671 };
2672
2673
2674 // JSSloppyArgumentsObject is just a JSObject with specific initial map.
2675 // This initial map adds in-object properties for "length" and "callee".
2676 class JSSloppyArgumentsObject: public JSArgumentsObject {
2677 public:
2678 // Offsets of object fields.
2679 static const int kCalleeOffset = JSArgumentsObject::kHeaderSize;
2680 static const int kSize = kCalleeOffset + kPointerSize;
2681 // Indices of in-object properties.
2682 static const int kCalleeIndex = 1;
2683
2684 private:
2685 DISALLOW_IMPLICIT_CONSTRUCTORS(JSSloppyArgumentsObject);
2686 };
2687
2688
2689 // JSStrictArgumentsObject is just a JSObject with specific initial map.
2690 // This initial map adds an in-object property for "length".
2691 class JSStrictArgumentsObject: public JSArgumentsObject {
2692 public:
2693 // Offsets of object fields.
2694 static const int kSize = JSArgumentsObject::kHeaderSize;
2695
2696 private:
2697 DISALLOW_IMPLICIT_CONSTRUCTORS(JSStrictArgumentsObject);
2698 };
2699
2700
2701 // Common superclass for FixedArrays that allow implementations to share
2702 // common accessors and some code paths.
2703 class FixedArrayBase: public HeapObject {
2704 public:
2705 // [length]: length of the array.
2706 inline int length() const;
2707 inline void set_length(int value);
2708
2709 // Get and set the length using acquire loads and release stores.
2710 inline int synchronized_length() const;
2711 inline void synchronized_set_length(int value);
2712
2713 DECLARE_CAST(FixedArrayBase)
2714
2715 static int GetMaxLengthForNewSpaceAllocation(ElementsKind kind);
2716
2717 // Layout description.
2718 // Length is smi tagged when it is stored.
2719 static const int kLengthOffset = HeapObject::kHeaderSize;
2720 static const int kHeaderSize = kLengthOffset + kPointerSize;
2721 };
2722
2723
2724 class FixedDoubleArray;
2725 class IncrementalMarking;
2726
2727
2728 // FixedArray describes fixed-sized arrays with element type Object*.
2729 class FixedArray: public FixedArrayBase {
2730 public:
2731 // Setter and getter for elements.
2732 inline Object* get(int index) const;
2733 static inline Handle<Object> get(FixedArray* array, int index,
2734 Isolate* isolate);
2735 template <class T>
2736 MaybeHandle<T> GetValue(Isolate* isolate, int index) const;
2737
2738 template <class T>
2739 Handle<T> GetValueChecked(Isolate* isolate, int index) const;
2740
2741 // Return a grown copy if the index is bigger than the array's length.
2742 static Handle<FixedArray> SetAndGrow(Handle<FixedArray> array, int index,
2743 Handle<Object> value);
2744
2745 // Setter that uses write barrier.
2746 inline void set(int index, Object* value);
2747 inline bool is_the_hole(Isolate* isolate, int index);
2748
2749 // Setter that doesn't need write barrier.
2750 inline void set(int index, Smi* value);
2751 // Setter with explicit barrier mode.
2752 inline void set(int index, Object* value, WriteBarrierMode mode);
2753
2754 // Setters for frequently used oddballs located in old space.
2755 inline void set_undefined(int index);
2756 inline void set_undefined(Isolate* isolate, int index);
2757 inline void set_null(int index);
2758 inline void set_null(Isolate* isolate, int index);
2759 inline void set_the_hole(int index);
2760 inline void set_the_hole(Isolate* isolate, int index);
2761
2762 inline Object** GetFirstElementAddress();
2763 inline bool ContainsOnlySmisOrHoles();
2764
2765 // Gives access to raw memory which stores the array's data.
2766 inline Object** data_start();
2767
2768 inline void FillWithHoles(int from, int to);
2769
2770 // Shrink length and insert filler objects.
2771 void Shrink(int length);
2772
2773 // Copy a sub array from the receiver to dest.
2774 void CopyTo(int pos, FixedArray* dest, int dest_pos, int len);
2775
2776 // Garbage collection support.
SizeFor(int length)2777 static constexpr int SizeFor(int length) {
2778 return kHeaderSize + length * kPointerSize;
2779 }
2780
2781 // Code Generation support.
OffsetOfElementAt(int index)2782 static constexpr int OffsetOfElementAt(int index) { return SizeFor(index); }
2783
2784 // Garbage collection support.
2785 inline Object** RawFieldOfElementAt(int index);
2786
2787 DECLARE_CAST(FixedArray)
2788
2789 // Maximal allowed size, in bytes, of a single FixedArray.
2790 // Prevents overflowing size computations, as well as extreme memory
2791 // consumption.
2792 static const int kMaxSize = 128 * MB * kPointerSize;
2793 // Maximally allowed length of a FixedArray.
2794 static const int kMaxLength = (kMaxSize - kHeaderSize) / kPointerSize;
2795
2796 // Dispatched behavior.
2797 DECLARE_PRINTER(FixedArray)
2798 DECLARE_VERIFIER(FixedArray)
2799 #ifdef DEBUG
2800 // Checks if two FixedArrays have identical contents.
2801 bool IsEqualTo(FixedArray* other);
2802 #endif
2803
2804 typedef FlexibleBodyDescriptor<kHeaderSize> BodyDescriptor;
2805
2806 protected:
2807 // Set operation on FixedArray without using write barriers. Can
2808 // only be used for storing old space objects or smis.
2809 static inline void NoWriteBarrierSet(FixedArray* array,
2810 int index,
2811 Object* value);
2812
2813 private:
2814 STATIC_ASSERT(kHeaderSize == Internals::kFixedArrayHeaderSize);
2815
2816 DISALLOW_IMPLICIT_CONSTRUCTORS(FixedArray);
2817 };
2818
2819 // FixedDoubleArray describes fixed-sized arrays with element type double.
2820 class FixedDoubleArray: public FixedArrayBase {
2821 public:
2822 // Setter and getter for elements.
2823 inline double get_scalar(int index);
2824 inline uint64_t get_representation(int index);
2825 static inline Handle<Object> get(FixedDoubleArray* array, int index,
2826 Isolate* isolate);
2827 inline void set(int index, double value);
2828 inline void set_the_hole(Isolate* isolate, int index);
2829 inline void set_the_hole(int index);
2830
2831 // Checking for the hole.
2832 inline bool is_the_hole(Isolate* isolate, int index);
2833 inline bool is_the_hole(int index);
2834
2835 // Garbage collection support.
SizeFor(int length)2836 inline static int SizeFor(int length) {
2837 return kHeaderSize + length * kDoubleSize;
2838 }
2839
2840 // Gives access to raw memory which stores the array's data.
2841 inline double* data_start();
2842
2843 inline void FillWithHoles(int from, int to);
2844
2845 // Code Generation support.
OffsetOfElementAt(int index)2846 static int OffsetOfElementAt(int index) { return SizeFor(index); }
2847
2848 DECLARE_CAST(FixedDoubleArray)
2849
2850 // Maximal allowed size, in bytes, of a single FixedDoubleArray.
2851 // Prevents overflowing size computations, as well as extreme memory
2852 // consumption.
2853 static const int kMaxSize = 512 * MB;
2854 // Maximally allowed length of a FixedArray.
2855 static const int kMaxLength = (kMaxSize - kHeaderSize) / kDoubleSize;
2856
2857 // Dispatched behavior.
2858 DECLARE_PRINTER(FixedDoubleArray)
2859 DECLARE_VERIFIER(FixedDoubleArray)
2860
2861 private:
2862 DISALLOW_IMPLICIT_CONSTRUCTORS(FixedDoubleArray);
2863 };
2864
2865
2866 class WeakFixedArray : public FixedArray {
2867 public:
2868 // If |maybe_array| is not a WeakFixedArray, a fresh one will be allocated.
2869 // This function does not check if the value exists already, callers must
2870 // ensure this themselves if necessary.
2871 static Handle<WeakFixedArray> Add(Handle<Object> maybe_array,
2872 Handle<HeapObject> value,
2873 int* assigned_index = NULL);
2874
2875 // Returns true if an entry was found and removed.
2876 bool Remove(Handle<HeapObject> value);
2877
2878 class NullCallback {
2879 public:
Callback(Object * value,int old_index,int new_index)2880 static void Callback(Object* value, int old_index, int new_index) {}
2881 };
2882
2883 template <class CompactionCallback>
2884 void Compact();
2885
2886 inline Object* Get(int index) const;
2887 inline void Clear(int index);
2888 inline int Length() const;
2889
2890 inline bool IsEmptySlot(int index) const;
Empty()2891 static Object* Empty() { return Smi::kZero; }
2892
2893 class Iterator {
2894 public:
Iterator(Object * maybe_array)2895 explicit Iterator(Object* maybe_array) : list_(NULL) { Reset(maybe_array); }
2896 void Reset(Object* maybe_array);
2897
2898 template <class T>
2899 inline T* Next();
2900
2901 private:
2902 int index_;
2903 WeakFixedArray* list_;
2904 #ifdef DEBUG
2905 int last_used_index_;
2906 DisallowHeapAllocation no_gc_;
2907 #endif // DEBUG
2908 DISALLOW_COPY_AND_ASSIGN(Iterator);
2909 };
2910
2911 DECLARE_CAST(WeakFixedArray)
2912
2913 private:
2914 static const int kLastUsedIndexIndex = 0;
2915 static const int kFirstIndex = 1;
2916
2917 static Handle<WeakFixedArray> Allocate(
2918 Isolate* isolate, int size, Handle<WeakFixedArray> initialize_from);
2919
2920 static void Set(Handle<WeakFixedArray> array, int index,
2921 Handle<HeapObject> value);
2922 inline void clear(int index);
2923
2924 inline int last_used_index() const;
2925 inline void set_last_used_index(int index);
2926
2927 // Disallow inherited setters.
2928 void set(int index, Smi* value);
2929 void set(int index, Object* value);
2930 void set(int index, Object* value, WriteBarrierMode mode);
2931 DISALLOW_IMPLICIT_CONSTRUCTORS(WeakFixedArray);
2932 };
2933
2934 // Generic array grows dynamically with O(1) amortized insertion.
2935 class ArrayList : public FixedArray {
2936 public:
2937 enum AddMode {
2938 kNone,
2939 // Use this if GC can delete elements from the array.
2940 kReloadLengthAfterAllocation,
2941 };
2942 static Handle<ArrayList> Add(Handle<ArrayList> array, Handle<Object> obj,
2943 AddMode mode = kNone);
2944 static Handle<ArrayList> Add(Handle<ArrayList> array, Handle<Object> obj1,
2945 Handle<Object> obj2, AddMode = kNone);
2946 static Handle<ArrayList> New(Isolate* isolate, int size);
2947 inline int Length();
2948 inline void SetLength(int length);
2949 inline Object* Get(int index);
2950 inline Object** Slot(int index);
2951 inline void Set(int index, Object* obj,
2952 WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
2953 inline void Clear(int index, Object* undefined);
2954 bool IsFull();
2955 DECLARE_CAST(ArrayList)
2956
2957 private:
2958 static Handle<ArrayList> EnsureSpace(Handle<ArrayList> array, int length);
2959 static const int kLengthIndex = 0;
2960 static const int kFirstIndex = 1;
2961 DISALLOW_IMPLICIT_CONSTRUCTORS(ArrayList);
2962 };
2963
2964 #define FRAME_ARRAY_FIELD_LIST(V) \
2965 V(WasmInstance, Object) \
2966 V(WasmFunctionIndex, Smi) \
2967 V(Receiver, Object) \
2968 V(Function, JSFunction) \
2969 V(Code, AbstractCode) \
2970 V(Offset, Smi) \
2971 V(Flags, Smi)
2972
2973 // Container object for data collected during simple stack trace captures.
2974 class FrameArray : public FixedArray {
2975 public:
2976 #define DECLARE_FRAME_ARRAY_ACCESSORS(name, type) \
2977 inline type* name(int frame_ix) const; \
2978 inline void Set##name(int frame_ix, type* value);
2979 FRAME_ARRAY_FIELD_LIST(DECLARE_FRAME_ARRAY_ACCESSORS)
2980 #undef DECLARE_FRAME_ARRAY_ACCESSORS
2981
2982 inline bool IsWasmFrame(int frame_ix) const;
2983 inline bool IsAsmJsWasmFrame(int frame_ix) const;
2984 inline int FrameCount() const;
2985
2986 void ShrinkToFit();
2987
2988 // Flags.
2989 static const int kIsWasmFrame = 1 << 0;
2990 static const int kIsAsmJsWasmFrame = 1 << 1;
2991 static const int kIsStrict = 1 << 2;
2992 static const int kForceConstructor = 1 << 3;
2993 static const int kAsmJsAtNumberConversion = 1 << 4;
2994
2995 static Handle<FrameArray> AppendJSFrame(Handle<FrameArray> in,
2996 Handle<Object> receiver,
2997 Handle<JSFunction> function,
2998 Handle<AbstractCode> code, int offset,
2999 int flags);
3000 static Handle<FrameArray> AppendWasmFrame(Handle<FrameArray> in,
3001 Handle<Object> wasm_instance,
3002 int wasm_function_index,
3003 Handle<AbstractCode> code,
3004 int offset, int flags);
3005
3006 DECLARE_CAST(FrameArray)
3007
3008 private:
3009 // The underlying fixed array embodies a captured stack trace. Frame i
3010 // occupies indices
3011 //
3012 // kFirstIndex + 1 + [i * kElementsPerFrame, (i + 1) * kElementsPerFrame[,
3013 //
3014 // with internal offsets as below:
3015
3016 static const int kWasmInstanceOffset = 0;
3017 static const int kWasmFunctionIndexOffset = 1;
3018
3019 static const int kReceiverOffset = 0;
3020 static const int kFunctionOffset = 1;
3021
3022 static const int kCodeOffset = 2;
3023 static const int kOffsetOffset = 3;
3024
3025 static const int kFlagsOffset = 4;
3026
3027 static const int kElementsPerFrame = 5;
3028
3029 // Array layout indices.
3030
3031 static const int kFrameCountIndex = 0;
3032 static const int kFirstIndex = 1;
3033
LengthFor(int frame_count)3034 static int LengthFor(int frame_count) {
3035 return kFirstIndex + frame_count * kElementsPerFrame;
3036 }
3037
3038 static Handle<FrameArray> EnsureSpace(Handle<FrameArray> array, int length);
3039
3040 friend class Factory;
3041 DISALLOW_IMPLICIT_CONSTRUCTORS(FrameArray);
3042 };
3043
3044 // DescriptorArrays are fixed arrays used to hold instance descriptors.
3045 // The format of the these objects is:
3046 // [0]: Number of descriptors
3047 // [1]: Either Smi(0) if uninitialized, or a pointer to small fixed array:
3048 // [0]: pointer to fixed array with enum cache
3049 // [1]: either Smi(0) or pointer to fixed array with indices
3050 // [2]: first key
3051 // [2 + number of descriptors * kEntrySize]: start of slack
3052 class DescriptorArray: public FixedArray {
3053 public:
3054 // Returns true for both shared empty_descriptor_array and for smis, which the
3055 // map uses to encode additional bit fields when the descriptor array is not
3056 // yet used.
3057 inline bool IsEmpty();
3058
3059 // Returns the number of descriptors in the array.
3060 inline int number_of_descriptors();
3061
3062 inline int number_of_descriptors_storage();
3063
3064 inline int NumberOfSlackDescriptors();
3065
3066 inline void SetNumberOfDescriptors(int number_of_descriptors);
3067 inline int number_of_entries();
3068
3069 inline bool HasEnumCache();
3070
3071 inline void CopyEnumCacheFrom(DescriptorArray* array);
3072
3073 inline FixedArray* GetEnumCache();
3074
3075 inline bool HasEnumIndicesCache();
3076
3077 inline FixedArray* GetEnumIndicesCache();
3078
3079 inline Object** GetEnumCacheSlot();
3080
3081 void ClearEnumCache();
3082
3083 // Initialize or change the enum cache,
3084 // using the supplied storage for the small "bridge".
3085 static void SetEnumCache(Handle<DescriptorArray> descriptors,
3086 Isolate* isolate, Handle<FixedArray> new_cache,
3087 Handle<FixedArray> new_index_cache);
3088
3089 // Accessors for fetching instance descriptor at descriptor number.
3090 inline Name* GetKey(int descriptor_number);
3091 inline Object** GetKeySlot(int descriptor_number);
3092 inline Object* GetValue(int descriptor_number);
3093 inline void SetValue(int descriptor_number, Object* value);
3094 inline Object** GetValueSlot(int descriptor_number);
3095 static inline int GetValueOffset(int descriptor_number);
3096 inline Object** GetDescriptorStartSlot(int descriptor_number);
3097 inline Object** GetDescriptorEndSlot(int descriptor_number);
3098 inline PropertyDetails GetDetails(int descriptor_number);
3099 inline int GetFieldIndex(int descriptor_number);
3100 inline FieldType* GetFieldType(int descriptor_number);
3101
3102 inline Name* GetSortedKey(int descriptor_number);
3103 inline int GetSortedKeyIndex(int descriptor_number);
3104 inline void SetSortedKey(int pointer, int descriptor_number);
3105
3106 // Accessor for complete descriptor.
3107 inline void Get(int descriptor_number, Descriptor* desc);
3108 inline void Set(int descriptor_number, Descriptor* desc);
3109 inline void Set(int descriptor_number, Name* key, Object* value,
3110 PropertyDetails details);
3111 void Replace(int descriptor_number, Descriptor* descriptor);
3112
3113 // Generalizes constness, representation and field type of all field
3114 // descriptors.
3115 void GeneralizeAllFields();
3116
3117 // Append automatically sets the enumeration index. This should only be used
3118 // to add descriptors in bulk at the end, followed by sorting the descriptor
3119 // array.
3120 inline void Append(Descriptor* desc);
3121
3122 static Handle<DescriptorArray> CopyUpTo(Handle<DescriptorArray> desc,
3123 int enumeration_index,
3124 int slack = 0);
3125
3126 static Handle<DescriptorArray> CopyUpToAddAttributes(
3127 Handle<DescriptorArray> desc,
3128 int enumeration_index,
3129 PropertyAttributes attributes,
3130 int slack = 0);
3131
3132 // Sort the instance descriptors by the hash codes of their keys.
3133 void Sort();
3134
3135 // Search the instance descriptors for given name.
3136 INLINE(int Search(Name* name, int number_of_own_descriptors));
3137
3138 // As the above, but uses DescriptorLookupCache and updates it when
3139 // necessary.
3140 INLINE(int SearchWithCache(Isolate* isolate, Name* name, Map* map));
3141
3142 bool IsEqualUpTo(DescriptorArray* desc, int nof_descriptors);
3143
3144 // Allocates a DescriptorArray, but returns the singleton
3145 // empty descriptor array object if number_of_descriptors is 0.
3146 static Handle<DescriptorArray> Allocate(
3147 Isolate* isolate, int number_of_descriptors, int slack,
3148 PretenureFlag pretenure = NOT_TENURED);
3149
3150 DECLARE_CAST(DescriptorArray)
3151
3152 // Constant for denoting key was not found.
3153 static const int kNotFound = -1;
3154
3155 static const int kDescriptorLengthIndex = 0;
3156 static const int kEnumCacheIndex = 1;
3157 static const int kFirstIndex = 2;
3158
3159 // The length of the "bridge" to the enum cache.
3160 static const int kEnumCacheBridgeLength = 2;
3161 static const int kEnumCacheBridgeCacheIndex = 0;
3162 static const int kEnumCacheBridgeIndicesCacheIndex = 1;
3163
3164 // Layout description.
3165 static const int kDescriptorLengthOffset = FixedArray::kHeaderSize;
3166 static const int kEnumCacheOffset = kDescriptorLengthOffset + kPointerSize;
3167 static const int kFirstOffset = kEnumCacheOffset + kPointerSize;
3168
3169 // Layout description for the bridge array.
3170 static const int kEnumCacheBridgeCacheOffset = FixedArray::kHeaderSize;
3171
3172 // Layout of descriptor.
3173 // Naming is consistent with Dictionary classes for easy templating.
3174 static const int kEntryKeyIndex = 0;
3175 static const int kEntryDetailsIndex = 1;
3176 static const int kEntryValueIndex = 2;
3177 static const int kEntrySize = 3;
3178
3179 #if defined(DEBUG) || defined(OBJECT_PRINT)
3180 // For our gdb macros, we should perhaps change these in the future.
3181 void Print();
3182
3183 // Print all the descriptors.
3184 void PrintDescriptors(std::ostream& os); // NOLINT
3185
3186 void PrintDescriptorDetails(std::ostream& os, int descriptor,
3187 PropertyDetails::PrintMode mode);
3188 #endif
3189
3190 #ifdef DEBUG
3191 // Is the descriptor array sorted and without duplicates?
3192 bool IsSortedNoDuplicates(int valid_descriptors = -1);
3193
3194 // Is the descriptor array consistent with the back pointers in targets?
3195 bool IsConsistentWithBackPointers(Map* current_map);
3196
3197 // Are two DescriptorArrays equal?
3198 bool IsEqualTo(DescriptorArray* other);
3199 #endif
3200
3201 // Returns the fixed array length required to hold number_of_descriptors
3202 // descriptors.
LengthFor(int number_of_descriptors)3203 static int LengthFor(int number_of_descriptors) {
3204 return ToKeyIndex(number_of_descriptors);
3205 }
3206
ToDetailsIndex(int descriptor_number)3207 static int ToDetailsIndex(int descriptor_number) {
3208 return kFirstIndex + (descriptor_number * kEntrySize) + kEntryDetailsIndex;
3209 }
3210
3211 // Conversion from descriptor number to array indices.
ToKeyIndex(int descriptor_number)3212 static int ToKeyIndex(int descriptor_number) {
3213 return kFirstIndex + (descriptor_number * kEntrySize) + kEntryKeyIndex;
3214 }
3215
ToValueIndex(int descriptor_number)3216 static int ToValueIndex(int descriptor_number) {
3217 return kFirstIndex + (descriptor_number * kEntrySize) + kEntryValueIndex;
3218 }
3219
3220 private:
3221 // Transfer a complete descriptor from the src descriptor array to this
3222 // descriptor array.
3223 void CopyFrom(int index, DescriptorArray* src);
3224
3225 // Swap first and second descriptor.
3226 inline void SwapSortedKeys(int first, int second);
3227
3228 DISALLOW_IMPLICIT_CONSTRUCTORS(DescriptorArray);
3229 };
3230
3231
3232 enum SearchMode { ALL_ENTRIES, VALID_ENTRIES };
3233
3234 template <SearchMode search_mode, typename T>
3235 inline int Search(T* array, Name* name, int valid_entries = 0,
3236 int* out_insertion_index = NULL);
3237
3238
3239 // HashTable is a subclass of FixedArray that implements a hash table
3240 // that uses open addressing and quadratic probing.
3241 //
3242 // In order for the quadratic probing to work, elements that have not
3243 // yet been used and elements that have been deleted are
3244 // distinguished. Probing continues when deleted elements are
3245 // encountered and stops when unused elements are encountered.
3246 //
3247 // - Elements with key == undefined have not been used yet.
3248 // - Elements with key == the_hole have been deleted.
3249 //
3250 // The hash table class is parameterized with a Shape and a Key.
3251 // Shape must be a class with the following interface:
3252 // class ExampleShape {
3253 // public:
3254 // // Tells whether key matches other.
3255 // static bool IsMatch(Key key, Object* other);
3256 // // Returns the hash value for key.
3257 // static uint32_t Hash(Key key);
3258 // // Returns the hash value for object.
3259 // static uint32_t HashForObject(Key key, Object* object);
3260 // // Convert key to an object.
3261 // static inline Handle<Object> AsHandle(Isolate* isolate, Key key);
3262 // // The prefix size indicates number of elements in the beginning
3263 // // of the backing storage.
3264 // static const int kPrefixSize = ..;
3265 // // The Element size indicates number of elements per entry.
3266 // static const int kEntrySize = ..;
3267 // };
3268 // The prefix size indicates an amount of memory in the
3269 // beginning of the backing storage that can be used for non-element
3270 // information by subclasses.
3271
3272 template<typename Key>
3273 class BaseShape {
3274 public:
3275 static const bool UsesSeed = false;
Hash(Key key)3276 static uint32_t Hash(Key key) { return 0; }
SeededHash(Key key,uint32_t seed)3277 static uint32_t SeededHash(Key key, uint32_t seed) {
3278 DCHECK(UsesSeed);
3279 return Hash(key);
3280 }
HashForObject(Key key,Object * object)3281 static uint32_t HashForObject(Key key, Object* object) { return 0; }
SeededHashForObject(Key key,uint32_t seed,Object * object)3282 static uint32_t SeededHashForObject(Key key, uint32_t seed, Object* object) {
3283 DCHECK(UsesSeed);
3284 return HashForObject(key, object);
3285 }
3286 static inline Map* GetMap(Isolate* isolate);
3287 };
3288
3289
3290 class HashTableBase : public FixedArray {
3291 public:
3292 // Returns the number of elements in the hash table.
3293 inline int NumberOfElements();
3294
3295 // Returns the number of deleted elements in the hash table.
3296 inline int NumberOfDeletedElements();
3297
3298 // Returns the capacity of the hash table.
3299 inline int Capacity();
3300
3301 // ElementAdded should be called whenever an element is added to a
3302 // hash table.
3303 inline void ElementAdded();
3304
3305 // ElementRemoved should be called whenever an element is removed from
3306 // a hash table.
3307 inline void ElementRemoved();
3308 inline void ElementsRemoved(int n);
3309
3310 // Computes the required capacity for a table holding the given
3311 // number of elements. May be more than HashTable::kMaxCapacity.
3312 static inline int ComputeCapacity(int at_least_space_for);
3313
3314 // Tells whether k is a real key. The hole and undefined are not allowed
3315 // as keys and can be used to indicate missing or deleted elements.
3316 inline bool IsKey(Object* k);
3317 inline bool IsKey(Isolate* isolate, Object* k);
3318
3319 // Compute the probe offset (quadratic probing).
INLINE(static uint32_t GetProbeOffset (uint32_t n))3320 INLINE(static uint32_t GetProbeOffset(uint32_t n)) {
3321 return (n + n * n) >> 1;
3322 }
3323
3324 static const int kNumberOfElementsIndex = 0;
3325 static const int kNumberOfDeletedElementsIndex = 1;
3326 static const int kCapacityIndex = 2;
3327 static const int kPrefixStartIndex = 3;
3328
3329 // Constant used for denoting a absent entry.
3330 static const int kNotFound = -1;
3331
3332 // Minimum capacity for newly created hash tables.
3333 static const int kMinCapacity = 4;
3334
3335 protected:
3336 // Update the number of elements in the hash table.
3337 inline void SetNumberOfElements(int nof);
3338
3339 // Update the number of deleted elements in the hash table.
3340 inline void SetNumberOfDeletedElements(int nod);
3341
3342 // Returns probe entry.
GetProbe(uint32_t hash,uint32_t number,uint32_t size)3343 static uint32_t GetProbe(uint32_t hash, uint32_t number, uint32_t size) {
3344 DCHECK(base::bits::IsPowerOfTwo32(size));
3345 return (hash + GetProbeOffset(number)) & (size - 1);
3346 }
3347
FirstProbe(uint32_t hash,uint32_t size)3348 inline static uint32_t FirstProbe(uint32_t hash, uint32_t size) {
3349 return hash & (size - 1);
3350 }
3351
NextProbe(uint32_t last,uint32_t number,uint32_t size)3352 inline static uint32_t NextProbe(
3353 uint32_t last, uint32_t number, uint32_t size) {
3354 return (last + number) & (size - 1);
3355 }
3356 };
3357
3358
3359 template <typename Derived, typename Shape, typename Key>
3360 class HashTable : public HashTableBase {
3361 public:
3362 typedef Shape ShapeT;
3363
3364 // Wrapper methods
Hash(Key key)3365 inline uint32_t Hash(Key key) {
3366 if (Shape::UsesSeed) {
3367 return Shape::SeededHash(key, GetHeap()->HashSeed());
3368 } else {
3369 return Shape::Hash(key);
3370 }
3371 }
3372
HashForObject(Key key,Object * object)3373 inline uint32_t HashForObject(Key key, Object* object) {
3374 if (Shape::UsesSeed) {
3375 return Shape::SeededHashForObject(key, GetHeap()->HashSeed(), object);
3376 } else {
3377 return Shape::HashForObject(key, object);
3378 }
3379 }
3380
3381 // Returns a new HashTable object.
3382 MUST_USE_RESULT static Handle<Derived> New(
3383 Isolate* isolate, int at_least_space_for,
3384 MinimumCapacity capacity_option = USE_DEFAULT_MINIMUM_CAPACITY,
3385 PretenureFlag pretenure = NOT_TENURED);
3386
3387 DECLARE_CAST(HashTable)
3388
3389 // Garbage collection support.
3390 void IteratePrefix(ObjectVisitor* visitor);
3391 void IterateElements(ObjectVisitor* visitor);
3392
3393 // Find entry for key otherwise return kNotFound.
3394 inline int FindEntry(Key key);
3395 inline int FindEntry(Isolate* isolate, Key key, int32_t hash);
3396 int FindEntry(Isolate* isolate, Key key);
3397 inline bool Has(Isolate* isolate, Key key);
3398 inline bool Has(Key key);
3399
3400 // Rehashes the table in-place.
3401 void Rehash(Key key);
3402
3403 // Returns the key at entry.
KeyAt(int entry)3404 Object* KeyAt(int entry) { return get(EntryToIndex(entry) + kEntryKeyIndex); }
3405
3406 static const int kElementsStartIndex = kPrefixStartIndex + Shape::kPrefixSize;
3407 static const int kEntrySize = Shape::kEntrySize;
3408 STATIC_ASSERT(kEntrySize > 0);
3409 static const int kEntryKeyIndex = 0;
3410 static const int kElementsStartOffset =
3411 kHeaderSize + kElementsStartIndex * kPointerSize;
3412 // Maximal capacity of HashTable. Based on maximal length of underlying
3413 // FixedArray. Staying below kMaxCapacity also ensures that EntryToIndex
3414 // cannot overflow.
3415 static const int kMaxCapacity =
3416 (FixedArray::kMaxLength - kElementsStartIndex) / kEntrySize;
3417
3418 // Returns the index for an entry (of the key)
EntryToIndex(int entry)3419 static inline int EntryToIndex(int entry) {
3420 return (entry * kEntrySize) + kElementsStartIndex;
3421 }
3422
3423 protected:
3424 friend class ObjectHashTable;
3425
3426 MUST_USE_RESULT static Handle<Derived> New(Isolate* isolate, int capacity,
3427 PretenureFlag pretenure);
3428
3429 // Find the entry at which to insert element with the given key that
3430 // has the given hash value.
3431 uint32_t FindInsertionEntry(uint32_t hash);
3432
3433 // Attempt to shrink hash table after removal of key.
3434 MUST_USE_RESULT static Handle<Derived> Shrink(Handle<Derived> table, Key key);
3435
3436 // Ensure enough space for n additional elements.
3437 MUST_USE_RESULT static Handle<Derived> EnsureCapacity(
3438 Handle<Derived> table,
3439 int n,
3440 Key key,
3441 PretenureFlag pretenure = NOT_TENURED);
3442
3443 // Returns true if this table has sufficient capacity for adding n elements.
3444 bool HasSufficientCapacityToAdd(int number_of_additional_elements);
3445
3446 // Sets the capacity of the hash table.
SetCapacity(int capacity)3447 void SetCapacity(int capacity) {
3448 // To scale a computed hash code to fit within the hash table, we
3449 // use bit-wise AND with a mask, so the capacity must be positive
3450 // and non-zero.
3451 DCHECK(capacity > 0);
3452 DCHECK(capacity <= kMaxCapacity);
3453 set(kCapacityIndex, Smi::FromInt(capacity));
3454 }
3455
3456 private:
3457 // Returns _expected_ if one of entries given by the first _probe_ probes is
3458 // equal to _expected_. Otherwise, returns the entry given by the probe
3459 // number _probe_.
3460 uint32_t EntryForProbe(Key key, Object* k, int probe, uint32_t expected);
3461
3462 void Swap(uint32_t entry1, uint32_t entry2, WriteBarrierMode mode);
3463
3464 // Rehashes this hash-table into the new table.
3465 void Rehash(Handle<Derived> new_table, Key key);
3466 };
3467
3468
3469 // HashTableKey is an abstract superclass for virtual key behavior.
3470 class HashTableKey {
3471 public:
3472 // Returns whether the other object matches this key.
3473 virtual bool IsMatch(Object* other) = 0;
3474 // Returns the hash value for this key.
3475 virtual uint32_t Hash() = 0;
3476 // Returns the hash value for object.
3477 virtual uint32_t HashForObject(Object* key) = 0;
3478 // Returns the key object for storing into the hash table.
3479 MUST_USE_RESULT virtual Handle<Object> AsHandle(Isolate* isolate) = 0;
3480 // Required.
~HashTableKey()3481 virtual ~HashTableKey() {}
3482 };
3483
3484
3485 class StringTableShape : public BaseShape<HashTableKey*> {
3486 public:
IsMatch(HashTableKey * key,Object * value)3487 static inline bool IsMatch(HashTableKey* key, Object* value) {
3488 return key->IsMatch(value);
3489 }
3490
Hash(HashTableKey * key)3491 static inline uint32_t Hash(HashTableKey* key) {
3492 return key->Hash();
3493 }
3494
HashForObject(HashTableKey * key,Object * object)3495 static inline uint32_t HashForObject(HashTableKey* key, Object* object) {
3496 return key->HashForObject(object);
3497 }
3498
3499 static inline Handle<Object> AsHandle(Isolate* isolate, HashTableKey* key);
3500
3501 static const int kPrefixSize = 0;
3502 static const int kEntrySize = 1;
3503 };
3504
3505 class SeqOneByteString;
3506
3507 // StringTable.
3508 //
3509 // No special elements in the prefix and the element size is 1
3510 // because only the string itself (the key) needs to be stored.
3511 class StringTable: public HashTable<StringTable,
3512 StringTableShape,
3513 HashTableKey*> {
3514 public:
3515 // Find string in the string table. If it is not there yet, it is
3516 // added. The return value is the string found.
3517 V8_EXPORT_PRIVATE static Handle<String> LookupString(Isolate* isolate,
3518 Handle<String> key);
3519 static Handle<String> LookupKey(Isolate* isolate, HashTableKey* key);
3520 static String* LookupKeyIfExists(Isolate* isolate, HashTableKey* key);
3521
3522 // Tries to internalize given string and returns string handle on success
3523 // or an empty handle otherwise.
3524 MUST_USE_RESULT static MaybeHandle<String> InternalizeStringIfExists(
3525 Isolate* isolate,
3526 Handle<String> string);
3527
3528 // Looks up a string that is equal to the given string and returns
3529 // string handle if it is found, or an empty handle otherwise.
3530 MUST_USE_RESULT static MaybeHandle<String> LookupStringIfExists(
3531 Isolate* isolate,
3532 Handle<String> str);
3533 MUST_USE_RESULT static MaybeHandle<String> LookupTwoCharsStringIfExists(
3534 Isolate* isolate,
3535 uint16_t c1,
3536 uint16_t c2);
3537
3538 static void EnsureCapacityForDeserialization(Isolate* isolate, int expected);
3539
3540 DECLARE_CAST(StringTable)
3541
3542 private:
3543 template <bool seq_one_byte>
3544 friend class JsonParser;
3545
3546 DISALLOW_IMPLICIT_CONSTRUCTORS(StringTable);
3547 };
3548
3549 class StringSetShape : public BaseShape<String*> {
3550 public:
3551 static inline bool IsMatch(String* key, Object* value);
3552 static inline uint32_t Hash(String* key);
3553 static inline uint32_t HashForObject(String* key, Object* object);
3554
3555 static const int kPrefixSize = 0;
3556 static const int kEntrySize = 1;
3557 };
3558
3559 class StringSet : public HashTable<StringSet, StringSetShape, String*> {
3560 public:
3561 static Handle<StringSet> New(Isolate* isolate);
3562 static Handle<StringSet> Add(Handle<StringSet> blacklist,
3563 Handle<String> name);
3564 bool Has(Handle<String> name);
3565
3566 DECLARE_CAST(StringSet)
3567 };
3568
3569 template <typename Derived, typename Shape, typename Key>
3570 class Dictionary: public HashTable<Derived, Shape, Key> {
3571 typedef HashTable<Derived, Shape, Key> DerivedHashTable;
3572
3573 public:
3574 // Returns the value at entry.
ValueAt(int entry)3575 Object* ValueAt(int entry) {
3576 return this->get(Derived::EntryToIndex(entry) + 1);
3577 }
3578
3579 // Set the value for entry.
ValueAtPut(int entry,Object * value)3580 void ValueAtPut(int entry, Object* value) {
3581 this->set(Derived::EntryToIndex(entry) + 1, value);
3582 }
3583
3584 // Returns the property details for the property at entry.
DetailsAt(int entry)3585 PropertyDetails DetailsAt(int entry) {
3586 return Shape::DetailsAt(static_cast<Derived*>(this), entry);
3587 }
3588
3589 // Set the details for entry.
DetailsAtPut(int entry,PropertyDetails value)3590 void DetailsAtPut(int entry, PropertyDetails value) {
3591 Shape::DetailsAtPut(static_cast<Derived*>(this), entry, value);
3592 }
3593
3594 // Returns true if property at given entry is deleted.
IsDeleted(int entry)3595 bool IsDeleted(int entry) {
3596 return Shape::IsDeleted(static_cast<Derived*>(this), entry);
3597 }
3598
3599 // Delete a property from the dictionary.
3600 static Handle<Object> DeleteProperty(Handle<Derived> dictionary, int entry);
3601
3602 // Attempt to shrink the dictionary after deletion of key.
Shrink(Handle<Derived> dictionary,Key key)3603 MUST_USE_RESULT static inline Handle<Derived> Shrink(
3604 Handle<Derived> dictionary,
3605 Key key) {
3606 return DerivedHashTable::Shrink(dictionary, key);
3607 }
3608
3609 // Sorting support
3610 // TODO(dcarney): templatize or move to SeededNumberDictionary
3611 void CopyValuesTo(FixedArray* elements);
3612
3613 // Returns the number of elements in the dictionary filtering out properties
3614 // with the specified attributes.
3615 int NumberOfElementsFilterAttributes(PropertyFilter filter);
3616
3617 // Returns the number of enumerable elements in the dictionary.
NumberOfEnumElements()3618 int NumberOfEnumElements() {
3619 return NumberOfElementsFilterAttributes(ENUMERABLE_STRINGS);
3620 }
3621
3622 enum SortMode { UNSORTED, SORTED };
3623
3624 // Return the key indices sorted by its enumeration index.
3625 static Handle<FixedArray> IterationIndices(
3626 Handle<Dictionary<Derived, Shape, Key>> dictionary);
3627
3628 // Collect the keys into the given KeyAccumulator, in ascending chronological
3629 // order of property creation.
3630 static void CollectKeysTo(Handle<Dictionary<Derived, Shape, Key>> dictionary,
3631 KeyAccumulator* keys);
3632
3633 // Copies enumerable keys to preallocated fixed array.
3634 static void CopyEnumKeysTo(Handle<Dictionary<Derived, Shape, Key>> dictionary,
3635 Handle<FixedArray> storage, KeyCollectionMode mode,
3636 KeyAccumulator* accumulator);
3637
3638 // Accessors for next enumeration index.
SetNextEnumerationIndex(int index)3639 void SetNextEnumerationIndex(int index) {
3640 DCHECK(index != 0);
3641 this->set(kNextEnumerationIndexIndex, Smi::FromInt(index));
3642 }
3643
NextEnumerationIndex()3644 int NextEnumerationIndex() {
3645 return Smi::cast(this->get(kNextEnumerationIndexIndex))->value();
3646 }
3647
3648 // Creates a new dictionary.
3649 MUST_USE_RESULT static Handle<Derived> New(
3650 Isolate* isolate, int at_least_space_for,
3651 PretenureFlag pretenure = NOT_TENURED,
3652 MinimumCapacity capacity_option = USE_DEFAULT_MINIMUM_CAPACITY);
3653
3654 // Creates an dictionary with minimal possible capacity.
3655 MUST_USE_RESULT static Handle<Derived> NewEmpty(
3656 Isolate* isolate, PretenureFlag pretenure = NOT_TENURED);
3657
3658 // Ensures that a new dictionary is created when the capacity is checked.
3659 void SetRequiresCopyOnCapacityChange();
3660
3661 // Ensure enough space for n additional elements.
3662 static Handle<Derived> EnsureCapacity(Handle<Derived> obj, int n, Key key);
3663
3664 #ifdef OBJECT_PRINT
3665 // For our gdb macros, we should perhaps change these in the future.
3666 void Print();
3667
3668 void Print(std::ostream& os); // NOLINT
3669 #endif
3670 // Returns the key (slow).
3671 Object* SlowReverseLookup(Object* value);
3672
3673 // Sets the entry to (key, value) pair.
3674 inline void SetEntry(int entry,
3675 Handle<Object> key,
3676 Handle<Object> value);
3677 inline void SetEntry(int entry,
3678 Handle<Object> key,
3679 Handle<Object> value,
3680 PropertyDetails details);
3681
3682 MUST_USE_RESULT static Handle<Derived> Add(Handle<Derived> dictionary,
3683 Key key, Handle<Object> value,
3684 PropertyDetails details,
3685 int* entry_out = nullptr);
3686
3687 static const int kMaxNumberKeyIndex = DerivedHashTable::kPrefixStartIndex;
3688 static const int kNextEnumerationIndexIndex = kMaxNumberKeyIndex + 1;
3689
3690 static const bool kIsEnumerable = Shape::kIsEnumerable;
3691
3692 protected:
3693 // Generic at put operation.
3694 MUST_USE_RESULT static Handle<Derived> AtPut(
3695 Handle<Derived> dictionary,
3696 Key key,
3697 Handle<Object> value);
3698 // Add entry to dictionary. Returns entry value.
3699 static int AddEntry(Handle<Derived> dictionary, Key key, Handle<Object> value,
3700 PropertyDetails details, uint32_t hash);
3701 // Generate new enumeration indices to avoid enumeration index overflow.
3702 // Returns iteration indices array for the |dictionary|.
3703 static Handle<FixedArray> GenerateNewEnumerationIndices(
3704 Handle<Derived> dictionary);
3705 };
3706
3707
3708 template <typename Derived, typename Shape>
3709 class NameDictionaryBase : public Dictionary<Derived, Shape, Handle<Name> > {
3710 typedef Dictionary<Derived, Shape, Handle<Name> > DerivedDictionary;
3711
3712 public:
3713 // Find entry for key, otherwise return kNotFound. Optimized version of
3714 // HashTable::FindEntry.
3715 int FindEntry(Handle<Name> key);
3716 };
3717
3718
3719 template <typename Key>
3720 class BaseDictionaryShape : public BaseShape<Key> {
3721 public:
3722 template <typename Dictionary>
DetailsAt(Dictionary * dict,int entry)3723 static inline PropertyDetails DetailsAt(Dictionary* dict, int entry) {
3724 STATIC_ASSERT(Dictionary::kEntrySize == 3);
3725 DCHECK(entry >= 0); // Not found is -1, which is not caught by get().
3726 return PropertyDetails(Smi::cast(dict->get(
3727 Dictionary::EntryToIndex(entry) + Dictionary::kEntryDetailsIndex)));
3728 }
3729
3730 template <typename Dictionary>
DetailsAtPut(Dictionary * dict,int entry,PropertyDetails value)3731 static inline void DetailsAtPut(Dictionary* dict, int entry,
3732 PropertyDetails value) {
3733 STATIC_ASSERT(Dictionary::kEntrySize == 3);
3734 dict->set(Dictionary::EntryToIndex(entry) + Dictionary::kEntryDetailsIndex,
3735 value.AsSmi());
3736 }
3737
3738 template <typename Dictionary>
IsDeleted(Dictionary * dict,int entry)3739 static bool IsDeleted(Dictionary* dict, int entry) {
3740 return false;
3741 }
3742
3743 template <typename Dictionary>
3744 static inline void SetEntry(Dictionary* dict, int entry, Handle<Object> key,
3745 Handle<Object> value, PropertyDetails details);
3746 };
3747
3748
3749 class NameDictionaryShape : public BaseDictionaryShape<Handle<Name> > {
3750 public:
3751 static inline bool IsMatch(Handle<Name> key, Object* other);
3752 static inline uint32_t Hash(Handle<Name> key);
3753 static inline uint32_t HashForObject(Handle<Name> key, Object* object);
3754 static inline Handle<Object> AsHandle(Isolate* isolate, Handle<Name> key);
3755 static const int kPrefixSize = 2;
3756 static const int kEntrySize = 3;
3757 static const int kEntryValueIndex = 1;
3758 static const int kEntryDetailsIndex = 2;
3759 static const bool kIsEnumerable = true;
3760 };
3761
3762
3763 class NameDictionary
3764 : public NameDictionaryBase<NameDictionary, NameDictionaryShape> {
3765 typedef NameDictionaryBase<NameDictionary, NameDictionaryShape>
3766 DerivedDictionary;
3767
3768 public:
3769 DECLARE_CAST(NameDictionary)
3770
3771 inline static Handle<FixedArray> DoGenerateNewEnumerationIndices(
3772 Handle<NameDictionary> dictionary);
3773
3774 static const int kEntryValueIndex = 1;
3775 static const int kEntryDetailsIndex = 2;
3776 static const int kInitialCapacity = 2;
3777 };
3778
3779
3780 class GlobalDictionaryShape : public NameDictionaryShape {
3781 public:
3782 static const int kEntrySize = 2; // Overrides NameDictionaryShape::kEntrySize
3783
3784 template <typename Dictionary>
3785 static inline PropertyDetails DetailsAt(Dictionary* dict, int entry);
3786
3787 template <typename Dictionary>
3788 static inline void DetailsAtPut(Dictionary* dict, int entry,
3789 PropertyDetails value);
3790
3791 template <typename Dictionary>
3792 static bool IsDeleted(Dictionary* dict, int entry);
3793
3794 template <typename Dictionary>
3795 static inline void SetEntry(Dictionary* dict, int entry, Handle<Object> key,
3796 Handle<Object> value, PropertyDetails details);
3797 };
3798
3799
3800 class GlobalDictionary
3801 : public NameDictionaryBase<GlobalDictionary, GlobalDictionaryShape> {
3802 public:
3803 DECLARE_CAST(GlobalDictionary)
3804
3805 static const int kEntryValueIndex = 1;
3806 };
3807
3808
3809 class NumberDictionaryShape : public BaseDictionaryShape<uint32_t> {
3810 public:
3811 static inline bool IsMatch(uint32_t key, Object* other);
3812 static inline Handle<Object> AsHandle(Isolate* isolate, uint32_t key);
3813 static const bool kIsEnumerable = false;
3814 };
3815
3816
3817 class SeededNumberDictionaryShape : public NumberDictionaryShape {
3818 public:
3819 static const bool UsesSeed = true;
3820 static const int kPrefixSize = 2;
3821 static const int kEntrySize = 3;
3822
3823 static inline uint32_t SeededHash(uint32_t key, uint32_t seed);
3824 static inline uint32_t SeededHashForObject(uint32_t key,
3825 uint32_t seed,
3826 Object* object);
3827 };
3828
3829
3830 class UnseededNumberDictionaryShape : public NumberDictionaryShape {
3831 public:
3832 static const int kPrefixSize = 0;
3833 static const int kEntrySize = 2;
3834
3835 static inline uint32_t Hash(uint32_t key);
3836 static inline uint32_t HashForObject(uint32_t key, Object* object);
3837
3838 template <typename Dictionary>
DetailsAt(Dictionary * dict,int entry)3839 static inline PropertyDetails DetailsAt(Dictionary* dict, int entry) {
3840 UNREACHABLE();
3841 return PropertyDetails::Empty();
3842 }
3843
3844 template <typename Dictionary>
DetailsAtPut(Dictionary * dict,int entry,PropertyDetails value)3845 static inline void DetailsAtPut(Dictionary* dict, int entry,
3846 PropertyDetails value) {
3847 UNREACHABLE();
3848 }
3849
3850 static inline Map* GetMap(Isolate* isolate);
3851 };
3852
3853
3854 class SeededNumberDictionary
3855 : public Dictionary<SeededNumberDictionary,
3856 SeededNumberDictionaryShape,
3857 uint32_t> {
3858 public:
3859 DECLARE_CAST(SeededNumberDictionary)
3860
3861 // Type specific at put (default NONE attributes is used when adding).
3862 MUST_USE_RESULT static Handle<SeededNumberDictionary> AtNumberPut(
3863 Handle<SeededNumberDictionary> dictionary, uint32_t key,
3864 Handle<Object> value, Handle<JSObject> dictionary_holder);
3865 MUST_USE_RESULT static Handle<SeededNumberDictionary> AddNumberEntry(
3866 Handle<SeededNumberDictionary> dictionary, uint32_t key,
3867 Handle<Object> value, PropertyDetails details,
3868 Handle<JSObject> dictionary_holder);
3869
3870 // Set an existing entry or add a new one if needed.
3871 // Return the updated dictionary.
3872 MUST_USE_RESULT static Handle<SeededNumberDictionary> Set(
3873 Handle<SeededNumberDictionary> dictionary, uint32_t key,
3874 Handle<Object> value, PropertyDetails details,
3875 Handle<JSObject> dictionary_holder);
3876
3877 void UpdateMaxNumberKey(uint32_t key, Handle<JSObject> dictionary_holder);
3878
3879 // Returns true if the dictionary contains any elements that are non-writable,
3880 // non-configurable, non-enumerable, or have getters/setters.
3881 bool HasComplexElements();
3882
3883 // If slow elements are required we will never go back to fast-case
3884 // for the elements kept in this dictionary. We require slow
3885 // elements if an element has been added at an index larger than
3886 // kRequiresSlowElementsLimit or set_requires_slow_elements() has been called
3887 // when defining a getter or setter with a number key.
3888 inline bool requires_slow_elements();
3889 inline void set_requires_slow_elements();
3890
3891 // Get the value of the max number key that has been added to this
3892 // dictionary. max_number_key can only be called if
3893 // requires_slow_elements returns false.
3894 inline uint32_t max_number_key();
3895
3896 static const int kEntryValueIndex = 1;
3897 static const int kEntryDetailsIndex = 2;
3898
3899 // Bit masks.
3900 static const int kRequiresSlowElementsMask = 1;
3901 static const int kRequiresSlowElementsTagSize = 1;
3902 static const uint32_t kRequiresSlowElementsLimit = (1 << 29) - 1;
3903 };
3904
3905
3906 class UnseededNumberDictionary
3907 : public Dictionary<UnseededNumberDictionary,
3908 UnseededNumberDictionaryShape,
3909 uint32_t> {
3910 public:
3911 DECLARE_CAST(UnseededNumberDictionary)
3912
3913 // Type specific at put (default NONE attributes is used when adding).
3914 MUST_USE_RESULT static Handle<UnseededNumberDictionary> AtNumberPut(
3915 Handle<UnseededNumberDictionary> dictionary,
3916 uint32_t key,
3917 Handle<Object> value);
3918 MUST_USE_RESULT static Handle<UnseededNumberDictionary> AddNumberEntry(
3919 Handle<UnseededNumberDictionary> dictionary,
3920 uint32_t key,
3921 Handle<Object> value);
3922 static Handle<UnseededNumberDictionary> DeleteKey(
3923 Handle<UnseededNumberDictionary> dictionary, uint32_t key);
3924
3925 // Set an existing entry or add a new one if needed.
3926 // Return the updated dictionary.
3927 MUST_USE_RESULT static Handle<UnseededNumberDictionary> Set(
3928 Handle<UnseededNumberDictionary> dictionary,
3929 uint32_t key,
3930 Handle<Object> value);
3931
3932 static const int kEntryValueIndex = 1;
3933 static const int kEntryDetailsIndex = 2;
3934 };
3935
3936
3937 class ObjectHashTableShape : public BaseShape<Handle<Object> > {
3938 public:
3939 static inline bool IsMatch(Handle<Object> key, Object* other);
3940 static inline uint32_t Hash(Handle<Object> key);
3941 static inline uint32_t HashForObject(Handle<Object> key, Object* object);
3942 static inline Handle<Object> AsHandle(Isolate* isolate, Handle<Object> key);
3943 static const int kPrefixSize = 0;
3944 static const int kEntrySize = 2;
3945 };
3946
3947
3948 // ObjectHashTable maps keys that are arbitrary objects to object values by
3949 // using the identity hash of the key for hashing purposes.
3950 class ObjectHashTable: public HashTable<ObjectHashTable,
3951 ObjectHashTableShape,
3952 Handle<Object> > {
3953 typedef HashTable<
3954 ObjectHashTable, ObjectHashTableShape, Handle<Object> > DerivedHashTable;
3955 public:
3956 DECLARE_CAST(ObjectHashTable)
3957
3958 // Attempt to shrink hash table after removal of key.
3959 MUST_USE_RESULT static inline Handle<ObjectHashTable> Shrink(
3960 Handle<ObjectHashTable> table,
3961 Handle<Object> key);
3962
3963 // Looks up the value associated with the given key. The hole value is
3964 // returned in case the key is not present.
3965 Object* Lookup(Handle<Object> key);
3966 Object* Lookup(Handle<Object> key, int32_t hash);
3967 Object* Lookup(Isolate* isolate, Handle<Object> key, int32_t hash);
3968
3969 // Returns the value at entry.
3970 Object* ValueAt(int entry);
3971
3972 // Adds (or overwrites) the value associated with the given key.
3973 static Handle<ObjectHashTable> Put(Handle<ObjectHashTable> table,
3974 Handle<Object> key,
3975 Handle<Object> value);
3976 static Handle<ObjectHashTable> Put(Handle<ObjectHashTable> table,
3977 Handle<Object> key, Handle<Object> value,
3978 int32_t hash);
3979
3980 // Returns an ObjectHashTable (possibly |table|) where |key| has been removed.
3981 static Handle<ObjectHashTable> Remove(Handle<ObjectHashTable> table,
3982 Handle<Object> key,
3983 bool* was_present);
3984 static Handle<ObjectHashTable> Remove(Handle<ObjectHashTable> table,
3985 Handle<Object> key, bool* was_present,
3986 int32_t hash);
3987
3988 protected:
3989 friend class MarkCompactCollector;
3990
3991 void AddEntry(int entry, Object* key, Object* value);
3992 void RemoveEntry(int entry);
3993
3994 // Returns the index to the value of an entry.
EntryToValueIndex(int entry)3995 static inline int EntryToValueIndex(int entry) {
3996 return EntryToIndex(entry) + 1;
3997 }
3998 };
3999
4000 class ObjectHashSetShape : public ObjectHashTableShape {
4001 public:
4002 static const int kPrefixSize = 0;
4003 static const int kEntrySize = 1;
4004 };
4005
4006 class ObjectHashSet
4007 : public HashTable<ObjectHashSet, ObjectHashSetShape, Handle<Object>> {
4008 public:
4009 static Handle<ObjectHashSet> Add(Handle<ObjectHashSet> set,
4010 Handle<Object> key);
4011
4012 inline bool Has(Isolate* isolate, Handle<Object> key, int32_t hash);
4013 inline bool Has(Isolate* isolate, Handle<Object> key);
4014
4015 DECLARE_CAST(ObjectHashSet)
4016 };
4017
4018 // OrderedHashTable is a HashTable with Object keys that preserves
4019 // insertion order. There are Map and Set interfaces (OrderedHashMap
4020 // and OrderedHashTable, below). It is meant to be used by JSMap/JSSet.
4021 //
4022 // Only Object* keys are supported, with Object::SameValueZero() used as the
4023 // equality operator and Object::GetHash() for the hash function.
4024 //
4025 // Based on the "Deterministic Hash Table" as described by Jason Orendorff at
4026 // https://wiki.mozilla.org/User:Jorend/Deterministic_hash_tables
4027 // Originally attributed to Tyler Close.
4028 //
4029 // Memory layout:
4030 // [0]: bucket count
4031 // [1]: element count
4032 // [2]: deleted element count
4033 // [3..(3 + NumberOfBuckets() - 1)]: "hash table", where each item is an
4034 // offset into the data table (see below) where the
4035 // first item in this bucket is stored.
4036 // [3 + NumberOfBuckets()..length]: "data table", an array of length
4037 // Capacity() * kEntrySize, where the first entrysize
4038 // items are handled by the derived class and the
4039 // item at kChainOffset is another entry into the
4040 // data table indicating the next entry in this hash
4041 // bucket.
4042 //
4043 // When we transition the table to a new version we obsolete it and reuse parts
4044 // of the memory to store information how to transition an iterator to the new
4045 // table:
4046 //
4047 // Memory layout for obsolete table:
4048 // [0]: bucket count
4049 // [1]: Next newer table
4050 // [2]: Number of removed holes or -1 when the table was cleared.
4051 // [3..(3 + NumberOfRemovedHoles() - 1)]: The indexes of the removed holes.
4052 // [3 + NumberOfRemovedHoles()..length]: Not used
4053 //
4054 template<class Derived, class Iterator, int entrysize>
4055 class OrderedHashTable: public FixedArray {
4056 public:
4057 // Returns an OrderedHashTable with a capacity of at least |capacity|.
4058 static Handle<Derived> Allocate(
4059 Isolate* isolate, int capacity, PretenureFlag pretenure = NOT_TENURED);
4060
4061 // Returns an OrderedHashTable (possibly |table|) with enough space
4062 // to add at least one new element.
4063 static Handle<Derived> EnsureGrowable(Handle<Derived> table);
4064
4065 // Returns an OrderedHashTable (possibly |table|) that's shrunken
4066 // if possible.
4067 static Handle<Derived> Shrink(Handle<Derived> table);
4068
4069 // Returns a new empty OrderedHashTable and records the clearing so that
4070 // existing iterators can be updated.
4071 static Handle<Derived> Clear(Handle<Derived> table);
4072
4073 // Returns a true if the OrderedHashTable contains the key
4074 static bool HasKey(Handle<Derived> table, Handle<Object> key);
4075
NumberOfElements()4076 int NumberOfElements() {
4077 return Smi::cast(get(kNumberOfElementsIndex))->value();
4078 }
4079
NumberOfDeletedElements()4080 int NumberOfDeletedElements() {
4081 return Smi::cast(get(kNumberOfDeletedElementsIndex))->value();
4082 }
4083
4084 // Returns the number of contiguous entries in the data table, starting at 0,
4085 // that either are real entries or have been deleted.
UsedCapacity()4086 int UsedCapacity() { return NumberOfElements() + NumberOfDeletedElements(); }
4087
NumberOfBuckets()4088 int NumberOfBuckets() {
4089 return Smi::cast(get(kNumberOfBucketsIndex))->value();
4090 }
4091
4092 // Returns an index into |this| for the given entry.
EntryToIndex(int entry)4093 int EntryToIndex(int entry) {
4094 return kHashTableStartIndex + NumberOfBuckets() + (entry * kEntrySize);
4095 }
4096
HashToBucket(int hash)4097 int HashToBucket(int hash) { return hash & (NumberOfBuckets() - 1); }
4098
HashToEntry(int hash)4099 int HashToEntry(int hash) {
4100 int bucket = HashToBucket(hash);
4101 Object* entry = this->get(kHashTableStartIndex + bucket);
4102 return Smi::cast(entry)->value();
4103 }
4104
KeyToFirstEntry(Isolate * isolate,Object * key)4105 int KeyToFirstEntry(Isolate* isolate, Object* key) {
4106 Object* hash = key->GetHash();
4107 // If the object does not have an identity hash, it was never used as a key
4108 if (hash->IsUndefined(isolate)) return kNotFound;
4109 return HashToEntry(Smi::cast(hash)->value());
4110 }
4111
NextChainEntry(int entry)4112 int NextChainEntry(int entry) {
4113 Object* next_entry = get(EntryToIndex(entry) + kChainOffset);
4114 return Smi::cast(next_entry)->value();
4115 }
4116
4117 // use KeyAt(i)->IsTheHole(isolate) to determine if this is a deleted entry.
KeyAt(int entry)4118 Object* KeyAt(int entry) {
4119 DCHECK_LT(entry, this->UsedCapacity());
4120 return get(EntryToIndex(entry));
4121 }
4122
IsObsolete()4123 bool IsObsolete() {
4124 return !get(kNextTableIndex)->IsSmi();
4125 }
4126
4127 // The next newer table. This is only valid if the table is obsolete.
NextTable()4128 Derived* NextTable() {
4129 return Derived::cast(get(kNextTableIndex));
4130 }
4131
4132 // When the table is obsolete we store the indexes of the removed holes.
RemovedIndexAt(int index)4133 int RemovedIndexAt(int index) {
4134 return Smi::cast(get(kRemovedHolesIndex + index))->value();
4135 }
4136
4137 static const int kNotFound = -1;
4138 static const int kMinCapacity = 4;
4139
4140 static const int kNumberOfElementsIndex = 0;
4141 // The next table is stored at the same index as the nof elements.
4142 static const int kNextTableIndex = kNumberOfElementsIndex;
4143 static const int kNumberOfDeletedElementsIndex = kNumberOfElementsIndex + 1;
4144 static const int kNumberOfBucketsIndex = kNumberOfDeletedElementsIndex + 1;
4145 static const int kHashTableStartIndex = kNumberOfBucketsIndex + 1;
4146
4147 static constexpr const int kNumberOfElementsOffset =
4148 FixedArray::OffsetOfElementAt(kNumberOfElementsIndex);
4149 static constexpr const int kNextTableOffset =
4150 FixedArray::OffsetOfElementAt(kNextTableIndex);
4151 static constexpr const int kNumberOfDeletedElementsOffset =
4152 FixedArray::OffsetOfElementAt(kNumberOfDeletedElementsIndex);
4153 static constexpr const int kNumberOfBucketsOffset =
4154 FixedArray::OffsetOfElementAt(kNumberOfBucketsIndex);
4155 static constexpr const int kHashTableStartOffset =
4156 FixedArray::OffsetOfElementAt(kHashTableStartIndex);
4157
4158 static const int kEntrySize = entrysize + 1;
4159 static const int kChainOffset = entrysize;
4160
4161 static const int kLoadFactor = 2;
4162
4163 // NumberOfDeletedElements is set to kClearedTableSentinel when
4164 // the table is cleared, which allows iterator transitions to
4165 // optimize that case.
4166 static const int kClearedTableSentinel = -1;
4167
4168 protected:
4169 static Handle<Derived> Rehash(Handle<Derived> table, int new_capacity);
4170
SetNumberOfBuckets(int num)4171 void SetNumberOfBuckets(int num) {
4172 set(kNumberOfBucketsIndex, Smi::FromInt(num));
4173 }
4174
SetNumberOfElements(int num)4175 void SetNumberOfElements(int num) {
4176 set(kNumberOfElementsIndex, Smi::FromInt(num));
4177 }
4178
SetNumberOfDeletedElements(int num)4179 void SetNumberOfDeletedElements(int num) {
4180 set(kNumberOfDeletedElementsIndex, Smi::FromInt(num));
4181 }
4182
4183 // Returns the number elements that can fit into the allocated buffer.
Capacity()4184 int Capacity() {
4185 return NumberOfBuckets() * kLoadFactor;
4186 }
4187
SetNextTable(Derived * next_table)4188 void SetNextTable(Derived* next_table) {
4189 set(kNextTableIndex, next_table);
4190 }
4191
SetRemovedIndexAt(int index,int removed_index)4192 void SetRemovedIndexAt(int index, int removed_index) {
4193 return set(kRemovedHolesIndex + index, Smi::FromInt(removed_index));
4194 }
4195
4196 static const int kRemovedHolesIndex = kHashTableStartIndex;
4197
4198 static const int kMaxCapacity =
4199 (FixedArray::kMaxLength - kHashTableStartIndex)
4200 / (1 + (kEntrySize * kLoadFactor));
4201 };
4202
4203
4204 class JSSetIterator;
4205
4206
4207 class OrderedHashSet: public OrderedHashTable<
4208 OrderedHashSet, JSSetIterator, 1> {
4209 public:
4210 DECLARE_CAST(OrderedHashSet)
4211
4212 static Handle<OrderedHashSet> Add(Handle<OrderedHashSet> table,
4213 Handle<Object> value);
4214 static Handle<FixedArray> ConvertToKeysArray(Handle<OrderedHashSet> table,
4215 GetKeysConversion convert);
4216 };
4217
4218
4219 class JSMapIterator;
4220
4221
4222 class OrderedHashMap
4223 : public OrderedHashTable<OrderedHashMap, JSMapIterator, 2> {
4224 public:
4225 DECLARE_CAST(OrderedHashMap)
4226
4227 inline Object* ValueAt(int entry);
4228
4229 static const int kValueOffset = 1;
4230 };
4231
4232
4233 template <int entrysize>
4234 class WeakHashTableShape : public BaseShape<Handle<Object> > {
4235 public:
4236 static inline bool IsMatch(Handle<Object> key, Object* other);
4237 static inline uint32_t Hash(Handle<Object> key);
4238 static inline uint32_t HashForObject(Handle<Object> key, Object* object);
4239 static inline Handle<Object> AsHandle(Isolate* isolate, Handle<Object> key);
4240 static const int kPrefixSize = 0;
4241 static const int kEntrySize = entrysize;
4242 };
4243
4244
4245 // WeakHashTable maps keys that are arbitrary heap objects to heap object
4246 // values. The table wraps the keys in weak cells and store values directly.
4247 // Thus it references keys weakly and values strongly.
4248 class WeakHashTable: public HashTable<WeakHashTable,
4249 WeakHashTableShape<2>,
4250 Handle<Object> > {
4251 typedef HashTable<
4252 WeakHashTable, WeakHashTableShape<2>, Handle<Object> > DerivedHashTable;
4253 public:
4254 DECLARE_CAST(WeakHashTable)
4255
4256 // Looks up the value associated with the given key. The hole value is
4257 // returned in case the key is not present.
4258 Object* Lookup(Handle<HeapObject> key);
4259
4260 // Adds (or overwrites) the value associated with the given key. Mapping a
4261 // key to the hole value causes removal of the whole entry.
4262 MUST_USE_RESULT static Handle<WeakHashTable> Put(Handle<WeakHashTable> table,
4263 Handle<HeapObject> key,
4264 Handle<HeapObject> value);
4265
4266 static Handle<FixedArray> GetValues(Handle<WeakHashTable> table);
4267
4268 private:
4269 friend class MarkCompactCollector;
4270
4271 void AddEntry(int entry, Handle<WeakCell> key, Handle<HeapObject> value);
4272
4273 // Returns the index to the value of an entry.
EntryToValueIndex(int entry)4274 static inline int EntryToValueIndex(int entry) {
4275 return EntryToIndex(entry) + 1;
4276 }
4277 };
4278
4279
4280 // The cache for maps used by normalized (dictionary mode) objects.
4281 // Such maps do not have property descriptors, so a typical program
4282 // needs very limited number of distinct normalized maps.
4283 class NormalizedMapCache: public FixedArray {
4284 public:
4285 static Handle<NormalizedMapCache> New(Isolate* isolate);
4286
4287 MUST_USE_RESULT MaybeHandle<Map> Get(Handle<Map> fast_map,
4288 PropertyNormalizationMode mode);
4289 void Set(Handle<Map> fast_map, Handle<Map> normalized_map);
4290
4291 void Clear();
4292
4293 DECLARE_CAST(NormalizedMapCache)
4294
4295 static inline bool IsNormalizedMapCache(const HeapObject* obj);
4296
4297 DECLARE_VERIFIER(NormalizedMapCache)
4298 private:
4299 static const int kEntries = 64;
4300
4301 static inline int GetIndex(Handle<Map> map);
4302
4303 // The following declarations hide base class methods.
4304 Object* get(int index);
4305 void set(int index, Object* value);
4306 };
4307
4308 // HandlerTable is a fixed array containing entries for exception handlers in
4309 // the code object it is associated with. The tables comes in two flavors:
4310 // 1) Based on ranges: Used for unoptimized code. Contains one entry per
4311 // exception handler and a range representing the try-block covered by that
4312 // handler. Layout looks as follows:
4313 // [ range-start , range-end , handler-offset , handler-data ]
4314 // 2) Based on return addresses: Used for turbofanned code. Contains one entry
4315 // per call-site that could throw an exception. Layout looks as follows:
4316 // [ return-address-offset , handler-offset ]
4317 class HandlerTable : public FixedArray {
4318 public:
4319 // Conservative prediction whether a given handler will locally catch an
4320 // exception or cause a re-throw to outside the code boundary. Since this is
4321 // undecidable it is merely an approximation (e.g. useful for debugger).
4322 enum CatchPrediction {
4323 UNCAUGHT, // The handler will (likely) rethrow the exception.
4324 CAUGHT, // The exception will be caught by the handler.
4325 PROMISE, // The exception will be caught and cause a promise rejection.
4326 DESUGARING, // The exception will be caught, but both the exception and the
4327 // catching are part of a desugaring and should therefore not
4328 // be visible to the user (we won't notify the debugger of such
4329 // exceptions).
4330 ASYNC_AWAIT, // The exception will be caught and cause a promise rejection
4331 // in the desugaring of an async function, so special
4332 // async/await handling in the debugger can take place.
4333 };
4334
4335 // Getters for handler table based on ranges.
4336 inline int GetRangeStart(int index) const;
4337 inline int GetRangeEnd(int index) const;
4338 inline int GetRangeHandler(int index) const;
4339 inline int GetRangeData(int index) const;
4340
4341 // Setters for handler table based on ranges.
4342 inline void SetRangeStart(int index, int value);
4343 inline void SetRangeEnd(int index, int value);
4344 inline void SetRangeHandler(int index, int offset, CatchPrediction pred);
4345 inline void SetRangeData(int index, int value);
4346
4347 // Setters for handler table based on return addresses.
4348 inline void SetReturnOffset(int index, int value);
4349 inline void SetReturnHandler(int index, int offset);
4350
4351 // Lookup handler in a table based on ranges. The {pc_offset} is an offset to
4352 // the start of the potentially throwing instruction (using return addresses
4353 // for this value would be invalid).
4354 int LookupRange(int pc_offset, int* data, CatchPrediction* prediction);
4355
4356 // Lookup handler in a table based on return addresses.
4357 int LookupReturn(int pc_offset);
4358
4359 // Returns the number of entries in the table.
4360 inline int NumberOfRangeEntries() const;
4361
4362 // Returns the required length of the underlying fixed array.
LengthForRange(int entries)4363 static int LengthForRange(int entries) { return entries * kRangeEntrySize; }
LengthForReturn(int entries)4364 static int LengthForReturn(int entries) { return entries * kReturnEntrySize; }
4365
4366 DECLARE_CAST(HandlerTable)
4367
4368 #ifdef ENABLE_DISASSEMBLER
4369 void HandlerTableRangePrint(std::ostream& os); // NOLINT
4370 void HandlerTableReturnPrint(std::ostream& os); // NOLINT
4371 #endif
4372
4373 private:
4374 // Layout description for handler table based on ranges.
4375 static const int kRangeStartIndex = 0;
4376 static const int kRangeEndIndex = 1;
4377 static const int kRangeHandlerIndex = 2;
4378 static const int kRangeDataIndex = 3;
4379 static const int kRangeEntrySize = 4;
4380
4381 // Layout description for handler table based on return addresses.
4382 static const int kReturnOffsetIndex = 0;
4383 static const int kReturnHandlerIndex = 1;
4384 static const int kReturnEntrySize = 2;
4385
4386 // Encoding of the {handler} field.
4387 class HandlerPredictionField : public BitField<CatchPrediction, 0, 3> {};
4388 class HandlerOffsetField : public BitField<int, 3, 29> {};
4389 };
4390
4391 // ByteArray represents fixed sized byte arrays. Used for the relocation info
4392 // that is attached to code objects.
4393 class ByteArray: public FixedArrayBase {
4394 public:
4395 inline int Size();
4396
4397 // Setter and getter.
4398 inline byte get(int index);
4399 inline void set(int index, byte value);
4400
4401 // Copy in / copy out whole byte slices.
4402 inline void copy_out(int index, byte* buffer, int length);
4403 inline void copy_in(int index, const byte* buffer, int length);
4404
4405 // Treat contents as an int array.
4406 inline int get_int(int index);
4407 inline void set_int(int index, int value);
4408
SizeFor(int length)4409 static int SizeFor(int length) {
4410 return OBJECT_POINTER_ALIGN(kHeaderSize + length);
4411 }
4412 // We use byte arrays for free blocks in the heap. Given a desired size in
4413 // bytes that is a multiple of the word size and big enough to hold a byte
4414 // array, this function returns the number of elements a byte array should
4415 // have.
LengthFor(int size_in_bytes)4416 static int LengthFor(int size_in_bytes) {
4417 DCHECK(IsAligned(size_in_bytes, kPointerSize));
4418 DCHECK(size_in_bytes >= kHeaderSize);
4419 return size_in_bytes - kHeaderSize;
4420 }
4421
4422 // Returns data start address.
4423 inline Address GetDataStartAddress();
4424
4425 // Returns a pointer to the ByteArray object for a given data start address.
4426 static inline ByteArray* FromDataStartAddress(Address address);
4427
4428 DECLARE_CAST(ByteArray)
4429
4430 // Dispatched behavior.
4431 inline int ByteArraySize();
4432 DECLARE_PRINTER(ByteArray)
4433 DECLARE_VERIFIER(ByteArray)
4434
4435 // Layout description.
4436 static const int kAlignedSize = OBJECT_POINTER_ALIGN(kHeaderSize);
4437
4438 // Maximal memory consumption for a single ByteArray.
4439 static const int kMaxSize = 512 * MB;
4440 // Maximal length of a single ByteArray.
4441 static const int kMaxLength = kMaxSize - kHeaderSize;
4442
4443 private:
4444 DISALLOW_IMPLICIT_CONSTRUCTORS(ByteArray);
4445 };
4446
4447 // Wrapper class for ByteArray which can store arbitrary C++ classes, as long
4448 // as they can be copied with memcpy.
4449 template <class T>
4450 class PodArray : public ByteArray {
4451 public:
4452 static Handle<PodArray<T>> New(Isolate* isolate, int length,
4453 PretenureFlag pretenure = NOT_TENURED);
copy_out(int index,T * result)4454 void copy_out(int index, T* result) {
4455 ByteArray::copy_out(index * sizeof(T), reinterpret_cast<byte*>(result),
4456 sizeof(T));
4457 }
get(int index)4458 T get(int index) {
4459 T result;
4460 copy_out(index, &result);
4461 return result;
4462 }
set(int index,const T & value)4463 void set(int index, const T& value) {
4464 copy_in(index * sizeof(T), reinterpret_cast<const byte*>(&value),
4465 sizeof(T));
4466 }
length()4467 int length() { return ByteArray::length() / sizeof(T); }
4468 DECLARE_CAST(PodArray<T>)
4469
4470 private:
4471 DISALLOW_IMPLICIT_CONSTRUCTORS(PodArray<T>);
4472 };
4473
4474 // BytecodeArray represents a sequence of interpreter bytecodes.
4475 class BytecodeArray : public FixedArrayBase {
4476 public:
4477 #define DECLARE_BYTECODE_AGE_ENUM(X) k##X##BytecodeAge,
4478 enum Age {
4479 kNoAgeBytecodeAge = 0,
4480 CODE_AGE_LIST(DECLARE_BYTECODE_AGE_ENUM) kAfterLastBytecodeAge,
4481 kFirstBytecodeAge = kNoAgeBytecodeAge,
4482 kLastBytecodeAge = kAfterLastBytecodeAge - 1,
4483 kBytecodeAgeCount = kAfterLastBytecodeAge - kFirstBytecodeAge - 1,
4484 kIsOldBytecodeAge = kSexagenarianBytecodeAge
4485 };
4486 #undef DECLARE_BYTECODE_AGE_ENUM
4487
SizeFor(int length)4488 static int SizeFor(int length) {
4489 return OBJECT_POINTER_ALIGN(kHeaderSize + length);
4490 }
4491
4492 // Setter and getter
4493 inline byte get(int index);
4494 inline void set(int index, byte value);
4495
4496 // Returns data start address.
4497 inline Address GetFirstBytecodeAddress();
4498
4499 // Accessors for frame size.
4500 inline int frame_size() const;
4501 inline void set_frame_size(int frame_size);
4502
4503 // Accessor for register count (derived from frame_size).
4504 inline int register_count() const;
4505
4506 // Accessors for parameter count (including implicit 'this' receiver).
4507 inline int parameter_count() const;
4508 inline void set_parameter_count(int number_of_parameters);
4509
4510 // Accessors for profiling count.
4511 inline int interrupt_budget() const;
4512 inline void set_interrupt_budget(int interrupt_budget);
4513
4514 // Accessors for OSR loop nesting level.
4515 inline int osr_loop_nesting_level() const;
4516 inline void set_osr_loop_nesting_level(int depth);
4517
4518 // Accessors for bytecode's code age.
4519 inline Age bytecode_age() const;
4520 inline void set_bytecode_age(Age age);
4521
4522 // Accessors for the constant pool.
4523 DECL_ACCESSORS(constant_pool, FixedArray)
4524
4525 // Accessors for handler table containing offsets of exception handlers.
4526 DECL_ACCESSORS(handler_table, FixedArray)
4527
4528 // Accessors for source position table containing mappings between byte code
4529 // offset and source position.
4530 DECL_ACCESSORS(source_position_table, ByteArray)
4531
4532 DECLARE_CAST(BytecodeArray)
4533
4534 // Dispatched behavior.
4535 inline int BytecodeArraySize();
4536
4537 inline int instruction_size();
4538
4539 // Returns the size of bytecode and its metadata. This includes the size of
4540 // bytecode, constant pool, source position table, and handler table.
4541 inline int SizeIncludingMetadata();
4542
4543 int SourcePosition(int offset);
4544 int SourceStatementPosition(int offset);
4545
4546 DECLARE_PRINTER(BytecodeArray)
4547 DECLARE_VERIFIER(BytecodeArray)
4548
4549 void Disassemble(std::ostream& os);
4550
4551 void CopyBytecodesTo(BytecodeArray* to);
4552
4553 // Bytecode aging
4554 bool IsOld() const;
4555 void MakeOlder();
4556
4557 // Layout description.
4558 static const int kConstantPoolOffset = FixedArrayBase::kHeaderSize;
4559 static const int kHandlerTableOffset = kConstantPoolOffset + kPointerSize;
4560 static const int kSourcePositionTableOffset =
4561 kHandlerTableOffset + kPointerSize;
4562 static const int kFrameSizeOffset = kSourcePositionTableOffset + kPointerSize;
4563 static const int kParameterSizeOffset = kFrameSizeOffset + kIntSize;
4564 static const int kInterruptBudgetOffset = kParameterSizeOffset + kIntSize;
4565 static const int kOSRNestingLevelOffset = kInterruptBudgetOffset + kIntSize;
4566 static const int kBytecodeAgeOffset = kOSRNestingLevelOffset + kCharSize;
4567 static const int kHeaderSize = kBytecodeAgeOffset + kCharSize;
4568
4569 // Maximal memory consumption for a single BytecodeArray.
4570 static const int kMaxSize = 512 * MB;
4571 // Maximal length of a single BytecodeArray.
4572 static const int kMaxLength = kMaxSize - kHeaderSize;
4573
4574 static const int kPointerFieldsBeginOffset = kConstantPoolOffset;
4575 static const int kPointerFieldsEndOffset = kFrameSizeOffset;
4576
4577 typedef FixedBodyDescriptor<kPointerFieldsBeginOffset,
4578 kPointerFieldsEndOffset, kHeaderSize>
4579 MarkingBodyDescriptor;
4580
4581 class BodyDescriptor;
4582
4583 private:
4584 DISALLOW_IMPLICIT_CONSTRUCTORS(BytecodeArray);
4585 };
4586
4587
4588 // FreeSpace are fixed-size free memory blocks used by the heap and GC.
4589 // They look like heap objects (are heap object tagged and have a map) so that
4590 // the heap remains iterable. They have a size and a next pointer.
4591 // The next pointer is the raw address of the next FreeSpace object (or NULL)
4592 // in the free list.
4593 class FreeSpace: public HeapObject {
4594 public:
4595 // [size]: size of the free space including the header.
4596 inline int size() const;
4597 inline void set_size(int value);
4598
4599 inline int nobarrier_size() const;
4600 inline void nobarrier_set_size(int value);
4601
4602 inline int Size();
4603
4604 // Accessors for the next field.
4605 inline FreeSpace* next();
4606 inline void set_next(FreeSpace* next);
4607
4608 inline static FreeSpace* cast(HeapObject* obj);
4609
4610 // Dispatched behavior.
4611 DECLARE_PRINTER(FreeSpace)
4612 DECLARE_VERIFIER(FreeSpace)
4613
4614 // Layout description.
4615 // Size is smi tagged when it is stored.
4616 static const int kSizeOffset = HeapObject::kHeaderSize;
4617 static const int kNextOffset = POINTER_SIZE_ALIGN(kSizeOffset + kPointerSize);
4618 static const int kSize = kNextOffset + kPointerSize;
4619
4620 private:
4621 DISALLOW_IMPLICIT_CONSTRUCTORS(FreeSpace);
4622 };
4623
4624
4625 // V has parameters (Type, type, TYPE, C type, element_size)
4626 #define TYPED_ARRAYS(V) \
4627 V(Uint8, uint8, UINT8, uint8_t, 1) \
4628 V(Int8, int8, INT8, int8_t, 1) \
4629 V(Uint16, uint16, UINT16, uint16_t, 2) \
4630 V(Int16, int16, INT16, int16_t, 2) \
4631 V(Uint32, uint32, UINT32, uint32_t, 4) \
4632 V(Int32, int32, INT32, int32_t, 4) \
4633 V(Float32, float32, FLOAT32, float, 4) \
4634 V(Float64, float64, FLOAT64, double, 8) \
4635 V(Uint8Clamped, uint8_clamped, UINT8_CLAMPED, uint8_t, 1)
4636
4637
4638 class FixedTypedArrayBase: public FixedArrayBase {
4639 public:
4640 // [base_pointer]: Either points to the FixedTypedArrayBase itself or nullptr.
4641 DECL_ACCESSORS(base_pointer, Object)
4642
4643 // [external_pointer]: Contains the offset between base_pointer and the start
4644 // of the data. If the base_pointer is a nullptr, the external_pointer
4645 // therefore points to the actual backing store.
4646 DECL_ACCESSORS(external_pointer, void)
4647
4648 // Dispatched behavior.
4649 DECLARE_CAST(FixedTypedArrayBase)
4650
4651 static const int kBasePointerOffset = FixedArrayBase::kHeaderSize;
4652 static const int kExternalPointerOffset = kBasePointerOffset + kPointerSize;
4653 static const int kHeaderSize =
4654 DOUBLE_POINTER_ALIGN(kExternalPointerOffset + kPointerSize);
4655
4656 static const int kDataOffset = kHeaderSize;
4657
4658 class BodyDescriptor;
4659
4660 inline int size();
4661
4662 static inline int TypedArraySize(InstanceType type, int length);
4663 inline int TypedArraySize(InstanceType type);
4664
4665 // Use with care: returns raw pointer into heap.
4666 inline void* DataPtr();
4667
4668 inline int DataSize();
4669
4670 private:
4671 static inline int ElementSize(InstanceType type);
4672
4673 inline int DataSize(InstanceType type);
4674
4675 DISALLOW_IMPLICIT_CONSTRUCTORS(FixedTypedArrayBase);
4676 };
4677
4678
4679 template <class Traits>
4680 class FixedTypedArray: public FixedTypedArrayBase {
4681 public:
4682 typedef typename Traits::ElementType ElementType;
4683 static const InstanceType kInstanceType = Traits::kInstanceType;
4684
4685 DECLARE_CAST(FixedTypedArray<Traits>)
4686
4687 inline ElementType get_scalar(int index);
4688 static inline Handle<Object> get(FixedTypedArray* array, int index);
4689 inline void set(int index, ElementType value);
4690
4691 static inline ElementType from_int(int value);
4692 static inline ElementType from_double(double value);
4693
4694 // This accessor applies the correct conversion from Smi, HeapNumber
4695 // and undefined.
4696 inline void SetValue(uint32_t index, Object* value);
4697
4698 DECLARE_PRINTER(FixedTypedArray)
4699 DECLARE_VERIFIER(FixedTypedArray)
4700
4701 private:
4702 DISALLOW_IMPLICIT_CONSTRUCTORS(FixedTypedArray);
4703 };
4704
4705 #define FIXED_TYPED_ARRAY_TRAITS(Type, type, TYPE, elementType, size) \
4706 class Type##ArrayTraits { \
4707 public: /* NOLINT */ \
4708 typedef elementType ElementType; \
4709 static const InstanceType kInstanceType = FIXED_##TYPE##_ARRAY_TYPE; \
4710 static const char* Designator() { return #type " array"; } \
4711 static inline Handle<Object> ToHandle(Isolate* isolate, \
4712 elementType scalar); \
4713 static inline elementType defaultValue(); \
4714 }; \
4715 \
4716 typedef FixedTypedArray<Type##ArrayTraits> Fixed##Type##Array;
4717
TYPED_ARRAYS(FIXED_TYPED_ARRAY_TRAITS)4718 TYPED_ARRAYS(FIXED_TYPED_ARRAY_TRAITS)
4719
4720 #undef FIXED_TYPED_ARRAY_TRAITS
4721
4722 // DeoptimizationInputData is a fixed array used to hold the deoptimization
4723 // data for code generated by the Hydrogen/Lithium compiler. It also
4724 // contains information about functions that were inlined. If N different
4725 // functions were inlined then first N elements of the literal array will
4726 // contain these functions.
4727 //
4728 // It can be empty.
4729 class DeoptimizationInputData: public FixedArray {
4730 public:
4731 // Layout description. Indices in the array.
4732 static const int kTranslationByteArrayIndex = 0;
4733 static const int kInlinedFunctionCountIndex = 1;
4734 static const int kLiteralArrayIndex = 2;
4735 static const int kOsrAstIdIndex = 3;
4736 static const int kOsrPcOffsetIndex = 4;
4737 static const int kOptimizationIdIndex = 5;
4738 static const int kSharedFunctionInfoIndex = 6;
4739 static const int kWeakCellCacheIndex = 7;
4740 static const int kInliningPositionsIndex = 8;
4741 static const int kFirstDeoptEntryIndex = 9;
4742
4743 // Offsets of deopt entry elements relative to the start of the entry.
4744 static const int kAstIdRawOffset = 0;
4745 static const int kTranslationIndexOffset = 1;
4746 static const int kArgumentsStackHeightOffset = 2;
4747 static const int kPcOffset = 3;
4748 static const int kDeoptEntrySize = 4;
4749
4750 // Simple element accessors.
4751 #define DECLARE_ELEMENT_ACCESSORS(name, type) \
4752 inline type* name(); \
4753 inline void Set##name(type* value);
4754
4755 DECLARE_ELEMENT_ACCESSORS(TranslationByteArray, ByteArray)
4756 DECLARE_ELEMENT_ACCESSORS(InlinedFunctionCount, Smi)
4757 DECLARE_ELEMENT_ACCESSORS(LiteralArray, FixedArray)
4758 DECLARE_ELEMENT_ACCESSORS(OsrAstId, Smi)
4759 DECLARE_ELEMENT_ACCESSORS(OsrPcOffset, Smi)
4760 DECLARE_ELEMENT_ACCESSORS(OptimizationId, Smi)
4761 DECLARE_ELEMENT_ACCESSORS(SharedFunctionInfo, Object)
4762 DECLARE_ELEMENT_ACCESSORS(WeakCellCache, Object)
4763 DECLARE_ELEMENT_ACCESSORS(InliningPositions, PodArray<InliningPosition>)
4764
4765 #undef DECLARE_ELEMENT_ACCESSORS
4766
4767 // Accessors for elements of the ith deoptimization entry.
4768 #define DECLARE_ENTRY_ACCESSORS(name, type) \
4769 inline type* name(int i); \
4770 inline void Set##name(int i, type* value);
4771
4772 DECLARE_ENTRY_ACCESSORS(AstIdRaw, Smi)
4773 DECLARE_ENTRY_ACCESSORS(TranslationIndex, Smi)
4774 DECLARE_ENTRY_ACCESSORS(ArgumentsStackHeight, Smi)
4775 DECLARE_ENTRY_ACCESSORS(Pc, Smi)
4776
4777 #undef DECLARE_ENTRY_ACCESSORS
4778
4779 inline BailoutId AstId(int i);
4780
4781 inline void SetAstId(int i, BailoutId value);
4782
4783 inline int DeoptCount();
4784
4785 static const int kNotInlinedIndex = -1;
4786
4787 // Returns the inlined function at the given position in LiteralArray, or the
4788 // outer function if index == kNotInlinedIndex.
4789 class SharedFunctionInfo* GetInlinedFunction(int index);
4790
4791 // Allocates a DeoptimizationInputData.
4792 static Handle<DeoptimizationInputData> New(Isolate* isolate,
4793 int deopt_entry_count,
4794 PretenureFlag pretenure);
4795
4796 DECLARE_CAST(DeoptimizationInputData)
4797
4798 #ifdef ENABLE_DISASSEMBLER
4799 void DeoptimizationInputDataPrint(std::ostream& os); // NOLINT
4800 #endif
4801
4802 private:
4803 static int IndexForEntry(int i) {
4804 return kFirstDeoptEntryIndex + (i * kDeoptEntrySize);
4805 }
4806
4807
4808 static int LengthFor(int entry_count) { return IndexForEntry(entry_count); }
4809 };
4810
4811 // DeoptimizationOutputData is a fixed array used to hold the deoptimization
4812 // data for code generated by the full compiler.
4813 // The format of the these objects is
4814 // [i * 2]: Ast ID for ith deoptimization.
4815 // [i * 2 + 1]: PC and state of ith deoptimization
4816 class DeoptimizationOutputData: public FixedArray {
4817 public:
4818 inline int DeoptPoints();
4819
4820 inline BailoutId AstId(int index);
4821
4822 inline void SetAstId(int index, BailoutId id);
4823
4824 inline Smi* PcAndState(int index);
4825 inline void SetPcAndState(int index, Smi* offset);
4826
LengthOfFixedArray(int deopt_points)4827 static int LengthOfFixedArray(int deopt_points) {
4828 return deopt_points * 2;
4829 }
4830
4831 // Allocates a DeoptimizationOutputData.
4832 static Handle<DeoptimizationOutputData> New(Isolate* isolate,
4833 int number_of_deopt_points,
4834 PretenureFlag pretenure);
4835
4836 DECLARE_CAST(DeoptimizationOutputData)
4837
4838 #ifdef ENABLE_DISASSEMBLER
4839 void DeoptimizationOutputDataPrint(std::ostream& os); // NOLINT
4840 #endif
4841 };
4842
4843 class TemplateList : public FixedArray {
4844 public:
4845 static Handle<TemplateList> New(Isolate* isolate, int size);
4846 inline int length() const;
4847 inline Object* get(int index) const;
4848 inline void set(int index, Object* value);
4849 static Handle<TemplateList> Add(Isolate* isolate, Handle<TemplateList> list,
4850 Handle<Object> value);
4851 DECLARE_CAST(TemplateList)
4852 private:
4853 static const int kLengthIndex = 0;
4854 static const int kFirstElementIndex = kLengthIndex + 1;
4855 DISALLOW_IMPLICIT_CONSTRUCTORS(TemplateList);
4856 };
4857
4858 // Code describes objects with on-the-fly generated machine code.
4859 class Code: public HeapObject {
4860 public:
4861 // Opaque data type for encapsulating code flags like kind, inline
4862 // cache state, and arguments count.
4863 typedef uint32_t Flags;
4864
4865 #define NON_IC_KIND_LIST(V) \
4866 V(FUNCTION) \
4867 V(OPTIMIZED_FUNCTION) \
4868 V(BYTECODE_HANDLER) \
4869 V(STUB) \
4870 V(HANDLER) \
4871 V(BUILTIN) \
4872 V(REGEXP) \
4873 V(WASM_FUNCTION) \
4874 V(WASM_TO_JS_FUNCTION) \
4875 V(JS_TO_WASM_FUNCTION) \
4876 V(WASM_INTERPRETER_ENTRY)
4877
4878 #define IC_KIND_LIST(V) \
4879 V(LOAD_IC) \
4880 V(LOAD_GLOBAL_IC) \
4881 V(KEYED_LOAD_IC) \
4882 V(STORE_IC) \
4883 V(KEYED_STORE_IC) \
4884 V(BINARY_OP_IC) \
4885 V(COMPARE_IC) \
4886 V(TO_BOOLEAN_IC)
4887
4888 #define CODE_KIND_LIST(V) \
4889 NON_IC_KIND_LIST(V) \
4890 IC_KIND_LIST(V)
4891
4892 enum Kind {
4893 #define DEFINE_CODE_KIND_ENUM(name) name,
4894 CODE_KIND_LIST(DEFINE_CODE_KIND_ENUM)
4895 #undef DEFINE_CODE_KIND_ENUM
4896 NUMBER_OF_KINDS
4897 };
4898
4899 static const char* Kind2String(Kind kind);
4900
4901 static const int kPrologueOffsetNotSet = -1;
4902
4903 #if defined(OBJECT_PRINT) || defined(ENABLE_DISASSEMBLER)
4904 // Printing
4905 static const char* ICState2String(InlineCacheState state);
4906 static void PrintExtraICState(std::ostream& os, // NOLINT
4907 Kind kind, ExtraICState extra);
4908 #endif // defined(OBJECT_PRINT) || defined(ENABLE_DISASSEMBLER)
4909
4910 #ifdef ENABLE_DISASSEMBLER
4911 void Disassemble(const char* name, std::ostream& os); // NOLINT
4912 #endif // ENABLE_DISASSEMBLER
4913
4914 // [instruction_size]: Size of the native instructions
4915 inline int instruction_size() const;
4916 inline void set_instruction_size(int value);
4917
4918 // [relocation_info]: Code relocation information
4919 DECL_ACCESSORS(relocation_info, ByteArray)
4920 void InvalidateRelocation();
4921 void InvalidateEmbeddedObjects();
4922
4923 // [handler_table]: Fixed array containing offsets of exception handlers.
4924 DECL_ACCESSORS(handler_table, FixedArray)
4925
4926 // [deoptimization_data]: Array containing data for deopt.
4927 DECL_ACCESSORS(deoptimization_data, FixedArray)
4928
4929 // [source_position_table]: ByteArray for the source positions table.
4930 DECL_ACCESSORS(source_position_table, ByteArray)
4931
4932 // [raw_type_feedback_info]: This field stores various things, depending on
4933 // the kind of the code object.
4934 // FUNCTION => type feedback information.
4935 // STUB and ICs => major/minor key as Smi.
4936 DECL_ACCESSORS(raw_type_feedback_info, Object)
4937 inline Object* type_feedback_info();
4938 inline void set_type_feedback_info(
4939 Object* value, WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
4940 inline uint32_t stub_key();
4941 inline void set_stub_key(uint32_t key);
4942
4943 // [next_code_link]: Link for lists of optimized or deoptimized code.
4944 // Note that storage for this field is overlapped with typefeedback_info.
4945 DECL_ACCESSORS(next_code_link, Object)
4946
4947 // [gc_metadata]: Field used to hold GC related metadata. The contents of this
4948 // field does not have to be traced during garbage collection since
4949 // it is only used by the garbage collector itself.
4950 DECL_ACCESSORS(gc_metadata, Object)
4951
4952 // [ic_age]: Inline caching age: the value of the Heap::global_ic_age
4953 // at the moment when this object was created.
4954 inline void set_ic_age(int count);
4955 inline int ic_age() const;
4956
4957 // [prologue_offset]: Offset of the function prologue, used for aging
4958 // FUNCTIONs and OPTIMIZED_FUNCTIONs.
4959 inline int prologue_offset() const;
4960 inline void set_prologue_offset(int offset);
4961
4962 // [constant_pool offset]: Offset of the constant pool.
4963 // Valid for FLAG_enable_embedded_constant_pool only
4964 inline int constant_pool_offset() const;
4965 inline void set_constant_pool_offset(int offset);
4966
4967 // Unchecked accessors to be used during GC.
4968 inline ByteArray* unchecked_relocation_info();
4969
4970 inline int relocation_size();
4971
4972 // [flags]: Various code flags.
4973 inline Flags flags();
4974 inline void set_flags(Flags flags);
4975
4976 // [flags]: Access to specific code flags.
4977 inline Kind kind();
4978 inline ExtraICState extra_ic_state(); // Only valid for IC stubs.
4979
4980 // Testers for IC stub kinds.
4981 inline bool is_inline_cache_stub();
4982 inline bool is_debug_stub();
4983 inline bool is_handler();
4984 inline bool is_stub();
4985 inline bool is_binary_op_stub();
4986 inline bool is_compare_ic_stub();
4987 inline bool is_to_boolean_ic_stub();
4988 inline bool is_optimized_code();
4989 inline bool is_wasm_code();
4990
4991 inline bool IsCodeStubOrIC();
4992
4993 inline void set_raw_kind_specific_flags1(int value);
4994 inline void set_raw_kind_specific_flags2(int value);
4995
4996 // Testers for interpreter builtins.
4997 inline bool is_interpreter_trampoline_builtin();
4998
4999 // [is_crankshafted]: For kind STUB or ICs, tells whether or not a code
5000 // object was generated by either the hydrogen or the TurboFan optimizing
5001 // compiler (but it may not be an optimized function).
5002 inline bool is_crankshafted();
5003 inline bool is_hydrogen_stub(); // Crankshafted, but not a function.
5004 inline void set_is_crankshafted(bool value);
5005
5006 // [is_turbofanned]: For kind STUB or OPTIMIZED_FUNCTION, tells whether the
5007 // code object was generated by the TurboFan optimizing compiler.
5008 inline bool is_turbofanned();
5009 inline void set_is_turbofanned(bool value);
5010
5011 // [can_have_weak_objects]: For kind OPTIMIZED_FUNCTION, tells whether the
5012 // embedded objects in code should be treated weakly.
5013 inline bool can_have_weak_objects();
5014 inline void set_can_have_weak_objects(bool value);
5015
5016 // [is_construct_stub]: For kind BUILTIN, tells whether the code object
5017 // represents a hand-written construct stub
5018 // (e.g., NumberConstructor_ConstructStub).
5019 inline bool is_construct_stub();
5020 inline void set_is_construct_stub(bool value);
5021
5022 // [has_deoptimization_support]: For FUNCTION kind, tells if it has
5023 // deoptimization support.
5024 inline bool has_deoptimization_support();
5025 inline void set_has_deoptimization_support(bool value);
5026
5027 // [has_debug_break_slots]: For FUNCTION kind, tells if it has
5028 // been compiled with debug break slots.
5029 inline bool has_debug_break_slots();
5030 inline void set_has_debug_break_slots(bool value);
5031
5032 // [has_reloc_info_for_serialization]: For FUNCTION kind, tells if its
5033 // reloc info includes runtime and external references to support
5034 // serialization/deserialization.
5035 inline bool has_reloc_info_for_serialization();
5036 inline void set_has_reloc_info_for_serialization(bool value);
5037
5038 // [allow_osr_at_loop_nesting_level]: For FUNCTION kind, tells for
5039 // how long the function has been marked for OSR and therefore which
5040 // level of loop nesting we are willing to do on-stack replacement
5041 // for.
5042 inline void set_allow_osr_at_loop_nesting_level(int level);
5043 inline int allow_osr_at_loop_nesting_level();
5044
5045 // [profiler_ticks]: For FUNCTION kind, tells for how many profiler ticks
5046 // the code object was seen on the stack with no IC patching going on.
5047 inline int profiler_ticks();
5048 inline void set_profiler_ticks(int ticks);
5049
5050 // [builtin_index]: For builtins, tells which builtin index the code object
5051 // has. Note that builtins can have a code kind other than BUILTIN. The
5052 // builtin index is a non-negative integer for builtins, and -1 otherwise.
5053 inline int builtin_index();
5054 inline void set_builtin_index(int id);
5055
5056 // [stack_slots]: For kind OPTIMIZED_FUNCTION, the number of stack slots
5057 // reserved in the code prologue.
5058 inline unsigned stack_slots();
5059 inline void set_stack_slots(unsigned slots);
5060
5061 // [safepoint_table_start]: For kind OPTIMIZED_FUNCTION, the offset in
5062 // the instruction stream where the safepoint table starts.
5063 inline unsigned safepoint_table_offset();
5064 inline void set_safepoint_table_offset(unsigned offset);
5065
5066 // [back_edge_table_start]: For kind FUNCTION, the offset in the
5067 // instruction stream where the back edge table starts.
5068 inline unsigned back_edge_table_offset();
5069 inline void set_back_edge_table_offset(unsigned offset);
5070
5071 inline bool back_edges_patched_for_osr();
5072
5073 // [to_boolean_foo]: For kind TO_BOOLEAN_IC tells what state the stub is in.
5074 inline uint16_t to_boolean_state();
5075
5076 // [marked_for_deoptimization]: For kind OPTIMIZED_FUNCTION tells whether
5077 // the code is going to be deoptimized because of dead embedded maps.
5078 inline bool marked_for_deoptimization();
5079 inline void set_marked_for_deoptimization(bool flag);
5080
5081 // [is_promise_rejection]: For kind BUILTIN tells whether the exception
5082 // thrown by the code will lead to promise rejection.
5083 inline bool is_promise_rejection();
5084 inline void set_is_promise_rejection(bool flag);
5085
5086 // [is_exception_caught]: For kind BUILTIN tells whether the exception
5087 // thrown by the code will be caught internally.
5088 inline bool is_exception_caught();
5089 inline void set_is_exception_caught(bool flag);
5090
5091 // [constant_pool]: The constant pool for this function.
5092 inline Address constant_pool();
5093
5094 // Get the safepoint entry for the given pc.
5095 SafepointEntry GetSafepointEntry(Address pc);
5096
5097 // Find an object in a stub with a specified map
5098 Object* FindNthObject(int n, Map* match_map);
5099
5100 // Find the first allocation site in an IC stub.
5101 AllocationSite* FindFirstAllocationSite();
5102
5103 // Find the first map in an IC stub.
5104 Map* FindFirstMap();
5105
5106 // For each (map-to-find, object-to-replace) pair in the pattern, this
5107 // function replaces the corresponding placeholder in the code with the
5108 // object-to-replace. The function assumes that pairs in the pattern come in
5109 // the same order as the placeholders in the code.
5110 // If the placeholder is a weak cell, then the value of weak cell is matched
5111 // against the map-to-find.
5112 void FindAndReplace(const FindAndReplacePattern& pattern);
5113
5114 // The entire code object including its header is copied verbatim to the
5115 // snapshot so that it can be written in one, fast, memcpy during
5116 // deserialization. The deserializer will overwrite some pointers, rather
5117 // like a runtime linker, but the random allocation addresses used in the
5118 // mksnapshot process would still be present in the unlinked snapshot data,
5119 // which would make snapshot production non-reproducible. This method wipes
5120 // out the to-be-overwritten header data for reproducible snapshots.
5121 inline void WipeOutHeader();
5122
5123 // Flags operations.
5124 static inline Flags ComputeFlags(
5125 Kind kind, ExtraICState extra_ic_state = kNoExtraICState,
5126 CacheHolderFlag holder = kCacheOnReceiver);
5127
5128 static inline Flags ComputeHandlerFlags(
5129 Kind handler_kind, CacheHolderFlag holder = kCacheOnReceiver);
5130
5131 static inline CacheHolderFlag ExtractCacheHolderFromFlags(Flags flags);
5132 static inline Kind ExtractKindFromFlags(Flags flags);
5133 static inline ExtraICState ExtractExtraICStateFromFlags(Flags flags);
5134
5135 static inline Flags RemoveHolderFromFlags(Flags flags);
5136
5137 // Convert a target address into a code object.
5138 static inline Code* GetCodeFromTargetAddress(Address address);
5139
5140 // Convert an entry address into an object.
5141 static inline Object* GetObjectFromEntryAddress(Address location_of_address);
5142
5143 // Returns the address of the first instruction.
5144 inline byte* instruction_start();
5145
5146 // Returns the address right after the last instruction.
5147 inline byte* instruction_end();
5148
5149 // Returns the size of the instructions, padding, relocation and unwinding
5150 // information.
5151 inline int body_size();
5152
5153 // Returns the size of code and its metadata. This includes the size of code
5154 // relocation information, deoptimization data and handler table.
5155 inline int SizeIncludingMetadata();
5156
5157 // Returns the address of the first relocation info (read backwards!).
5158 inline byte* relocation_start();
5159
5160 // [has_unwinding_info]: Whether this code object has unwinding information.
5161 // If it doesn't, unwinding_information_start() will point to invalid data.
5162 //
5163 // The body of all code objects has the following layout.
5164 //
5165 // +--------------------------+ <-- instruction_start()
5166 // | instructions |
5167 // | ... |
5168 // +--------------------------+
5169 // | relocation info |
5170 // | ... |
5171 // +--------------------------+ <-- instruction_end()
5172 //
5173 // If has_unwinding_info() is false, instruction_end() points to the first
5174 // memory location after the end of the code object. Otherwise, the body
5175 // continues as follows:
5176 //
5177 // +--------------------------+
5178 // | padding to the next |
5179 // | 8-byte aligned address |
5180 // +--------------------------+ <-- instruction_end()
5181 // | [unwinding_info_size] |
5182 // | as uint64_t |
5183 // +--------------------------+ <-- unwinding_info_start()
5184 // | unwinding info |
5185 // | ... |
5186 // +--------------------------+ <-- unwinding_info_end()
5187 //
5188 // and unwinding_info_end() points to the first memory location after the end
5189 // of the code object.
5190 //
5191 DECL_BOOLEAN_ACCESSORS(has_unwinding_info)
5192
5193 // [unwinding_info_size]: Size of the unwinding information.
5194 inline int unwinding_info_size() const;
5195 inline void set_unwinding_info_size(int value);
5196
5197 // Returns the address of the unwinding information, if any.
5198 inline byte* unwinding_info_start();
5199
5200 // Returns the address right after the end of the unwinding information.
5201 inline byte* unwinding_info_end();
5202
5203 // Code entry point.
5204 inline byte* entry();
5205
5206 // Returns true if pc is inside this object's instructions.
5207 inline bool contains(byte* pc);
5208
5209 // Relocate the code by delta bytes. Called to signal that this code
5210 // object has been moved by delta bytes.
5211 void Relocate(intptr_t delta);
5212
5213 // Migrate code described by desc.
5214 void CopyFrom(const CodeDesc& desc);
5215
5216 // Returns the object size for a given body (used for allocation).
SizeFor(int body_size)5217 static int SizeFor(int body_size) {
5218 DCHECK_SIZE_TAG_ALIGNED(body_size);
5219 return RoundUp(kHeaderSize + body_size, kCodeAlignment);
5220 }
5221
5222 // Calculate the size of the code object to report for log events. This takes
5223 // the layout of the code object into account.
5224 inline int ExecutableSize();
5225
5226 DECLARE_CAST(Code)
5227
5228 // Dispatched behavior.
5229 inline int CodeSize();
5230
5231 DECLARE_PRINTER(Code)
5232 DECLARE_VERIFIER(Code)
5233
5234 void ClearInlineCaches();
5235
5236 BailoutId TranslatePcOffsetToAstId(uint32_t pc_offset);
5237 uint32_t TranslateAstIdToPcOffset(BailoutId ast_id);
5238
5239 #define DECLARE_CODE_AGE_ENUM(X) k##X##CodeAge,
5240 enum Age {
5241 kToBeExecutedOnceCodeAge = -3,
5242 kNotExecutedCodeAge = -2,
5243 kExecutedOnceCodeAge = -1,
5244 kNoAgeCodeAge = 0,
5245 CODE_AGE_LIST(DECLARE_CODE_AGE_ENUM)
5246 kAfterLastCodeAge,
5247 kFirstCodeAge = kToBeExecutedOnceCodeAge,
5248 kLastCodeAge = kAfterLastCodeAge - 1,
5249 kCodeAgeCount = kAfterLastCodeAge - kFirstCodeAge - 1,
5250 kIsOldCodeAge = kSexagenarianCodeAge,
5251 kPreAgedCodeAge = kIsOldCodeAge - 1
5252 };
5253 #undef DECLARE_CODE_AGE_ENUM
5254
5255 // Code aging. Indicates how many full GCs this code has survived without
5256 // being entered through the prologue. Used to determine when it is
5257 // relatively safe to flush this code object and replace it with the lazy
5258 // compilation stub.
5259 static void MakeCodeAgeSequenceYoung(byte* sequence, Isolate* isolate);
5260 static void MarkCodeAsExecuted(byte* sequence, Isolate* isolate);
5261 void MakeYoung(Isolate* isolate);
5262 void PreAge(Isolate* isolate);
5263 void MarkToBeExecutedOnce(Isolate* isolate);
5264 void MakeOlder();
5265 static bool IsYoungSequence(Isolate* isolate, byte* sequence);
5266 bool IsOld();
5267 Age GetAge();
GetPreAgedCodeAgeStub(Isolate * isolate)5268 static inline Code* GetPreAgedCodeAgeStub(Isolate* isolate) {
5269 return GetCodeAgeStub(isolate, kNotExecutedCodeAge);
5270 }
5271
5272 void PrintDeoptLocation(FILE* out, Address pc);
5273 bool CanDeoptAt(Address pc);
5274
5275 #ifdef VERIFY_HEAP
5276 void VerifyEmbeddedObjectsDependency();
5277 #endif
5278
5279 #ifdef DEBUG
5280 enum VerifyMode { kNoContextSpecificPointers, kNoContextRetainingPointers };
5281 void VerifyEmbeddedObjects(VerifyMode mode = kNoContextRetainingPointers);
5282 static void VerifyRecompiledCode(Code* old_code, Code* new_code);
5283 #endif // DEBUG
5284
5285 inline bool CanContainWeakObjects();
5286
5287 inline bool IsWeakObject(Object* object);
5288
5289 static inline bool IsWeakObjectInOptimizedCode(Object* object);
5290
5291 static Handle<WeakCell> WeakCellFor(Handle<Code> code);
5292 WeakCell* CachedWeakCell();
5293
5294 static const int kConstantPoolSize =
5295 FLAG_enable_embedded_constant_pool ? kIntSize : 0;
5296
5297 // Layout description.
5298 static const int kRelocationInfoOffset = HeapObject::kHeaderSize;
5299 static const int kHandlerTableOffset = kRelocationInfoOffset + kPointerSize;
5300 static const int kDeoptimizationDataOffset =
5301 kHandlerTableOffset + kPointerSize;
5302 static const int kSourcePositionTableOffset =
5303 kDeoptimizationDataOffset + kPointerSize;
5304 // For FUNCTION kind, we store the type feedback info here.
5305 static const int kTypeFeedbackInfoOffset =
5306 kSourcePositionTableOffset + kPointerSize;
5307 static const int kNextCodeLinkOffset = kTypeFeedbackInfoOffset + kPointerSize;
5308 static const int kGCMetadataOffset = kNextCodeLinkOffset + kPointerSize;
5309 static const int kInstructionSizeOffset = kGCMetadataOffset + kPointerSize;
5310 static const int kICAgeOffset = kInstructionSizeOffset + kIntSize;
5311 static const int kFlagsOffset = kICAgeOffset + kIntSize;
5312 static const int kKindSpecificFlags1Offset = kFlagsOffset + kIntSize;
5313 static const int kKindSpecificFlags2Offset =
5314 kKindSpecificFlags1Offset + kIntSize;
5315 // Note: We might be able to squeeze this into the flags above.
5316 static const int kPrologueOffset = kKindSpecificFlags2Offset + kIntSize;
5317 static const int kConstantPoolOffset = kPrologueOffset + kIntSize;
5318 static const int kBuiltinIndexOffset =
5319 kConstantPoolOffset + kConstantPoolSize;
5320 static const int kHeaderPaddingStart = kBuiltinIndexOffset + kIntSize;
5321
5322 enum TrapFields { kTrapCodeOffset, kTrapLandingOffset, kTrapDataSize };
5323
5324
5325 // Add padding to align the instruction start following right after
5326 // the Code object header.
5327 static const int kHeaderSize =
5328 (kHeaderPaddingStart + kCodeAlignmentMask) & ~kCodeAlignmentMask;
5329
5330 inline int GetUnwindingInfoSizeOffset() const;
5331
5332 class BodyDescriptor;
5333
5334 // Byte offsets within kKindSpecificFlags1Offset.
5335 static const int kFullCodeFlags = kKindSpecificFlags1Offset;
5336 class FullCodeFlagsHasDeoptimizationSupportField:
5337 public BitField<bool, 0, 1> {}; // NOLINT
5338 class FullCodeFlagsHasDebugBreakSlotsField: public BitField<bool, 1, 1> {};
5339 class FullCodeFlagsHasRelocInfoForSerialization
5340 : public BitField<bool, 2, 1> {};
5341 // Bit 3 in this bitfield is unused.
5342 class ProfilerTicksField : public BitField<int, 4, 28> {};
5343
5344 // Flags layout. BitField<type, shift, size>.
5345 class HasUnwindingInfoField : public BitField<bool, 0, 1> {};
5346 class CacheHolderField
5347 : public BitField<CacheHolderFlag, HasUnwindingInfoField::kNext, 2> {};
5348 class KindField : public BitField<Kind, CacheHolderField::kNext, 5> {};
5349 STATIC_ASSERT(NUMBER_OF_KINDS <= KindField::kMax);
5350 class ExtraICStateField
5351 : public BitField<ExtraICState, KindField::kNext,
5352 PlatformSmiTagging::kSmiValueSize - KindField::kNext> {
5353 };
5354
5355 // KindSpecificFlags1 layout (STUB, BUILTIN and OPTIMIZED_FUNCTION)
5356 static const int kStackSlotsFirstBit = 0;
5357 static const int kStackSlotsBitCount = 24;
5358 static const int kMarkedForDeoptimizationBit =
5359 kStackSlotsFirstBit + kStackSlotsBitCount;
5360 static const int kIsTurbofannedBit = kMarkedForDeoptimizationBit + 1;
5361 static const int kCanHaveWeakObjects = kIsTurbofannedBit + 1;
5362 // Could be moved to overlap previous bits when we need more space.
5363 static const int kIsConstructStub = kCanHaveWeakObjects + 1;
5364 static const int kIsPromiseRejection = kIsConstructStub + 1;
5365 static const int kIsExceptionCaught = kIsPromiseRejection + 1;
5366
5367 STATIC_ASSERT(kStackSlotsFirstBit + kStackSlotsBitCount <= 32);
5368 STATIC_ASSERT(kIsExceptionCaught + 1 <= 32);
5369
5370 class StackSlotsField: public BitField<int,
5371 kStackSlotsFirstBit, kStackSlotsBitCount> {}; // NOLINT
5372 class MarkedForDeoptimizationField
5373 : public BitField<bool, kMarkedForDeoptimizationBit, 1> {}; // NOLINT
5374 class IsTurbofannedField : public BitField<bool, kIsTurbofannedBit, 1> {
5375 }; // NOLINT
5376 class CanHaveWeakObjectsField
5377 : public BitField<bool, kCanHaveWeakObjects, 1> {}; // NOLINT
5378 class IsConstructStubField : public BitField<bool, kIsConstructStub, 1> {
5379 }; // NOLINT
5380 class IsPromiseRejectionField
5381 : public BitField<bool, kIsPromiseRejection, 1> {}; // NOLINT
5382 class IsExceptionCaughtField : public BitField<bool, kIsExceptionCaught, 1> {
5383 }; // NOLINT
5384
5385 // KindSpecificFlags2 layout (ALL)
5386 static const int kIsCrankshaftedBit = 0;
5387 class IsCrankshaftedField: public BitField<bool,
5388 kIsCrankshaftedBit, 1> {}; // NOLINT
5389
5390 // KindSpecificFlags2 layout (STUB and OPTIMIZED_FUNCTION)
5391 static const int kSafepointTableOffsetFirstBit = kIsCrankshaftedBit + 1;
5392 static const int kSafepointTableOffsetBitCount = 30;
5393
5394 STATIC_ASSERT(kSafepointTableOffsetFirstBit +
5395 kSafepointTableOffsetBitCount <= 32);
5396 STATIC_ASSERT(1 + kSafepointTableOffsetBitCount <= 32);
5397
5398 class SafepointTableOffsetField: public BitField<int,
5399 kSafepointTableOffsetFirstBit,
5400 kSafepointTableOffsetBitCount> {}; // NOLINT
5401
5402 // KindSpecificFlags2 layout (FUNCTION)
5403 class BackEdgeTableOffsetField: public BitField<int,
5404 kIsCrankshaftedBit + 1, 27> {}; // NOLINT
5405 class AllowOSRAtLoopNestingLevelField: public BitField<int,
5406 kIsCrankshaftedBit + 1 + 27, 4> {}; // NOLINT
5407
5408 static const int kArgumentsBits = 16;
5409 static const int kMaxArguments = (1 << kArgumentsBits) - 1;
5410
5411 // This constant should be encodable in an ARM instruction.
5412 static const int kFlagsNotUsedInLookup = CacheHolderField::kMask;
5413
5414 private:
5415 friend class RelocIterator;
5416 friend class Deoptimizer; // For FindCodeAgeSequence.
5417
5418 // Code aging
5419 byte* FindCodeAgeSequence();
5420 static Age GetCodeAge(Isolate* isolate, byte* sequence);
5421 static Age GetAgeOfCodeAgeStub(Code* code);
5422 static Code* GetCodeAgeStub(Isolate* isolate, Age age);
5423
5424 // Code aging -- platform-specific
5425 static void PatchPlatformCodeAge(Isolate* isolate, byte* sequence, Age age);
5426
5427 DISALLOW_IMPLICIT_CONSTRUCTORS(Code);
5428 };
5429
5430 class AbstractCode : public HeapObject {
5431 public:
5432 // All code kinds and INTERPRETED_FUNCTION.
5433 enum Kind {
5434 #define DEFINE_CODE_KIND_ENUM(name) name,
5435 CODE_KIND_LIST(DEFINE_CODE_KIND_ENUM)
5436 #undef DEFINE_CODE_KIND_ENUM
5437 INTERPRETED_FUNCTION,
5438 NUMBER_OF_KINDS
5439 };
5440
5441 static const char* Kind2String(Kind kind);
5442
5443 int SourcePosition(int offset);
5444 int SourceStatementPosition(int offset);
5445
5446 // Returns the address of the first instruction.
5447 inline Address instruction_start();
5448
5449 // Returns the address right after the last instruction.
5450 inline Address instruction_end();
5451
5452 // Returns the size of the code instructions.
5453 inline int instruction_size();
5454
5455 // Return the source position table.
5456 inline ByteArray* source_position_table();
5457
5458 // Set the source position table.
5459 inline void set_source_position_table(ByteArray* source_position_table);
5460
5461 // Returns the size of instructions and the metadata.
5462 inline int SizeIncludingMetadata();
5463
5464 // Returns true if pc is inside this object's instructions.
5465 inline bool contains(byte* pc);
5466
5467 // Returns the AbstractCode::Kind of the code.
5468 inline Kind kind();
5469
5470 // Calculate the size of the code object to report for log events. This takes
5471 // the layout of the code object into account.
5472 inline int ExecutableSize();
5473
5474 DECLARE_CAST(AbstractCode)
5475 inline Code* GetCode();
5476 inline BytecodeArray* GetBytecodeArray();
5477
5478 // Max loop nesting marker used to postpose OSR. We don't take loop
5479 // nesting that is deeper than 5 levels into account.
5480 static const int kMaxLoopNestingMarker = 6;
5481 STATIC_ASSERT(Code::AllowOSRAtLoopNestingLevelField::kMax >=
5482 kMaxLoopNestingMarker);
5483 };
5484
5485 // Dependent code is a singly linked list of fixed arrays. Each array contains
5486 // code objects in weak cells for one dependent group. The suffix of the array
5487 // can be filled with the undefined value if the number of codes is less than
5488 // the length of the array.
5489 //
5490 // +------+-----------------+--------+--------+-----+--------+-----------+-----+
5491 // | next | count & group 1 | code 1 | code 2 | ... | code n | undefined | ... |
5492 // +------+-----------------+--------+--------+-----+--------+-----------+-----+
5493 // |
5494 // V
5495 // +------+-----------------+--------+--------+-----+--------+-----------+-----+
5496 // | next | count & group 2 | code 1 | code 2 | ... | code m | undefined | ... |
5497 // +------+-----------------+--------+--------+-----+--------+-----------+-----+
5498 // |
5499 // V
5500 // empty_fixed_array()
5501 //
5502 // The list of fixed arrays is ordered by dependency groups.
5503
5504 class DependentCode: public FixedArray {
5505 public:
5506 enum DependencyGroup {
5507 // Group of code that weakly embed this map and depend on being
5508 // deoptimized when the map is garbage collected.
5509 kWeakCodeGroup,
5510 // Group of code that embed a transition to this map, and depend on being
5511 // deoptimized when the transition is replaced by a new version.
5512 kTransitionGroup,
5513 // Group of code that omit run-time prototype checks for prototypes
5514 // described by this map. The group is deoptimized whenever an object
5515 // described by this map changes shape (and transitions to a new map),
5516 // possibly invalidating the assumptions embedded in the code.
5517 kPrototypeCheckGroup,
5518 // Group of code that depends on global property values in property cells
5519 // not being changed.
5520 kPropertyCellChangedGroup,
5521 // Group of code that omit run-time checks for field(s) introduced by
5522 // this map, i.e. for the field type.
5523 kFieldOwnerGroup,
5524 // Group of code that omit run-time type checks for initial maps of
5525 // constructors.
5526 kInitialMapChangedGroup,
5527 // Group of code that depends on tenuring information in AllocationSites
5528 // not being changed.
5529 kAllocationSiteTenuringChangedGroup,
5530 // Group of code that depends on element transition information in
5531 // AllocationSites not being changed.
5532 kAllocationSiteTransitionChangedGroup
5533 };
5534
5535 static const int kGroupCount = kAllocationSiteTransitionChangedGroup + 1;
5536 static const int kNextLinkIndex = 0;
5537 static const int kFlagsIndex = 1;
5538 static const int kCodesStartIndex = 2;
5539
5540 bool Contains(DependencyGroup group, WeakCell* code_cell);
5541 bool IsEmpty(DependencyGroup group);
5542
5543 static Handle<DependentCode> InsertCompilationDependencies(
5544 Handle<DependentCode> entries, DependencyGroup group,
5545 Handle<Foreign> info);
5546
5547 static Handle<DependentCode> InsertWeakCode(Handle<DependentCode> entries,
5548 DependencyGroup group,
5549 Handle<WeakCell> code_cell);
5550
5551 void UpdateToFinishedCode(DependencyGroup group, Foreign* info,
5552 WeakCell* code_cell);
5553
5554 void RemoveCompilationDependencies(DependentCode::DependencyGroup group,
5555 Foreign* info);
5556
5557 void DeoptimizeDependentCodeGroup(Isolate* isolate,
5558 DependentCode::DependencyGroup group);
5559
5560 bool MarkCodeForDeoptimization(Isolate* isolate,
5561 DependentCode::DependencyGroup group);
5562
5563 // The following low-level accessors should only be used by this class
5564 // and the mark compact collector.
5565 inline DependentCode* next_link();
5566 inline void set_next_link(DependentCode* next);
5567 inline int count();
5568 inline void set_count(int value);
5569 inline DependencyGroup group();
5570 inline void set_group(DependencyGroup group);
5571 inline Object* object_at(int i);
5572 inline void set_object_at(int i, Object* object);
5573 inline void clear_at(int i);
5574 inline void copy(int from, int to);
5575 DECLARE_CAST(DependentCode)
5576
5577 static const char* DependencyGroupName(DependencyGroup group);
5578 static void SetMarkedForDeoptimization(Code* code, DependencyGroup group);
5579
5580 private:
5581 static Handle<DependentCode> Insert(Handle<DependentCode> entries,
5582 DependencyGroup group,
5583 Handle<Object> object);
5584 static Handle<DependentCode> New(DependencyGroup group, Handle<Object> object,
5585 Handle<DependentCode> next);
5586 static Handle<DependentCode> EnsureSpace(Handle<DependentCode> entries);
5587 // Compact by removing cleared weak cells and return true if there was
5588 // any cleared weak cell.
5589 bool Compact();
Grow(int number_of_entries)5590 static int Grow(int number_of_entries) {
5591 if (number_of_entries < 5) return number_of_entries + 1;
5592 return number_of_entries * 5 / 4;
5593 }
5594 inline int flags();
5595 inline void set_flags(int flags);
5596 class GroupField : public BitField<int, 0, 3> {};
5597 class CountField : public BitField<int, 3, 27> {};
5598 STATIC_ASSERT(kGroupCount <= GroupField::kMax + 1);
5599 };
5600
5601
5602 class PrototypeInfo;
5603
5604
5605 // All heap objects have a Map that describes their structure.
5606 // A Map contains information about:
5607 // - Size information about the object
5608 // - How to iterate over an object (for garbage collection)
5609 class Map: public HeapObject {
5610 public:
5611 // Instance size.
5612 // Size in bytes or kVariableSizeSentinel if instances do not have
5613 // a fixed size.
5614 inline int instance_size();
5615 inline void set_instance_size(int value);
5616
5617 // Only to clear an unused byte, remove once byte is used.
5618 inline void clear_unused();
5619
5620 // [inobject_properties_or_constructor_function_index]: Provides access
5621 // to the inobject properties in case of JSObject maps, or the constructor
5622 // function index in case of primitive maps.
5623 inline int inobject_properties_or_constructor_function_index();
5624 inline void set_inobject_properties_or_constructor_function_index(int value);
5625 // Count of properties allocated in the object (JSObject only).
5626 inline int GetInObjectProperties();
5627 inline void SetInObjectProperties(int value);
5628 // Index of the constructor function in the native context (primitives only),
5629 // or the special sentinel value to indicate that there is no object wrapper
5630 // for the primitive (i.e. in case of null or undefined).
5631 static const int kNoConstructorFunctionIndex = 0;
5632 inline int GetConstructorFunctionIndex();
5633 inline void SetConstructorFunctionIndex(int value);
5634 static MaybeHandle<JSFunction> GetConstructorFunction(
5635 Handle<Map> map, Handle<Context> native_context);
5636
5637 // Retrieve interceptors.
5638 inline InterceptorInfo* GetNamedInterceptor();
5639 inline InterceptorInfo* GetIndexedInterceptor();
5640
5641 // Instance type.
5642 inline InstanceType instance_type();
5643 inline void set_instance_type(InstanceType value);
5644
5645 // Tells how many unused property fields are available in the
5646 // instance (only used for JSObject in fast mode).
5647 inline int unused_property_fields();
5648 inline void set_unused_property_fields(int value);
5649
5650 // Bit field.
5651 inline byte bit_field() const;
5652 inline void set_bit_field(byte value);
5653
5654 // Bit field 2.
5655 inline byte bit_field2() const;
5656 inline void set_bit_field2(byte value);
5657
5658 // Bit field 3.
5659 inline uint32_t bit_field3() const;
5660 inline void set_bit_field3(uint32_t bits);
5661
5662 class EnumLengthBits: public BitField<int,
5663 0, kDescriptorIndexBitCount> {}; // NOLINT
5664 class NumberOfOwnDescriptorsBits: public BitField<int,
5665 kDescriptorIndexBitCount, kDescriptorIndexBitCount> {}; // NOLINT
5666 STATIC_ASSERT(kDescriptorIndexBitCount + kDescriptorIndexBitCount == 20);
5667 class DictionaryMap : public BitField<bool, 20, 1> {};
5668 class OwnsDescriptors : public BitField<bool, 21, 1> {};
5669 class HasHiddenPrototype : public BitField<bool, 22, 1> {};
5670 class Deprecated : public BitField<bool, 23, 1> {};
5671 class IsUnstable : public BitField<bool, 24, 1> {};
5672 class IsMigrationTarget : public BitField<bool, 25, 1> {};
5673 class ImmutablePrototype : public BitField<bool, 26, 1> {};
5674 class NewTargetIsBase : public BitField<bool, 27, 1> {};
5675 // Bit 28 is free.
5676
5677 // Keep this bit field at the very end for better code in
5678 // Builtins::kJSConstructStubGeneric stub.
5679 // This counter is used for in-object slack tracking.
5680 // The in-object slack tracking is considered enabled when the counter is
5681 // non zero. The counter only has a valid count for initial maps. For
5682 // transitioned maps only kNoSlackTracking has a meaning, namely that inobject
5683 // slack tracking already finished for the transition tree. Any other value
5684 // indicates that either inobject slack tracking is still in progress, or that
5685 // the map isn't part of the transition tree anymore.
5686 class ConstructionCounter : public BitField<int, 29, 3> {};
5687 static const int kSlackTrackingCounterStart = 7;
5688 static const int kSlackTrackingCounterEnd = 1;
5689 static const int kNoSlackTracking = 0;
5690 STATIC_ASSERT(kSlackTrackingCounterStart <= ConstructionCounter::kMax);
5691
5692
5693 // Inobject slack tracking is the way to reclaim unused inobject space.
5694 //
5695 // The instance size is initially determined by adding some slack to
5696 // expected_nof_properties (to allow for a few extra properties added
5697 // after the constructor). There is no guarantee that the extra space
5698 // will not be wasted.
5699 //
5700 // Here is the algorithm to reclaim the unused inobject space:
5701 // - Detect the first constructor call for this JSFunction.
5702 // When it happens enter the "in progress" state: initialize construction
5703 // counter in the initial_map.
5704 // - While the tracking is in progress initialize unused properties of a new
5705 // object with one_pointer_filler_map instead of undefined_value (the "used"
5706 // part is initialized with undefined_value as usual). This way they can
5707 // be resized quickly and safely.
5708 // - Once enough objects have been created compute the 'slack'
5709 // (traverse the map transition tree starting from the
5710 // initial_map and find the lowest value of unused_property_fields).
5711 // - Traverse the transition tree again and decrease the instance size
5712 // of every map. Existing objects will resize automatically (they are
5713 // filled with one_pointer_filler_map). All further allocations will
5714 // use the adjusted instance size.
5715 // - SharedFunctionInfo's expected_nof_properties left unmodified since
5716 // allocations made using different closures could actually create different
5717 // kind of objects (see prototype inheritance pattern).
5718 //
5719 // Important: inobject slack tracking is not attempted during the snapshot
5720 // creation.
5721
5722 static const int kGenerousAllocationCount =
5723 kSlackTrackingCounterStart - kSlackTrackingCounterEnd + 1;
5724
5725 // Starts the tracking by initializing object constructions countdown counter.
5726 void StartInobjectSlackTracking();
5727
5728 // True if the object constructions countdown counter is a range
5729 // [kSlackTrackingCounterEnd, kSlackTrackingCounterStart].
5730 inline bool IsInobjectSlackTrackingInProgress();
5731
5732 // Does the tracking step.
5733 inline void InobjectSlackTrackingStep();
5734
5735 // Completes inobject slack tracking for the transition tree starting at this
5736 // initial map.
5737 void CompleteInobjectSlackTracking();
5738
5739 // Tells whether the object in the prototype property will be used
5740 // for instances created from this function. If the prototype
5741 // property is set to a value that is not a JSObject, the prototype
5742 // property will not be used to create instances of the function.
5743 // See ECMA-262, 13.2.2.
5744 inline void set_non_instance_prototype(bool value);
5745 inline bool has_non_instance_prototype();
5746
5747 // Tells whether the instance has a [[Construct]] internal method.
5748 // This property is implemented according to ES6, section 7.2.4.
5749 inline void set_is_constructor(bool value);
5750 inline bool is_constructor() const;
5751
5752 // Tells whether the instance with this map has a hidden prototype.
5753 inline void set_has_hidden_prototype(bool value);
5754 inline bool has_hidden_prototype() const;
5755
5756 // Records and queries whether the instance has a named interceptor.
5757 inline void set_has_named_interceptor();
5758 inline bool has_named_interceptor();
5759
5760 // Records and queries whether the instance has an indexed interceptor.
5761 inline void set_has_indexed_interceptor();
5762 inline bool has_indexed_interceptor();
5763
5764 // Tells whether the instance is undetectable.
5765 // An undetectable object is a special class of JSObject: 'typeof' operator
5766 // returns undefined, ToBoolean returns false. Otherwise it behaves like
5767 // a normal JS object. It is useful for implementing undetectable
5768 // document.all in Firefox & Safari.
5769 // See https://bugzilla.mozilla.org/show_bug.cgi?id=248549.
5770 inline void set_is_undetectable();
5771 inline bool is_undetectable();
5772
5773 // Tells whether the instance has a [[Call]] internal method.
5774 // This property is implemented according to ES6, section 7.2.3.
5775 inline void set_is_callable();
5776 inline bool is_callable() const;
5777
5778 inline void set_new_target_is_base(bool value);
5779 inline bool new_target_is_base();
5780 inline void set_is_extensible(bool value);
5781 inline bool is_extensible();
5782 inline void set_is_prototype_map(bool value);
5783 inline bool is_prototype_map() const;
5784
5785 inline void set_elements_kind(ElementsKind elements_kind);
5786 inline ElementsKind elements_kind();
5787
5788 // Tells whether the instance has fast elements that are only Smis.
5789 inline bool has_fast_smi_elements();
5790
5791 // Tells whether the instance has fast elements.
5792 inline bool has_fast_object_elements();
5793 inline bool has_fast_smi_or_object_elements();
5794 inline bool has_fast_double_elements();
5795 inline bool has_fast_elements();
5796 inline bool has_sloppy_arguments_elements();
5797 inline bool has_fast_sloppy_arguments_elements();
5798 inline bool has_fast_string_wrapper_elements();
5799 inline bool has_fixed_typed_array_elements();
5800 inline bool has_dictionary_elements();
5801
5802 static bool IsValidElementsTransition(ElementsKind from_kind,
5803 ElementsKind to_kind);
5804
5805 // Returns true if the current map doesn't have DICTIONARY_ELEMENTS but if a
5806 // map with DICTIONARY_ELEMENTS was found in the prototype chain.
5807 bool DictionaryElementsInPrototypeChainOnly();
5808
5809 inline Map* ElementsTransitionMap();
5810
5811 inline FixedArrayBase* GetInitialElements();
5812
5813 // [raw_transitions]: Provides access to the transitions storage field.
5814 // Don't call set_raw_transitions() directly to overwrite transitions, use
5815 // the TransitionArray::ReplaceTransitions() wrapper instead!
5816 DECL_ACCESSORS(raw_transitions, Object)
5817 // [prototype_info]: Per-prototype metadata. Aliased with transitions
5818 // (which prototype maps don't have).
5819 DECL_ACCESSORS(prototype_info, Object)
5820 // PrototypeInfo is created lazily using this helper (which installs it on
5821 // the given prototype's map).
5822 static Handle<PrototypeInfo> GetOrCreatePrototypeInfo(
5823 Handle<JSObject> prototype, Isolate* isolate);
5824 static Handle<PrototypeInfo> GetOrCreatePrototypeInfo(
5825 Handle<Map> prototype_map, Isolate* isolate);
5826 inline bool should_be_fast_prototype_map() const;
5827 static void SetShouldBeFastPrototypeMap(Handle<Map> map, bool value,
5828 Isolate* isolate);
5829
5830 // [prototype chain validity cell]: Associated with a prototype object,
5831 // stored in that object's map's PrototypeInfo, indicates that prototype
5832 // chains through this object are currently valid. The cell will be
5833 // invalidated and replaced when the prototype chain changes.
5834 static Handle<Cell> GetOrCreatePrototypeChainValidityCell(Handle<Map> map,
5835 Isolate* isolate);
5836 static const int kPrototypeChainValid = 0;
5837 static const int kPrototypeChainInvalid = 1;
5838
5839 // Return the map of the root of object's prototype chain.
5840 Map* GetPrototypeChainRootMap(Isolate* isolate);
5841
5842 // Returns a WeakCell object containing given prototype. The cell is cached
5843 // in PrototypeInfo which is created lazily.
5844 static Handle<WeakCell> GetOrCreatePrototypeWeakCell(
5845 Handle<JSObject> prototype, Isolate* isolate);
5846
5847 Map* FindRootMap();
5848 Map* FindFieldOwner(int descriptor);
5849
5850 inline int GetInObjectPropertyOffset(int index);
5851
5852 int NumberOfFields();
5853
5854 // Returns true if transition to the given map requires special
5855 // synchronization with the concurrent marker.
5856 bool TransitionRequiresSynchronizationWithGC(Map* target);
5857 // Returns true if transition to the given map removes a tagged in-object
5858 // field.
5859 bool TransitionRemovesTaggedField(Map* target);
5860 // Returns true if transition to the given map replaces a tagged in-object
5861 // field with an untagged in-object field.
5862 bool TransitionChangesTaggedFieldToUntaggedField(Map* target);
5863
5864 // TODO(ishell): candidate with JSObject::MigrateToMap().
5865 bool InstancesNeedRewriting(Map* target);
5866 bool InstancesNeedRewriting(Map* target, int target_number_of_fields,
5867 int target_inobject, int target_unused,
5868 int* old_number_of_fields);
5869 // TODO(ishell): moveit!
5870 static Handle<Map> GeneralizeAllFields(Handle<Map> map);
5871 MUST_USE_RESULT static Handle<FieldType> GeneralizeFieldType(
5872 Representation rep1, Handle<FieldType> type1, Representation rep2,
5873 Handle<FieldType> type2, Isolate* isolate);
5874 static void GeneralizeField(Handle<Map> map, int modify_index,
5875 PropertyConstness new_constness,
5876 Representation new_representation,
5877 Handle<FieldType> new_field_type);
5878
5879 static Handle<Map> ReconfigureProperty(Handle<Map> map, int modify_index,
5880 PropertyKind new_kind,
5881 PropertyAttributes new_attributes,
5882 Representation new_representation,
5883 Handle<FieldType> new_field_type);
5884
5885 static Handle<Map> ReconfigureElementsKind(Handle<Map> map,
5886 ElementsKind new_elements_kind);
5887
5888 static Handle<Map> PrepareForDataProperty(Handle<Map> old_map,
5889 int descriptor_number,
5890 PropertyConstness constness,
5891 Handle<Object> value);
5892
5893 static Handle<Map> Normalize(Handle<Map> map, PropertyNormalizationMode mode,
5894 const char* reason);
5895
5896 // Tells whether the map is used for JSObjects in dictionary mode (ie
5897 // normalized objects, ie objects for which HasFastProperties returns false).
5898 // A map can never be used for both dictionary mode and fast mode JSObjects.
5899 // False by default and for HeapObjects that are not JSObjects.
5900 inline void set_dictionary_map(bool value);
5901 inline bool is_dictionary_map();
5902
5903 // Tells whether the instance needs security checks when accessing its
5904 // properties.
5905 inline void set_is_access_check_needed(bool access_check_needed);
5906 inline bool is_access_check_needed();
5907
5908 // Returns true if map has a non-empty stub code cache.
5909 inline bool has_code_cache();
5910
5911 // [prototype]: implicit prototype object.
5912 DECL_ACCESSORS(prototype, Object)
5913 // TODO(jkummerow): make set_prototype private.
5914 static void SetPrototype(
5915 Handle<Map> map, Handle<Object> prototype,
5916 PrototypeOptimizationMode proto_mode = FAST_PROTOTYPE);
5917
5918 // [constructor]: points back to the function responsible for this map.
5919 // The field overlaps with the back pointer. All maps in a transition tree
5920 // have the same constructor, so maps with back pointers can walk the
5921 // back pointer chain until they find the map holding their constructor.
5922 DECL_ACCESSORS(constructor_or_backpointer, Object)
5923 inline Object* GetConstructor() const;
5924 inline void SetConstructor(Object* constructor,
5925 WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
5926 // [back pointer]: points back to the parent map from which a transition
5927 // leads to this map. The field overlaps with the constructor (see above).
5928 inline Object* GetBackPointer();
5929 inline void SetBackPointer(Object* value,
5930 WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
5931
5932 // [instance descriptors]: describes the object.
5933 DECL_ACCESSORS(instance_descriptors, DescriptorArray)
5934
5935 // [layout descriptor]: describes the object layout.
5936 DECL_ACCESSORS(layout_descriptor, LayoutDescriptor)
5937 // |layout descriptor| accessor which can be used from GC.
5938 inline LayoutDescriptor* layout_descriptor_gc_safe();
5939 inline bool HasFastPointerLayout() const;
5940
5941 // |layout descriptor| accessor that is safe to call even when
5942 // FLAG_unbox_double_fields is disabled (in this case Map does not contain
5943 // |layout_descriptor| field at all).
5944 inline LayoutDescriptor* GetLayoutDescriptor();
5945
5946 inline void UpdateDescriptors(DescriptorArray* descriptors,
5947 LayoutDescriptor* layout_descriptor);
5948 inline void InitializeDescriptors(DescriptorArray* descriptors,
5949 LayoutDescriptor* layout_descriptor);
5950
5951 // [stub cache]: contains stubs compiled for this map.
5952 DECL_ACCESSORS(code_cache, FixedArray)
5953
5954 // [dependent code]: list of optimized codes that weakly embed this map.
5955 DECL_ACCESSORS(dependent_code, DependentCode)
5956
5957 // [weak cell cache]: cache that stores a weak cell pointing to this map.
5958 DECL_ACCESSORS(weak_cell_cache, Object)
5959
5960 inline PropertyDetails GetLastDescriptorDetails();
5961
5962 inline int LastAdded();
5963
5964 inline int NumberOfOwnDescriptors();
5965 inline void SetNumberOfOwnDescriptors(int number);
5966
5967 inline Cell* RetrieveDescriptorsPointer();
5968
5969 // Checks whether all properties are stored either in the map or on the object
5970 // (inobject, properties, or elements backing store), requiring no special
5971 // checks.
5972 bool OnlyHasSimpleProperties();
5973 inline int EnumLength();
5974 inline void SetEnumLength(int length);
5975
5976 inline bool owns_descriptors();
5977 inline void set_owns_descriptors(bool owns_descriptors);
5978 inline void mark_unstable();
5979 inline bool is_stable();
5980 inline void set_migration_target(bool value);
5981 inline bool is_migration_target();
5982 inline void set_immutable_proto(bool value);
5983 inline bool is_immutable_proto();
5984 inline void set_construction_counter(int value);
5985 inline int construction_counter();
5986 inline void deprecate();
5987 inline bool is_deprecated();
5988 inline bool CanBeDeprecated();
5989 // Returns a non-deprecated version of the input. If the input was not
5990 // deprecated, it is directly returned. Otherwise, the non-deprecated version
5991 // is found by re-transitioning from the root of the transition tree using the
5992 // descriptor array of the map. Returns MaybeHandle<Map>() if no updated map
5993 // is found.
5994 static MaybeHandle<Map> TryUpdate(Handle<Map> map) WARN_UNUSED_RESULT;
5995
5996 // Returns a non-deprecated version of the input. This method may deprecate
5997 // existing maps along the way if encodings conflict. Not for use while
5998 // gathering type feedback. Use TryUpdate in those cases instead.
5999 static Handle<Map> Update(Handle<Map> map);
6000
6001 static inline Handle<Map> CopyInitialMap(Handle<Map> map);
6002 static Handle<Map> CopyInitialMap(Handle<Map> map, int instance_size,
6003 int in_object_properties,
6004 int unused_property_fields);
6005 static Handle<Map> CopyDropDescriptors(Handle<Map> map);
6006 static Handle<Map> CopyInsertDescriptor(Handle<Map> map,
6007 Descriptor* descriptor,
6008 TransitionFlag flag);
6009
6010 static Handle<Object> WrapFieldType(Handle<FieldType> type);
6011 static FieldType* UnwrapFieldType(Object* wrapped_type);
6012
6013 MUST_USE_RESULT static MaybeHandle<Map> CopyWithField(
6014 Handle<Map> map, Handle<Name> name, Handle<FieldType> type,
6015 PropertyAttributes attributes, PropertyConstness constness,
6016 Representation representation, TransitionFlag flag);
6017
6018 MUST_USE_RESULT static MaybeHandle<Map> CopyWithConstant(
6019 Handle<Map> map,
6020 Handle<Name> name,
6021 Handle<Object> constant,
6022 PropertyAttributes attributes,
6023 TransitionFlag flag);
6024
6025 // Returns a new map with all transitions dropped from the given map and
6026 // the ElementsKind set.
6027 static Handle<Map> TransitionElementsTo(Handle<Map> map,
6028 ElementsKind to_kind);
6029
6030 static Handle<Map> AsElementsKind(Handle<Map> map, ElementsKind kind);
6031
6032 static Handle<Map> CopyAsElementsKind(Handle<Map> map,
6033 ElementsKind kind,
6034 TransitionFlag flag);
6035
6036 static Handle<Map> AsLanguageMode(Handle<Map> initial_map,
6037 LanguageMode language_mode,
6038 FunctionKind kind);
6039
6040
6041 static Handle<Map> CopyForPreventExtensions(Handle<Map> map,
6042 PropertyAttributes attrs_to_add,
6043 Handle<Symbol> transition_marker,
6044 const char* reason);
6045
6046 static Handle<Map> FixProxy(Handle<Map> map, InstanceType type, int size);
6047
6048
6049 // Maximal number of fast properties. Used to restrict the number of map
6050 // transitions to avoid an explosion in the number of maps for objects used as
6051 // dictionaries.
6052 inline bool TooManyFastProperties(StoreFromKeyed store_mode);
6053 static Handle<Map> TransitionToDataProperty(Handle<Map> map,
6054 Handle<Name> name,
6055 Handle<Object> value,
6056 PropertyAttributes attributes,
6057 PropertyConstness constness,
6058 StoreFromKeyed store_mode);
6059 static Handle<Map> TransitionToAccessorProperty(
6060 Isolate* isolate, Handle<Map> map, Handle<Name> name, int descriptor,
6061 Handle<Object> getter, Handle<Object> setter,
6062 PropertyAttributes attributes);
6063 static Handle<Map> ReconfigureExistingProperty(Handle<Map> map,
6064 int descriptor,
6065 PropertyKind kind,
6066 PropertyAttributes attributes);
6067
6068 inline void AppendDescriptor(Descriptor* desc);
6069
6070 // Returns a copy of the map, prepared for inserting into the transition
6071 // tree (if the |map| owns descriptors then the new one will share
6072 // descriptors with |map|).
6073 static Handle<Map> CopyForTransition(Handle<Map> map, const char* reason);
6074
6075 // Returns a copy of the map, with all transitions dropped from the
6076 // instance descriptors.
6077 static Handle<Map> Copy(Handle<Map> map, const char* reason);
6078 static Handle<Map> Create(Isolate* isolate, int inobject_properties);
6079
6080 // Returns the next free property index (only valid for FAST MODE).
6081 int NextFreePropertyIndex();
6082
6083 // Returns the number of properties described in instance_descriptors
6084 // filtering out properties with the specified attributes.
6085 int NumberOfDescribedProperties(DescriptorFlag which = OWN_DESCRIPTORS,
6086 PropertyFilter filter = ALL_PROPERTIES);
6087
6088 DECLARE_CAST(Map)
6089
6090 // Code cache operations.
6091
6092 // Clears the code cache.
6093 inline void ClearCodeCache(Heap* heap);
6094
6095 // Update code cache.
6096 static void UpdateCodeCache(Handle<Map> map,
6097 Handle<Name> name,
6098 Handle<Code> code);
6099
6100 // Extend the descriptor array of the map with the list of descriptors.
6101 // In case of duplicates, the latest descriptor is used.
6102 static void AppendCallbackDescriptors(Handle<Map> map,
6103 Handle<Object> descriptors);
6104
6105 static inline int SlackForArraySize(int old_size, int size_limit);
6106
6107 static void EnsureDescriptorSlack(Handle<Map> map, int slack);
6108
6109 Code* LookupInCodeCache(Name* name, Code::Flags code);
6110
6111 static Handle<Map> GetObjectCreateMap(Handle<HeapObject> prototype);
6112
6113 // Computes a hash value for this map, to be used in HashTables and such.
6114 int Hash();
6115
6116 // Returns the transitioned map for this map with the most generic
6117 // elements_kind that's found in |candidates|, or |nullptr| if no match is
6118 // found at all.
6119 Map* FindElementsKindTransitionedMap(MapHandleList* candidates);
6120
6121 inline bool CanTransition();
6122
6123 inline bool IsBooleanMap();
6124 inline bool IsPrimitiveMap();
6125 inline bool IsJSReceiverMap();
6126 inline bool IsJSObjectMap();
6127 inline bool IsJSArrayMap();
6128 inline bool IsJSFunctionMap();
6129 inline bool IsStringMap();
6130 inline bool IsJSProxyMap();
6131 inline bool IsModuleMap();
6132 inline bool IsJSGlobalProxyMap();
6133 inline bool IsJSGlobalObjectMap();
6134 inline bool IsJSTypedArrayMap();
6135 inline bool IsJSDataViewMap();
6136
6137 inline bool IsSpecialReceiverMap();
6138
6139 inline bool CanOmitMapChecks();
6140
6141 static void AddDependentCode(Handle<Map> map,
6142 DependentCode::DependencyGroup group,
6143 Handle<Code> code);
6144
6145 bool IsMapInArrayPrototypeChain();
6146
6147 static Handle<WeakCell> WeakCellForMap(Handle<Map> map);
6148
6149 // Dispatched behavior.
6150 DECLARE_PRINTER(Map)
6151 DECLARE_VERIFIER(Map)
6152
6153 #ifdef VERIFY_HEAP
6154 void DictionaryMapVerify();
6155 void VerifyOmittedMapChecks();
6156 #endif
6157
6158 inline int visitor_id();
6159 inline void set_visitor_id(int visitor_id);
6160
6161 static Handle<Map> TransitionToPrototype(Handle<Map> map,
6162 Handle<Object> prototype,
6163 PrototypeOptimizationMode mode);
6164
6165 static Handle<Map> TransitionToImmutableProto(Handle<Map> map);
6166
6167 static const int kMaxPreAllocatedPropertyFields = 255;
6168
6169 // Layout description.
6170 static const int kInstanceSizesOffset = HeapObject::kHeaderSize;
6171 static const int kInstanceAttributesOffset = kInstanceSizesOffset + kIntSize;
6172 static const int kBitField3Offset = kInstanceAttributesOffset + kIntSize;
6173 static const int kPrototypeOffset = kBitField3Offset + kPointerSize;
6174 static const int kConstructorOrBackPointerOffset =
6175 kPrototypeOffset + kPointerSize;
6176 // When there is only one transition, it is stored directly in this field;
6177 // otherwise a transition array is used.
6178 // For prototype maps, this slot is used to store this map's PrototypeInfo
6179 // struct.
6180 static const int kTransitionsOrPrototypeInfoOffset =
6181 kConstructorOrBackPointerOffset + kPointerSize;
6182 static const int kDescriptorsOffset =
6183 kTransitionsOrPrototypeInfoOffset + kPointerSize;
6184 #if V8_DOUBLE_FIELDS_UNBOXING
6185 static const int kLayoutDescriptorOffset = kDescriptorsOffset + kPointerSize;
6186 static const int kCodeCacheOffset = kLayoutDescriptorOffset + kPointerSize;
6187 #else
6188 static const int kLayoutDescriptorOffset = 1; // Must not be ever accessed.
6189 static const int kCodeCacheOffset = kDescriptorsOffset + kPointerSize;
6190 #endif
6191 static const int kDependentCodeOffset = kCodeCacheOffset + kPointerSize;
6192 static const int kWeakCellCacheOffset = kDependentCodeOffset + kPointerSize;
6193 static const int kSize = kWeakCellCacheOffset + kPointerSize;
6194
6195 // Layout of pointer fields. Heap iteration code relies on them
6196 // being continuously allocated.
6197 static const int kPointerFieldsBeginOffset = Map::kPrototypeOffset;
6198 static const int kPointerFieldsEndOffset = kSize;
6199
6200 // Byte offsets within kInstanceSizesOffset.
6201 static const int kInstanceSizeOffset = kInstanceSizesOffset + 0;
6202 static const int kInObjectPropertiesOrConstructorFunctionIndexByte = 1;
6203 static const int kInObjectPropertiesOrConstructorFunctionIndexOffset =
6204 kInstanceSizesOffset + kInObjectPropertiesOrConstructorFunctionIndexByte;
6205 // Note there is one byte available for use here.
6206 static const int kUnusedByte = 2;
6207 static const int kUnusedOffset = kInstanceSizesOffset + kUnusedByte;
6208 static const int kVisitorIdByte = 3;
6209 static const int kVisitorIdOffset = kInstanceSizesOffset + kVisitorIdByte;
6210
6211 // Byte offsets within kInstanceAttributesOffset attributes.
6212 #if V8_TARGET_LITTLE_ENDIAN
6213 // Order instance type and bit field together such that they can be loaded
6214 // together as a 16-bit word with instance type in the lower 8 bits regardless
6215 // of endianess. Also provide endian-independent offset to that 16-bit word.
6216 static const int kInstanceTypeOffset = kInstanceAttributesOffset + 0;
6217 static const int kBitFieldOffset = kInstanceAttributesOffset + 1;
6218 #else
6219 static const int kBitFieldOffset = kInstanceAttributesOffset + 0;
6220 static const int kInstanceTypeOffset = kInstanceAttributesOffset + 1;
6221 #endif
6222 static const int kInstanceTypeAndBitFieldOffset =
6223 kInstanceAttributesOffset + 0;
6224 static const int kBitField2Offset = kInstanceAttributesOffset + 2;
6225 static const int kUnusedPropertyFieldsOffset = kInstanceAttributesOffset + 3;
6226
6227 STATIC_ASSERT(kInstanceTypeAndBitFieldOffset ==
6228 Internals::kMapInstanceTypeAndBitFieldOffset);
6229
6230 // Bit positions for bit field.
6231 static const int kHasNonInstancePrototype = 0;
6232 static const int kIsCallable = 1;
6233 static const int kHasNamedInterceptor = 2;
6234 static const int kHasIndexedInterceptor = 3;
6235 static const int kIsUndetectable = 4;
6236 static const int kIsAccessCheckNeeded = 5;
6237 static const int kIsConstructor = 6;
6238 // Bit 7 is free.
6239
6240 // Bit positions for bit field 2
6241 static const int kIsExtensible = 0;
6242 // Bit 1 is free.
6243 class IsPrototypeMapBits : public BitField<bool, 2, 1> {};
6244 class ElementsKindBits: public BitField<ElementsKind, 3, 5> {};
6245
6246 // Derived values from bit field 2
6247 static const int8_t kMaximumBitField2FastElementValue = static_cast<int8_t>(
6248 (FAST_ELEMENTS + 1) << Map::ElementsKindBits::kShift) - 1;
6249 static const int8_t kMaximumBitField2FastSmiElementValue =
6250 static_cast<int8_t>((FAST_SMI_ELEMENTS + 1) <<
6251 Map::ElementsKindBits::kShift) - 1;
6252 static const int8_t kMaximumBitField2FastHoleyElementValue =
6253 static_cast<int8_t>((FAST_HOLEY_ELEMENTS + 1) <<
6254 Map::ElementsKindBits::kShift) - 1;
6255 static const int8_t kMaximumBitField2FastHoleySmiElementValue =
6256 static_cast<int8_t>((FAST_HOLEY_SMI_ELEMENTS + 1) <<
6257 Map::ElementsKindBits::kShift) - 1;
6258
6259 typedef FixedBodyDescriptor<kPointerFieldsBeginOffset,
6260 kPointerFieldsEndOffset,
6261 kSize> BodyDescriptor;
6262
6263 // Compares this map to another to see if they describe equivalent objects.
6264 // If |mode| is set to CLEAR_INOBJECT_PROPERTIES, |other| is treated as if
6265 // it had exactly zero inobject properties.
6266 // The "shared" flags of both this map and |other| are ignored.
6267 bool EquivalentToForNormalization(Map* other, PropertyNormalizationMode mode);
6268
6269 // Returns true if given field is unboxed double.
6270 inline bool IsUnboxedDoubleField(FieldIndex index);
6271
6272 #if TRACE_MAPS
6273 static void TraceTransition(const char* what, Map* from, Map* to, Name* name);
6274 static void TraceAllTransitions(Map* map);
6275 #endif
6276
6277 static inline Handle<Map> AddMissingTransitionsForTesting(
6278 Handle<Map> split_map, Handle<DescriptorArray> descriptors,
6279 Handle<LayoutDescriptor> full_layout_descriptor);
6280
6281 // Fires when the layout of an object with a leaf map changes.
6282 // This includes adding transitions to the leaf map or changing
6283 // the descriptor array.
6284 inline void NotifyLeafMapLayoutChange();
6285
6286 private:
6287 // Returns the map that this (root) map transitions to if its elements_kind
6288 // is changed to |elements_kind|, or |nullptr| if no such map is cached yet.
6289 Map* LookupElementsTransitionMap(ElementsKind elements_kind);
6290
6291 // Tries to replay property transitions starting from this (root) map using
6292 // the descriptor array of the |map|. The |root_map| is expected to have
6293 // proper elements kind and therefore elements kinds transitions are not
6294 // taken by this function. Returns |nullptr| if matching transition map is
6295 // not found.
6296 Map* TryReplayPropertyTransitions(Map* map);
6297
6298 static void ConnectTransition(Handle<Map> parent, Handle<Map> child,
6299 Handle<Name> name, SimpleTransitionFlag flag);
6300
6301 bool EquivalentToForTransition(Map* other);
6302 static Handle<Map> RawCopy(Handle<Map> map, int instance_size);
6303 static Handle<Map> ShareDescriptor(Handle<Map> map,
6304 Handle<DescriptorArray> descriptors,
6305 Descriptor* descriptor);
6306 static Handle<Map> AddMissingTransitions(
6307 Handle<Map> map, Handle<DescriptorArray> descriptors,
6308 Handle<LayoutDescriptor> full_layout_descriptor);
6309 static void InstallDescriptors(
6310 Handle<Map> parent_map, Handle<Map> child_map, int new_descriptor,
6311 Handle<DescriptorArray> descriptors,
6312 Handle<LayoutDescriptor> full_layout_descriptor);
6313 static Handle<Map> CopyAddDescriptor(Handle<Map> map,
6314 Descriptor* descriptor,
6315 TransitionFlag flag);
6316 static Handle<Map> CopyReplaceDescriptors(
6317 Handle<Map> map, Handle<DescriptorArray> descriptors,
6318 Handle<LayoutDescriptor> layout_descriptor, TransitionFlag flag,
6319 MaybeHandle<Name> maybe_name, const char* reason,
6320 SimpleTransitionFlag simple_flag);
6321
6322 static Handle<Map> CopyReplaceDescriptor(Handle<Map> map,
6323 Handle<DescriptorArray> descriptors,
6324 Descriptor* descriptor,
6325 int index,
6326 TransitionFlag flag);
6327 static MUST_USE_RESULT MaybeHandle<Map> TryReconfigureExistingProperty(
6328 Handle<Map> map, int descriptor, PropertyKind kind,
6329 PropertyAttributes attributes, const char** reason);
6330
6331 static Handle<Map> CopyNormalized(Handle<Map> map,
6332 PropertyNormalizationMode mode);
6333
6334 // TODO(ishell): Move to MapUpdater.
6335 static Handle<Map> CopyGeneralizeAllFields(
6336 Handle<Map> map, ElementsKind elements_kind, int modify_index,
6337 PropertyKind kind, PropertyAttributes attributes, const char* reason);
6338
6339 void DeprecateTransitionTree();
6340
6341 void ReplaceDescriptors(DescriptorArray* new_descriptors,
6342 LayoutDescriptor* new_layout_descriptor);
6343
6344
6345 // Update field type of the given descriptor to new representation and new
6346 // type. The type must be prepared for storing in descriptor array:
6347 // it must be either a simple type or a map wrapped in a weak cell.
6348 void UpdateFieldType(int descriptor_number, Handle<Name> name,
6349 PropertyConstness new_constness,
6350 Representation new_representation,
6351 Handle<Object> new_wrapped_type);
6352
6353 // TODO(ishell): Move to MapUpdater.
6354 void PrintReconfiguration(FILE* file, int modify_index, PropertyKind kind,
6355 PropertyAttributes attributes);
6356 // TODO(ishell): Move to MapUpdater.
6357 void PrintGeneralization(FILE* file, const char* reason, int modify_index,
6358 int split, int descriptors, bool constant_to_field,
6359 Representation old_representation,
6360 Representation new_representation,
6361 MaybeHandle<FieldType> old_field_type,
6362 MaybeHandle<Object> old_value,
6363 MaybeHandle<FieldType> new_field_type,
6364 MaybeHandle<Object> new_value);
6365 static const int kFastPropertiesSoftLimit = 12;
6366 static const int kMaxFastProperties = 128;
6367
6368 friend class MapUpdater;
6369
6370 DISALLOW_IMPLICIT_CONSTRUCTORS(Map);
6371 };
6372
6373
6374 // An abstract superclass, a marker class really, for simple structure classes.
6375 // It doesn't carry much functionality but allows struct classes to be
6376 // identified in the type system.
6377 class Struct: public HeapObject {
6378 public:
6379 inline void InitializeBody(int object_size);
6380 DECLARE_CAST(Struct)
6381 };
6382
6383 // A container struct to hold state required for PromiseResolveThenableJob.
6384 class PromiseResolveThenableJobInfo : public Struct {
6385 public:
6386 DECL_ACCESSORS(thenable, JSReceiver)
6387 DECL_ACCESSORS(then, JSReceiver)
6388 DECL_ACCESSORS(resolve, JSFunction)
6389 DECL_ACCESSORS(reject, JSFunction)
6390
6391 DECL_ACCESSORS(context, Context)
6392
6393 static const int kThenableOffset = Struct::kHeaderSize;
6394 static const int kThenOffset = kThenableOffset + kPointerSize;
6395 static const int kResolveOffset = kThenOffset + kPointerSize;
6396 static const int kRejectOffset = kResolveOffset + kPointerSize;
6397 static const int kContextOffset = kRejectOffset + kPointerSize;
6398 static const int kSize = kContextOffset + kPointerSize;
6399
6400 DECLARE_CAST(PromiseResolveThenableJobInfo)
6401 DECLARE_PRINTER(PromiseResolveThenableJobInfo)
6402 DECLARE_VERIFIER(PromiseResolveThenableJobInfo)
6403
6404 private:
6405 DISALLOW_IMPLICIT_CONSTRUCTORS(PromiseResolveThenableJobInfo);
6406 };
6407
6408 class JSPromise;
6409
6410 // Struct to hold state required for PromiseReactionJob.
6411 class PromiseReactionJobInfo : public Struct {
6412 public:
6413 DECL_ACCESSORS(value, Object)
6414 DECL_ACCESSORS(tasks, Object)
6415
6416 // Check comment in JSPromise for information on what state these
6417 // deferred fields could be in.
6418 DECL_ACCESSORS(deferred_promise, Object)
6419 DECL_ACCESSORS(deferred_on_resolve, Object)
6420 DECL_ACCESSORS(deferred_on_reject, Object)
6421
6422 DECL_INT_ACCESSORS(debug_id)
6423
6424 DECL_ACCESSORS(context, Context)
6425
6426 static const int kValueOffset = Struct::kHeaderSize;
6427 static const int kTasksOffset = kValueOffset + kPointerSize;
6428 static const int kDeferredPromiseOffset = kTasksOffset + kPointerSize;
6429 static const int kDeferredOnResolveOffset =
6430 kDeferredPromiseOffset + kPointerSize;
6431 static const int kDeferredOnRejectOffset =
6432 kDeferredOnResolveOffset + kPointerSize;
6433 static const int kContextOffset = kDeferredOnRejectOffset + kPointerSize;
6434 static const int kSize = kContextOffset + kPointerSize;
6435
6436 DECLARE_CAST(PromiseReactionJobInfo)
6437 DECLARE_PRINTER(PromiseReactionJobInfo)
6438 DECLARE_VERIFIER(PromiseReactionJobInfo)
6439
6440 private:
6441 DISALLOW_IMPLICIT_CONSTRUCTORS(PromiseReactionJobInfo);
6442 };
6443
6444 // Container for metadata stored on each prototype map.
6445 class PrototypeInfo : public Struct {
6446 public:
6447 static const int UNREGISTERED = -1;
6448
6449 // [weak_cell]: A WeakCell containing this prototype. ICs cache the cell here.
6450 DECL_ACCESSORS(weak_cell, Object)
6451
6452 // [prototype_users]: WeakFixedArray containing maps using this prototype,
6453 // or Smi(0) if uninitialized.
6454 DECL_ACCESSORS(prototype_users, Object)
6455
6456 // [object_create_map]: A field caching the map for Object.create(prototype).
6457 static inline void SetObjectCreateMap(Handle<PrototypeInfo> info,
6458 Handle<Map> map);
6459 inline Map* ObjectCreateMap();
6460 inline bool HasObjectCreateMap();
6461
6462 // [registry_slot]: Slot in prototype's user registry where this user
6463 // is stored. Returns UNREGISTERED if this prototype has not been registered.
6464 inline int registry_slot() const;
6465 inline void set_registry_slot(int slot);
6466 // [validity_cell]: Cell containing the validity bit for prototype chains
6467 // going through this object, or Smi(0) if uninitialized.
6468 // When a prototype object changes its map, then both its own validity cell
6469 // and those of all "downstream" prototypes are invalidated; handlers for a
6470 // given receiver embed the currently valid cell for that receiver's prototype
6471 // during their compilation and check it on execution.
6472 DECL_ACCESSORS(validity_cell, Object)
6473 // [bit_field]
6474 inline int bit_field() const;
6475 inline void set_bit_field(int bit_field);
6476
6477 DECL_BOOLEAN_ACCESSORS(should_be_fast_map)
6478
6479 DECLARE_CAST(PrototypeInfo)
6480
6481 // Dispatched behavior.
6482 DECLARE_PRINTER(PrototypeInfo)
6483 DECLARE_VERIFIER(PrototypeInfo)
6484
6485 static const int kWeakCellOffset = HeapObject::kHeaderSize;
6486 static const int kPrototypeUsersOffset = kWeakCellOffset + kPointerSize;
6487 static const int kRegistrySlotOffset = kPrototypeUsersOffset + kPointerSize;
6488 static const int kValidityCellOffset = kRegistrySlotOffset + kPointerSize;
6489 static const int kObjectCreateMap = kValidityCellOffset + kPointerSize;
6490 static const int kBitFieldOffset = kObjectCreateMap + kPointerSize;
6491 static const int kSize = kBitFieldOffset + kPointerSize;
6492
6493 // Bit field usage.
6494 static const int kShouldBeFastBit = 0;
6495
6496 private:
6497 DECL_ACCESSORS(object_create_map, Object)
6498
6499 DISALLOW_IMPLICIT_CONSTRUCTORS(PrototypeInfo);
6500 };
6501
6502 class Tuple2 : public Struct {
6503 public:
6504 DECL_ACCESSORS(value1, Object)
6505 DECL_ACCESSORS(value2, Object)
6506
6507 DECLARE_CAST(Tuple2)
6508
6509 // Dispatched behavior.
6510 DECLARE_PRINTER(Tuple2)
6511 DECLARE_VERIFIER(Tuple2)
6512
6513 static const int kValue1Offset = HeapObject::kHeaderSize;
6514 static const int kValue2Offset = kValue1Offset + kPointerSize;
6515 static const int kSize = kValue2Offset + kPointerSize;
6516
6517 private:
6518 DISALLOW_IMPLICIT_CONSTRUCTORS(Tuple2);
6519 };
6520
6521 class Tuple3 : public Tuple2 {
6522 public:
6523 DECL_ACCESSORS(value3, Object)
6524
6525 DECLARE_CAST(Tuple3)
6526
6527 // Dispatched behavior.
6528 DECLARE_PRINTER(Tuple3)
6529 DECLARE_VERIFIER(Tuple3)
6530
6531 static const int kValue3Offset = Tuple2::kSize;
6532 static const int kSize = kValue3Offset + kPointerSize;
6533
6534 private:
6535 DISALLOW_IMPLICIT_CONSTRUCTORS(Tuple3);
6536 };
6537
6538 // Pair used to store both a ScopeInfo and an extension object in the extension
6539 // slot of a block, catch, or with context. Needed in the rare case where a
6540 // declaration block scope (a "varblock" as used to desugar parameter
6541 // destructuring) also contains a sloppy direct eval, or for with and catch
6542 // scopes. (In no other case both are needed at the same time.)
6543 class ContextExtension : public Struct {
6544 public:
6545 // [scope_info]: Scope info.
6546 DECL_ACCESSORS(scope_info, ScopeInfo)
6547 // [extension]: Extension object.
6548 DECL_ACCESSORS(extension, Object)
6549
6550 DECLARE_CAST(ContextExtension)
6551
6552 // Dispatched behavior.
6553 DECLARE_PRINTER(ContextExtension)
6554 DECLARE_VERIFIER(ContextExtension)
6555
6556 static const int kScopeInfoOffset = HeapObject::kHeaderSize;
6557 static const int kExtensionOffset = kScopeInfoOffset + kPointerSize;
6558 static const int kSize = kExtensionOffset + kPointerSize;
6559
6560 private:
6561 DISALLOW_IMPLICIT_CONSTRUCTORS(ContextExtension);
6562 };
6563
6564 // Script describes a script which has been added to the VM.
6565 class Script: public Struct {
6566 public:
6567 // Script types.
6568 enum Type {
6569 TYPE_NATIVE = 0,
6570 TYPE_EXTENSION = 1,
6571 TYPE_NORMAL = 2,
6572 TYPE_WASM = 3,
6573 TYPE_INSPECTOR = 4
6574 };
6575
6576 // Script compilation types.
6577 enum CompilationType {
6578 COMPILATION_TYPE_HOST = 0,
6579 COMPILATION_TYPE_EVAL = 1
6580 };
6581
6582 // Script compilation state.
6583 enum CompilationState {
6584 COMPILATION_STATE_INITIAL = 0,
6585 COMPILATION_STATE_COMPILED = 1
6586 };
6587
6588 // [source]: the script source.
6589 DECL_ACCESSORS(source, Object)
6590
6591 // [name]: the script name.
6592 DECL_ACCESSORS(name, Object)
6593
6594 // [id]: the script id.
6595 DECL_INT_ACCESSORS(id)
6596
6597 // [line_offset]: script line offset in resource from where it was extracted.
6598 DECL_INT_ACCESSORS(line_offset)
6599
6600 // [column_offset]: script column offset in resource from where it was
6601 // extracted.
6602 DECL_INT_ACCESSORS(column_offset)
6603
6604 // [context_data]: context data for the context this script was compiled in.
6605 DECL_ACCESSORS(context_data, Object)
6606
6607 // [wrapper]: the wrapper cache. This is either undefined or a WeakCell.
6608 DECL_ACCESSORS(wrapper, HeapObject)
6609
6610 // [type]: the script type.
6611 DECL_INT_ACCESSORS(type)
6612
6613 // [line_ends]: FixedArray of line ends positions.
6614 DECL_ACCESSORS(line_ends, Object)
6615
6616 // [eval_from_shared]: for eval scripts the shared function info for the
6617 // function from which eval was called.
6618 DECL_ACCESSORS(eval_from_shared, Object)
6619
6620 // [eval_from_position]: the source position in the code for the function
6621 // from which eval was called, as positive integer. Or the code offset in the
6622 // code from which eval was called, as negative integer.
6623 DECL_INT_ACCESSORS(eval_from_position)
6624
6625 // [shared_function_infos]: weak fixed array containing all shared
6626 // function infos created from this script.
6627 DECL_ACCESSORS(shared_function_infos, FixedArray)
6628
6629 // [flags]: Holds an exciting bitfield.
6630 DECL_INT_ACCESSORS(flags)
6631
6632 // [source_url]: sourceURL from magic comment
6633 DECL_ACCESSORS(source_url, Object)
6634
6635 // [source_mapping_url]: sourceMappingURL magic comment
6636 DECL_ACCESSORS(source_mapping_url, Object)
6637
6638 // [wasm_compiled_module]: the compiled wasm module this script belongs to.
6639 // This must only be called if the type of this script is TYPE_WASM.
6640 DECL_ACCESSORS(wasm_compiled_module, Object)
6641
6642 // [compilation_type]: how the the script was compiled. Encoded in the
6643 // 'flags' field.
6644 inline CompilationType compilation_type();
6645 inline void set_compilation_type(CompilationType type);
6646
6647 // [compilation_state]: determines whether the script has already been
6648 // compiled. Encoded in the 'flags' field.
6649 inline CompilationState compilation_state();
6650 inline void set_compilation_state(CompilationState state);
6651
6652 // [origin_options]: optional attributes set by the embedder via ScriptOrigin,
6653 // and used by the embedder to make decisions about the script. V8 just passes
6654 // this through. Encoded in the 'flags' field.
6655 inline v8::ScriptOriginOptions origin_options();
6656 inline void set_origin_options(ScriptOriginOptions origin_options);
6657
6658 DECLARE_CAST(Script)
6659
6660 // If script source is an external string, check that the underlying
6661 // resource is accessible. Otherwise, always return true.
6662 inline bool HasValidSource();
6663
6664 Object* GetNameOrSourceURL();
6665
6666 // Set eval origin for stack trace formatting.
6667 static void SetEvalOrigin(Handle<Script> script,
6668 Handle<SharedFunctionInfo> outer,
6669 int eval_position);
6670 // Retrieve source position from where eval was called.
6671 int GetEvalPosition();
6672
6673 // Init line_ends array with source code positions of line ends.
6674 static void InitLineEnds(Handle<Script> script);
6675
6676 // Carries information about a source position.
6677 struct PositionInfo {
PositionInfoPositionInfo6678 PositionInfo() : line(-1), column(-1), line_start(-1), line_end(-1) {}
6679
6680 int line; // Zero-based line number.
6681 int column; // Zero-based column number.
6682 int line_start; // Position of first character in line.
6683 int line_end; // Position of final linebreak character in line.
6684 };
6685
6686 // Specifies whether to add offsets to position infos.
6687 enum OffsetFlag { NO_OFFSET = 0, WITH_OFFSET = 1 };
6688
6689 // Retrieves information about the given position, optionally with an offset.
6690 // Returns false on failure, and otherwise writes into the given info object
6691 // on success.
6692 // The static method should is preferable for handlified callsites because it
6693 // initializes the line ends array, avoiding expensive recomputations.
6694 // The non-static version is not allocating and safe for unhandlified
6695 // callsites.
6696 static bool GetPositionInfo(Handle<Script> script, int position,
6697 PositionInfo* info, OffsetFlag offset_flag);
6698 bool GetPositionInfo(int position, PositionInfo* info,
6699 OffsetFlag offset_flag) const;
6700
6701 // Wrappers for GetPositionInfo
6702 static int GetColumnNumber(Handle<Script> script, int code_offset);
6703 int GetColumnNumber(int code_pos) const;
6704 static int GetLineNumber(Handle<Script> script, int code_offset);
6705 int GetLineNumber(int code_pos) const;
6706
6707 // Get the JS object wrapping the given script; create it if none exists.
6708 static Handle<JSObject> GetWrapper(Handle<Script> script);
6709
6710 // Look through the list of existing shared function infos to find one
6711 // that matches the function literal. Return empty handle if not found.
6712 MaybeHandle<SharedFunctionInfo> FindSharedFunctionInfo(
6713 Isolate* isolate, const FunctionLiteral* fun);
6714
6715 // Iterate over all script objects on the heap.
6716 class Iterator {
6717 public:
6718 explicit Iterator(Isolate* isolate);
6719 Script* Next();
6720
6721 private:
6722 WeakFixedArray::Iterator iterator_;
6723 DISALLOW_COPY_AND_ASSIGN(Iterator);
6724 };
6725
6726 // Dispatched behavior.
6727 DECLARE_PRINTER(Script)
6728 DECLARE_VERIFIER(Script)
6729
6730 static const int kSourceOffset = HeapObject::kHeaderSize;
6731 static const int kNameOffset = kSourceOffset + kPointerSize;
6732 static const int kLineOffsetOffset = kNameOffset + kPointerSize;
6733 static const int kColumnOffsetOffset = kLineOffsetOffset + kPointerSize;
6734 static const int kContextOffset = kColumnOffsetOffset + kPointerSize;
6735 static const int kWrapperOffset = kContextOffset + kPointerSize;
6736 static const int kTypeOffset = kWrapperOffset + kPointerSize;
6737 static const int kLineEndsOffset = kTypeOffset + kPointerSize;
6738 static const int kIdOffset = kLineEndsOffset + kPointerSize;
6739 static const int kEvalFromSharedOffset = kIdOffset + kPointerSize;
6740 static const int kEvalFromPositionOffset =
6741 kEvalFromSharedOffset + kPointerSize;
6742 static const int kSharedFunctionInfosOffset =
6743 kEvalFromPositionOffset + kPointerSize;
6744 static const int kFlagsOffset = kSharedFunctionInfosOffset + kPointerSize;
6745 static const int kSourceUrlOffset = kFlagsOffset + kPointerSize;
6746 static const int kSourceMappingUrlOffset = kSourceUrlOffset + kPointerSize;
6747 static const int kSize = kSourceMappingUrlOffset + kPointerSize;
6748
6749 private:
6750 // Bit positions in the flags field.
6751 static const int kCompilationTypeBit = 0;
6752 static const int kCompilationStateBit = 1;
6753 static const int kOriginOptionsShift = 2;
6754 static const int kOriginOptionsSize = 4;
6755 static const int kOriginOptionsMask = ((1 << kOriginOptionsSize) - 1)
6756 << kOriginOptionsShift;
6757
6758 DISALLOW_IMPLICIT_CONSTRUCTORS(Script);
6759 };
6760
6761
6762 // List of builtin functions we want to identify to improve code
6763 // generation.
6764 //
6765 // Each entry has a name of a global object property holding an object
6766 // optionally followed by ".prototype", a name of a builtin function
6767 // on the object (the one the id is set for), and a label.
6768 //
6769 // Installation of ids for the selected builtin functions is handled
6770 // by the bootstrapper.
6771 #define FUNCTIONS_WITH_ID_LIST(V) \
6772 V(Array, isArray, ArrayIsArray) \
6773 V(Array.prototype, concat, ArrayConcat) \
6774 V(Array.prototype, every, ArrayEvery) \
6775 V(Array.prototype, fill, ArrayFill) \
6776 V(Array.prototype, filter, ArrayFilter) \
6777 V(Array.prototype, findIndex, ArrayFindIndex) \
6778 V(Array.prototype, forEach, ArrayForEach) \
6779 V(Array.prototype, includes, ArrayIncludes) \
6780 V(Array.prototype, indexOf, ArrayIndexOf) \
6781 V(Array.prototype, join, ArrayJoin) \
6782 V(Array.prototype, lastIndexOf, ArrayLastIndexOf) \
6783 V(Array.prototype, map, ArrayMap) \
6784 V(Array.prototype, pop, ArrayPop) \
6785 V(Array.prototype, push, ArrayPush) \
6786 V(Array.prototype, reverse, ArrayReverse) \
6787 V(Array.prototype, shift, ArrayShift) \
6788 V(Array.prototype, slice, ArraySlice) \
6789 V(Array.prototype, some, ArraySome) \
6790 V(Array.prototype, splice, ArraySplice) \
6791 V(Array.prototype, unshift, ArrayUnshift) \
6792 V(Date, now, DateNow) \
6793 V(Date.prototype, getDate, DateGetDate) \
6794 V(Date.prototype, getDay, DateGetDay) \
6795 V(Date.prototype, getFullYear, DateGetFullYear) \
6796 V(Date.prototype, getHours, DateGetHours) \
6797 V(Date.prototype, getMilliseconds, DateGetMilliseconds) \
6798 V(Date.prototype, getMinutes, DateGetMinutes) \
6799 V(Date.prototype, getMonth, DateGetMonth) \
6800 V(Date.prototype, getSeconds, DateGetSeconds) \
6801 V(Date.prototype, getTime, DateGetTime) \
6802 V(Function.prototype, apply, FunctionApply) \
6803 V(Function.prototype, call, FunctionCall) \
6804 V(Object, assign, ObjectAssign) \
6805 V(Object, create, ObjectCreate) \
6806 V(Object.prototype, hasOwnProperty, ObjectHasOwnProperty) \
6807 V(Object.prototype, toString, ObjectToString) \
6808 V(RegExp.prototype, compile, RegExpCompile) \
6809 V(RegExp.prototype, exec, RegExpExec) \
6810 V(RegExp.prototype, test, RegExpTest) \
6811 V(RegExp.prototype, toString, RegExpToString) \
6812 V(String.prototype, charCodeAt, StringCharCodeAt) \
6813 V(String.prototype, charAt, StringCharAt) \
6814 V(String.prototype, codePointAt, StringCodePointAt) \
6815 V(String.prototype, concat, StringConcat) \
6816 V(String.prototype, endsWith, StringEndsWith) \
6817 V(String.prototype, includes, StringIncludes) \
6818 V(String.prototype, indexOf, StringIndexOf) \
6819 V(String.prototype, lastIndexOf, StringLastIndexOf) \
6820 V(String.prototype, repeat, StringRepeat) \
6821 V(String.prototype, slice, StringSlice) \
6822 V(String.prototype, startsWith, StringStartsWith) \
6823 V(String.prototype, substr, StringSubstr) \
6824 V(String.prototype, substring, StringSubstring) \
6825 V(String.prototype, toLowerCase, StringToLowerCase) \
6826 V(String.prototype, toString, StringToString) \
6827 V(String.prototype, toUpperCase, StringToUpperCase) \
6828 V(String.prototype, trim, StringTrim) \
6829 V(String.prototype, trimLeft, StringTrimLeft) \
6830 V(String.prototype, trimRight, StringTrimRight) \
6831 V(String.prototype, valueOf, StringValueOf) \
6832 V(String, fromCharCode, StringFromCharCode) \
6833 V(String, fromCodePoint, StringFromCodePoint) \
6834 V(String, raw, StringRaw) \
6835 V(Math, random, MathRandom) \
6836 V(Math, floor, MathFloor) \
6837 V(Math, round, MathRound) \
6838 V(Math, ceil, MathCeil) \
6839 V(Math, abs, MathAbs) \
6840 V(Math, log, MathLog) \
6841 V(Math, log1p, MathLog1p) \
6842 V(Math, log2, MathLog2) \
6843 V(Math, log10, MathLog10) \
6844 V(Math, cbrt, MathCbrt) \
6845 V(Math, exp, MathExp) \
6846 V(Math, expm1, MathExpm1) \
6847 V(Math, sqrt, MathSqrt) \
6848 V(Math, pow, MathPow) \
6849 V(Math, max, MathMax) \
6850 V(Math, min, MathMin) \
6851 V(Math, cos, MathCos) \
6852 V(Math, cosh, MathCosh) \
6853 V(Math, sign, MathSign) \
6854 V(Math, sin, MathSin) \
6855 V(Math, sinh, MathSinh) \
6856 V(Math, tan, MathTan) \
6857 V(Math, tanh, MathTanh) \
6858 V(Math, acos, MathAcos) \
6859 V(Math, acosh, MathAcosh) \
6860 V(Math, asin, MathAsin) \
6861 V(Math, asinh, MathAsinh) \
6862 V(Math, atan, MathAtan) \
6863 V(Math, atan2, MathAtan2) \
6864 V(Math, atanh, MathAtanh) \
6865 V(Math, imul, MathImul) \
6866 V(Math, clz32, MathClz32) \
6867 V(Math, fround, MathFround) \
6868 V(Math, trunc, MathTrunc) \
6869 V(Number, isFinite, NumberIsFinite) \
6870 V(Number, isInteger, NumberIsInteger) \
6871 V(Number, isNaN, NumberIsNaN) \
6872 V(Number, isSafeInteger, NumberIsSafeInteger) \
6873 V(Number, parseFloat, NumberParseFloat) \
6874 V(Number, parseInt, NumberParseInt) \
6875 V(Number.prototype, toString, NumberToString) \
6876 V(Map.prototype, clear, MapClear) \
6877 V(Map.prototype, delete, MapDelete) \
6878 V(Map.prototype, entries, MapEntries) \
6879 V(Map.prototype, forEach, MapForEach) \
6880 V(Map.prototype, has, MapHas) \
6881 V(Map.prototype, keys, MapKeys) \
6882 V(Map.prototype, set, MapSet) \
6883 V(Map.prototype, values, MapValues) \
6884 V(Set.prototype, add, SetAdd) \
6885 V(Set.prototype, clear, SetClear) \
6886 V(Set.prototype, delete, SetDelete) \
6887 V(Set.prototype, entries, SetEntries) \
6888 V(Set.prototype, forEach, SetForEach) \
6889 V(Set.prototype, has, SetHas) \
6890 V(Set.prototype, keys, SetKeys) \
6891 V(Set.prototype, values, SetValues) \
6892 V(WeakMap.prototype, delete, WeakMapDelete) \
6893 V(WeakMap.prototype, has, WeakMapHas) \
6894 V(WeakMap.prototype, set, WeakMapSet) \
6895 V(WeakSet.prototype, add, WeakSetAdd) \
6896 V(WeakSet.prototype, delete, WeakSetDelete) \
6897 V(WeakSet.prototype, has, WeakSetHas)
6898
6899 #define ATOMIC_FUNCTIONS_WITH_ID_LIST(V) \
6900 V(Atomics, load, AtomicsLoad) \
6901 V(Atomics, store, AtomicsStore)
6902
6903 enum BuiltinFunctionId {
6904 kArrayCode,
6905 #define DECLARE_FUNCTION_ID(ignored1, ignore2, name) \
6906 k##name,
6907 FUNCTIONS_WITH_ID_LIST(DECLARE_FUNCTION_ID)
6908 ATOMIC_FUNCTIONS_WITH_ID_LIST(DECLARE_FUNCTION_ID)
6909 #undef DECLARE_FUNCTION_ID
6910 // Fake id for a special case of Math.pow. Note, it continues the
6911 // list of math functions.
6912 kMathPowHalf,
6913 // These are manually assigned to special getters during bootstrapping.
6914 kArrayBufferByteLength,
6915 kArrayEntries,
6916 kArrayKeys,
6917 kArrayValues,
6918 kArrayIteratorNext,
6919 kDataViewBuffer,
6920 kDataViewByteLength,
6921 kDataViewByteOffset,
6922 kFunctionHasInstance,
6923 kGlobalDecodeURI,
6924 kGlobalDecodeURIComponent,
6925 kGlobalEncodeURI,
6926 kGlobalEncodeURIComponent,
6927 kGlobalEscape,
6928 kGlobalUnescape,
6929 kGlobalIsFinite,
6930 kGlobalIsNaN,
6931 kTypedArrayByteLength,
6932 kTypedArrayByteOffset,
6933 kTypedArrayEntries,
6934 kTypedArrayKeys,
6935 kTypedArrayLength,
6936 kTypedArrayValues,
6937 kSharedArrayBufferByteLength,
6938 kStringIterator,
6939 kStringIteratorNext,
6940 };
6941
6942 // Result of searching in an optimized code map of a SharedFunctionInfo. Note
6943 // that both {code} and {vector} can be NULL to pass search result status.
6944 struct CodeAndVector {
6945 Code* code; // Cached optimized code.
6946 FeedbackVector* vector; // Cached feedback vector.
6947 };
6948
6949 // SharedFunctionInfo describes the JSFunction information that can be
6950 // shared by multiple instances of the function.
6951 class SharedFunctionInfo: public HeapObject {
6952 public:
6953 // [name]: Function name.
6954 DECL_ACCESSORS(name, Object)
6955
6956 // [code]: Function code.
6957 DECL_ACCESSORS(code, Code)
6958
6959 // Get the abstract code associated with the function, which will either be
6960 // a Code object or a BytecodeArray.
6961 inline AbstractCode* abstract_code();
6962
6963 // Tells whether or not this shared function info is interpreted.
6964 //
6965 // Note: function->IsInterpreted() does not necessarily return the same value
6966 // as function->shared()->IsInterpreted() because the shared function info
6967 // could tier up to baseline via a different function closure. The interpreter
6968 // entry stub will "self-heal" this divergence when the function is executed.
6969 inline bool IsInterpreted() const;
6970
6971 inline void ReplaceCode(Code* code);
6972 inline bool HasBaselineCode() const;
6973
6974 // [optimized_code_map]: Map from native context to optimized code
6975 // and a shared literals array.
6976 DECL_ACCESSORS(optimized_code_map, FixedArray)
6977
6978 // Returns entry from optimized code map for specified context and OSR entry.
6979 Code* SearchOptimizedCodeMap(Context* native_context, BailoutId osr_ast_id);
6980
6981 // Clear optimized code map.
6982 void ClearOptimizedCodeMap();
6983
6984 // Like ClearOptimizedCodeMap, but preserves literals.
6985 void ClearCodeFromOptimizedCodeMap();
6986
6987 // We have a special root FixedArray with the right shape and values
6988 // to represent the cleared optimized code map. This predicate checks
6989 // if that root is installed.
6990 inline bool OptimizedCodeMapIsCleared() const;
6991
6992 // Removes a specific optimized code object from the optimized code map.
6993 // In case of non-OSR the code reference is cleared from the cache entry but
6994 // the entry itself is left in the map in order to proceed sharing literals.
6995 void EvictFromOptimizedCodeMap(Code* optimized_code, const char* reason);
6996
6997 // Add or update entry in the optimized code map for context-dependent code.
6998 static void AddToOptimizedCodeMap(Handle<SharedFunctionInfo> shared,
6999 Handle<Context> native_context,
7000 Handle<Code> code, BailoutId osr_ast_id);
7001
7002 // Set up the link between shared function info and the script. The shared
7003 // function info is added to the list on the script.
7004 V8_EXPORT_PRIVATE static void SetScript(Handle<SharedFunctionInfo> shared,
7005 Handle<Object> script_object);
7006
7007 // Layout description of the optimized code map.
7008 static const int kEntriesStart = 0;
7009 static const int kContextOffset = 0;
7010 static const int kCachedCodeOffset = 1;
7011 static const int kEntryLength = 2;
7012 static const int kInitialLength = kEntriesStart + kEntryLength;
7013
7014 static const int kNotFound = -1;
7015
7016 // Helpers for assembly code that does a backwards walk of the optimized code
7017 // map.
7018 static const int kOffsetToPreviousContext =
7019 FixedArray::kHeaderSize + kPointerSize * (kContextOffset - kEntryLength);
7020 static const int kOffsetToPreviousCachedCode =
7021 FixedArray::kHeaderSize +
7022 kPointerSize * (kCachedCodeOffset - kEntryLength);
7023
7024 // [scope_info]: Scope info.
7025 DECL_ACCESSORS(scope_info, ScopeInfo)
7026
7027 // The outer scope info for the purpose of parsing this function, or the hole
7028 // value if it isn't yet known.
7029 DECL_ACCESSORS(outer_scope_info, HeapObject)
7030
7031 // [construct stub]: Code stub for constructing instances of this function.
7032 DECL_ACCESSORS(construct_stub, Code)
7033
7034 // Sets the given code as the construct stub, and marks builtin code objects
7035 // as a construct stub.
7036 void SetConstructStub(Code* code);
7037
7038 // Returns if this function has been compiled to native code yet.
7039 inline bool is_compiled() const;
7040
7041 // [length]: The function length - usually the number of declared parameters.
7042 // Use up to 2^30 parameters.
7043 inline int length() const;
7044 inline void set_length(int value);
7045
7046 // [internal formal parameter count]: The declared number of parameters.
7047 // For subclass constructors, also includes new.target.
7048 // The size of function's frame is internal_formal_parameter_count + 1.
7049 inline int internal_formal_parameter_count() const;
7050 inline void set_internal_formal_parameter_count(int value);
7051
7052 // Set the formal parameter count so the function code will be
7053 // called without using argument adaptor frames.
7054 inline void DontAdaptArguments();
7055
7056 // [expected_nof_properties]: Expected number of properties for the function.
7057 inline int expected_nof_properties() const;
7058 inline void set_expected_nof_properties(int value);
7059
7060 // [feedback_metadata] - describes ast node feedback from full-codegen and
7061 // (increasingly) from crankshafted code where sufficient feedback isn't
7062 // available.
7063 DECL_ACCESSORS(feedback_metadata, FeedbackMetadata)
7064
7065 // [function_literal_id] - uniquely identifies the FunctionLiteral this
7066 // SharedFunctionInfo represents within its script, or -1 if this
7067 // SharedFunctionInfo object doesn't correspond to a parsed FunctionLiteral.
7068 inline int function_literal_id() const;
7069 inline void set_function_literal_id(int value);
7070
7071 #if TRACE_MAPS
7072 // [unique_id] - For --trace-maps purposes, an identifier that's persistent
7073 // even if the GC moves this SharedFunctionInfo.
7074 inline int unique_id() const;
7075 inline void set_unique_id(int value);
7076 #endif
7077
7078 // [instance class name]: class name for instances.
7079 DECL_ACCESSORS(instance_class_name, Object)
7080
7081 // [function data]: This field holds some additional data for function.
7082 // Currently it has one of:
7083 // - a FunctionTemplateInfo to make benefit the API [IsApiFunction()].
7084 // - a BytecodeArray for the interpreter [HasBytecodeArray()].
7085 // - a FixedArray with Asm->Wasm conversion [HasAsmWasmData()].
7086 DECL_ACCESSORS(function_data, Object)
7087
7088 inline bool IsApiFunction();
7089 inline FunctionTemplateInfo* get_api_func_data();
7090 inline void set_api_func_data(FunctionTemplateInfo* data);
7091 inline bool HasBytecodeArray() const;
7092 inline BytecodeArray* bytecode_array() const;
7093 inline void set_bytecode_array(BytecodeArray* bytecode);
7094 inline void ClearBytecodeArray();
7095 inline bool HasAsmWasmData() const;
7096 inline FixedArray* asm_wasm_data() const;
7097 inline void set_asm_wasm_data(FixedArray* data);
7098 inline void ClearAsmWasmData();
7099
7100 // [function identifier]: This field holds an additional identifier for the
7101 // function.
7102 // - a Smi identifying a builtin function [HasBuiltinFunctionId()].
7103 // - a String identifying the function's inferred name [HasInferredName()].
7104 // The inferred_name is inferred from variable or property
7105 // assignment of this function. It is used to facilitate debugging and
7106 // profiling of JavaScript code written in OO style, where almost
7107 // all functions are anonymous but are assigned to object
7108 // properties.
7109 DECL_ACCESSORS(function_identifier, Object)
7110
7111 inline bool HasBuiltinFunctionId();
7112 inline BuiltinFunctionId builtin_function_id();
7113 inline void set_builtin_function_id(BuiltinFunctionId id);
7114 inline bool HasInferredName();
7115 inline String* inferred_name();
7116 inline void set_inferred_name(String* inferred_name);
7117
7118 // [script]: Script from which the function originates.
7119 DECL_ACCESSORS(script, Object)
7120
7121 // [start_position_and_type]: Field used to store both the source code
7122 // position, whether or not the function is a function expression,
7123 // and whether or not the function is a toplevel function. The two
7124 // least significants bit indicates whether the function is an
7125 // expression and the rest contains the source code position.
7126 inline int start_position_and_type() const;
7127 inline void set_start_position_and_type(int value);
7128
7129 // The function is subject to debugging if a debug info is attached.
7130 inline bool HasDebugInfo() const;
7131 inline DebugInfo* GetDebugInfo() const;
7132
7133 // A function has debug code if the compiled code has debug break slots.
7134 inline bool HasDebugCode() const;
7135
7136 // [debug info]: Debug information.
7137 DECL_ACCESSORS(debug_info, Object)
7138
7139 // Bit field containing various information collected for debugging.
7140 // This field is either stored on the kDebugInfo slot or inside the
7141 // debug info struct.
7142 inline int debugger_hints() const;
7143 inline void set_debugger_hints(int value);
7144
7145 // Indicates that the function was created by the Function function.
7146 // Though it's anonymous, toString should treat it as if it had the name
7147 // "anonymous". We don't set the name itself so that the system does not
7148 // see a binding for it.
7149 DECL_BOOLEAN_ACCESSORS(name_should_print_as_anonymous)
7150
7151 // Indicates that the function is either an anonymous expression
7152 // or an arrow function (the name field can be set through the API,
7153 // which does not change this flag).
7154 DECL_BOOLEAN_ACCESSORS(is_anonymous_expression)
7155
7156 // Indicates that the the shared function info is deserialized from cache.
7157 DECL_BOOLEAN_ACCESSORS(deserialized)
7158
7159 // Indicates that the function cannot cause side-effects.
7160 DECL_BOOLEAN_ACCESSORS(has_no_side_effect)
7161
7162 // Indicates that |has_no_side_effect| has been computed and set.
7163 DECL_BOOLEAN_ACCESSORS(computed_has_no_side_effect)
7164
7165 // Indicates that the function should be skipped during stepping.
7166 DECL_BOOLEAN_ACCESSORS(debug_is_blackboxed)
7167
7168 // Indicates that |debug_is_blackboxed| has been computed and set.
7169 DECL_BOOLEAN_ACCESSORS(computed_debug_is_blackboxed)
7170
7171 // The function's name if it is non-empty, otherwise the inferred name.
7172 String* DebugName();
7173
7174 // The function cannot cause any side effects.
7175 bool HasNoSideEffect();
7176
7177 // Used for flags such as --hydrogen-filter.
7178 bool PassesFilter(const char* raw_filter);
7179
7180 // Position of the 'function' token in the script source.
7181 inline int function_token_position() const;
7182 inline void set_function_token_position(int function_token_position);
7183
7184 // Position of this function in the script source.
7185 inline int start_position() const;
7186 inline void set_start_position(int start_position);
7187
7188 // End position of this function in the script source.
7189 inline int end_position() const;
7190 inline void set_end_position(int end_position);
7191
7192 // Is this function a named function expression in the source code.
7193 DECL_BOOLEAN_ACCESSORS(is_named_expression)
7194
7195 // Is this function a top-level function (scripts, evals).
7196 DECL_BOOLEAN_ACCESSORS(is_toplevel)
7197
7198 // Bit field containing various information collected by the compiler to
7199 // drive optimization.
7200 inline int compiler_hints() const;
7201 inline void set_compiler_hints(int value);
7202
7203 inline int ast_node_count() const;
7204 inline void set_ast_node_count(int count);
7205
7206 inline int profiler_ticks() const;
7207 inline void set_profiler_ticks(int ticks);
7208
7209 // Inline cache age is used to infer whether the function survived a context
7210 // disposal or not. In the former case we reset the opt_count.
7211 inline int ic_age();
7212 inline void set_ic_age(int age);
7213
7214 // Indicates if this function can be lazy compiled.
7215 // This is used to determine if we can safely flush code from a function
7216 // when doing GC if we expect that the function will no longer be used.
7217 DECL_BOOLEAN_ACCESSORS(allows_lazy_compilation)
7218
7219 // Indicates whether optimizations have been disabled for this
7220 // shared function info. If a function is repeatedly optimized or if
7221 // we cannot optimize the function we disable optimization to avoid
7222 // spending time attempting to optimize it again.
7223 DECL_BOOLEAN_ACCESSORS(optimization_disabled)
7224
7225 // Indicates the language mode.
7226 inline LanguageMode language_mode();
7227 inline void set_language_mode(LanguageMode language_mode);
7228
7229 // False if the function definitely does not allocate an arguments object.
7230 DECL_BOOLEAN_ACCESSORS(uses_arguments)
7231
7232 // Indicates that this function uses a super property (or an eval that may
7233 // use a super property).
7234 // This is needed to set up the [[HomeObject]] on the function instance.
7235 DECL_BOOLEAN_ACCESSORS(needs_home_object)
7236
7237 // True if the function has any duplicated parameter names.
7238 DECL_BOOLEAN_ACCESSORS(has_duplicate_parameters)
7239
7240 // Indicates whether the function is a native function.
7241 // These needs special treatment in .call and .apply since
7242 // null passed as the receiver should not be translated to the
7243 // global object.
7244 DECL_BOOLEAN_ACCESSORS(native)
7245
7246 // Indicate that this function should always be inlined in optimized code.
7247 DECL_BOOLEAN_ACCESSORS(force_inline)
7248
7249 // Indicates that code for this function must be compiled through the
7250 // Ignition / TurboFan pipeline, and is unsupported by
7251 // FullCodegen / Crankshaft.
7252 DECL_BOOLEAN_ACCESSORS(must_use_ignition_turbo)
7253
7254 // Indicates that code for this function cannot be flushed.
7255 DECL_BOOLEAN_ACCESSORS(dont_flush)
7256
7257 // Indicates that this function is an asm function.
7258 DECL_BOOLEAN_ACCESSORS(asm_function)
7259
7260 // Whether this function was created from a FunctionDeclaration.
7261 DECL_BOOLEAN_ACCESSORS(is_declaration)
7262
7263 // Whether this function was marked to be tiered up.
7264 DECL_BOOLEAN_ACCESSORS(marked_for_tier_up)
7265
7266 // Indicates that asm->wasm conversion failed and should not be re-attempted.
7267 DECL_BOOLEAN_ACCESSORS(is_asm_wasm_broken)
7268
7269 inline FunctionKind kind() const;
7270 inline void set_kind(FunctionKind kind);
7271
7272 // Indicates whether or not the code in the shared function support
7273 // deoptimization.
7274 inline bool has_deoptimization_support();
7275
7276 // Enable deoptimization support through recompiled code.
7277 void EnableDeoptimizationSupport(Code* recompiled);
7278
7279 // Disable (further) attempted optimization of all functions sharing this
7280 // shared function info.
7281 void DisableOptimization(BailoutReason reason);
7282
7283 inline BailoutReason disable_optimization_reason();
7284
7285 // Lookup the bailout ID and DCHECK that it exists in the non-optimized
7286 // code, returns whether it asserted (i.e., always true if assertions are
7287 // disabled).
7288 bool VerifyBailoutId(BailoutId id);
7289
7290 // [source code]: Source code for the function.
7291 bool HasSourceCode() const;
7292 Handle<Object> GetSourceCode();
7293 Handle<Object> GetSourceCodeHarmony();
7294
7295 // Number of times the function was optimized.
7296 inline int opt_count();
7297 inline void set_opt_count(int opt_count);
7298
7299 // Number of times the function was deoptimized.
7300 inline void set_deopt_count(int value);
7301 inline int deopt_count();
7302 inline void increment_deopt_count();
7303
7304 // Number of time we tried to re-enable optimization after it
7305 // was disabled due to high number of deoptimizations.
7306 inline void set_opt_reenable_tries(int value);
7307 inline int opt_reenable_tries();
7308
7309 inline void TryReenableOptimization();
7310
7311 // Stores deopt_count, opt_reenable_tries and ic_age as bit-fields.
7312 inline void set_counters(int value);
7313 inline int counters() const;
7314
7315 // Stores opt_count and bailout_reason as bit-fields.
7316 inline void set_opt_count_and_bailout_reason(int value);
7317 inline int opt_count_and_bailout_reason() const;
7318
7319 inline void set_disable_optimization_reason(BailoutReason reason);
7320
7321 // Tells whether this function should be subject to debugging.
7322 inline bool IsSubjectToDebugging();
7323
7324 // Whether this function is defined in user-provided JavaScript code.
7325 inline bool IsUserJavaScript();
7326
7327 // Check whether or not this function is inlineable.
7328 bool IsInlineable();
7329
7330 // Source size of this function.
7331 int SourceSize();
7332
7333 // Returns `false` if formal parameters include rest parameters, optional
7334 // parameters, or destructuring parameters.
7335 // TODO(caitp): make this a flag set during parsing
7336 inline bool has_simple_parameters();
7337
7338 // Initialize a SharedFunctionInfo from a parsed function literal.
7339 static void InitFromFunctionLiteral(Handle<SharedFunctionInfo> shared_info,
7340 FunctionLiteral* lit);
7341
7342 // Dispatched behavior.
7343 DECLARE_PRINTER(SharedFunctionInfo)
7344 DECLARE_VERIFIER(SharedFunctionInfo)
7345
7346 void ResetForNewContext(int new_ic_age);
7347
7348 // Iterate over all shared function infos in a given script.
7349 class ScriptIterator {
7350 public:
7351 explicit ScriptIterator(Handle<Script> script);
7352 ScriptIterator(Isolate* isolate, Handle<FixedArray> shared_function_infos);
7353 SharedFunctionInfo* Next();
7354
7355 // Reset the iterator to run on |script|.
7356 void Reset(Handle<Script> script);
7357
7358 private:
7359 Isolate* isolate_;
7360 Handle<FixedArray> shared_function_infos_;
7361 int index_;
7362 DISALLOW_COPY_AND_ASSIGN(ScriptIterator);
7363 };
7364
7365 // Iterate over all shared function infos on the heap.
7366 class GlobalIterator {
7367 public:
7368 explicit GlobalIterator(Isolate* isolate);
7369 SharedFunctionInfo* Next();
7370
7371 private:
7372 Script::Iterator script_iterator_;
7373 WeakFixedArray::Iterator noscript_sfi_iterator_;
7374 SharedFunctionInfo::ScriptIterator sfi_iterator_;
7375 DisallowHeapAllocation no_gc_;
7376 DISALLOW_COPY_AND_ASSIGN(GlobalIterator);
7377 };
7378
7379 DECLARE_CAST(SharedFunctionInfo)
7380
7381 // Constants.
7382 static const int kDontAdaptArgumentsSentinel = -1;
7383
7384 // Layout description.
7385 // Pointer fields.
7386 static const int kCodeOffset = HeapObject::kHeaderSize;
7387 static const int kNameOffset = kCodeOffset + kPointerSize;
7388 static const int kOptimizedCodeMapOffset = kNameOffset + kPointerSize;
7389 static const int kScopeInfoOffset = kOptimizedCodeMapOffset + kPointerSize;
7390 static const int kOuterScopeInfoOffset = kScopeInfoOffset + kPointerSize;
7391 static const int kConstructStubOffset = kOuterScopeInfoOffset + kPointerSize;
7392 static const int kInstanceClassNameOffset =
7393 kConstructStubOffset + kPointerSize;
7394 static const int kFunctionDataOffset =
7395 kInstanceClassNameOffset + kPointerSize;
7396 static const int kScriptOffset = kFunctionDataOffset + kPointerSize;
7397 static const int kDebugInfoOffset = kScriptOffset + kPointerSize;
7398 static const int kFunctionIdentifierOffset = kDebugInfoOffset + kPointerSize;
7399 static const int kFeedbackMetadataOffset =
7400 kFunctionIdentifierOffset + kPointerSize;
7401 static const int kFunctionLiteralIdOffset =
7402 kFeedbackMetadataOffset + kPointerSize;
7403 #if TRACE_MAPS
7404 static const int kUniqueIdOffset = kFunctionLiteralIdOffset + kPointerSize;
7405 static const int kLastPointerFieldOffset = kUniqueIdOffset;
7406 #else
7407 // Just to not break the postmortrem support with conditional offsets
7408 static const int kUniqueIdOffset = kFunctionLiteralIdOffset;
7409 static const int kLastPointerFieldOffset = kFunctionLiteralIdOffset;
7410 #endif
7411
7412 #if V8_HOST_ARCH_32_BIT
7413 // Smi fields.
7414 static const int kLengthOffset = kLastPointerFieldOffset + kPointerSize;
7415 static const int kFormalParameterCountOffset = kLengthOffset + kPointerSize;
7416 static const int kExpectedNofPropertiesOffset =
7417 kFormalParameterCountOffset + kPointerSize;
7418 static const int kNumLiteralsOffset =
7419 kExpectedNofPropertiesOffset + kPointerSize;
7420 static const int kStartPositionAndTypeOffset =
7421 kNumLiteralsOffset + kPointerSize;
7422 static const int kEndPositionOffset =
7423 kStartPositionAndTypeOffset + kPointerSize;
7424 static const int kFunctionTokenPositionOffset =
7425 kEndPositionOffset + kPointerSize;
7426 static const int kCompilerHintsOffset =
7427 kFunctionTokenPositionOffset + kPointerSize;
7428 static const int kOptCountAndBailoutReasonOffset =
7429 kCompilerHintsOffset + kPointerSize;
7430 static const int kCountersOffset =
7431 kOptCountAndBailoutReasonOffset + kPointerSize;
7432 static const int kAstNodeCountOffset =
7433 kCountersOffset + kPointerSize;
7434 static const int kProfilerTicksOffset =
7435 kAstNodeCountOffset + kPointerSize;
7436
7437 // Total size.
7438 static const int kSize = kProfilerTicksOffset + kPointerSize;
7439 #else
7440 // The only reason to use smi fields instead of int fields is to allow
7441 // iteration without maps decoding during garbage collections.
7442 // To avoid wasting space on 64-bit architectures we use the following trick:
7443 // we group integer fields into pairs
7444 // The least significant integer in each pair is shifted left by 1. By doing
7445 // this we guarantee that LSB of each kPointerSize aligned word is not set and
7446 // thus this word cannot be treated as pointer to HeapObject during old space
7447 // traversal.
7448 #if V8_TARGET_LITTLE_ENDIAN
7449 static const int kLengthOffset = kLastPointerFieldOffset + kPointerSize;
7450 static const int kFormalParameterCountOffset =
7451 kLengthOffset + kIntSize;
7452
7453 static const int kExpectedNofPropertiesOffset =
7454 kFormalParameterCountOffset + kIntSize;
7455 static const int kNumLiteralsOffset =
7456 kExpectedNofPropertiesOffset + kIntSize;
7457
7458 static const int kEndPositionOffset =
7459 kNumLiteralsOffset + kIntSize;
7460 static const int kStartPositionAndTypeOffset =
7461 kEndPositionOffset + kIntSize;
7462
7463 static const int kFunctionTokenPositionOffset =
7464 kStartPositionAndTypeOffset + kIntSize;
7465 static const int kCompilerHintsOffset =
7466 kFunctionTokenPositionOffset + kIntSize;
7467
7468 static const int kOptCountAndBailoutReasonOffset =
7469 kCompilerHintsOffset + kIntSize;
7470 static const int kCountersOffset =
7471 kOptCountAndBailoutReasonOffset + kIntSize;
7472
7473 static const int kAstNodeCountOffset =
7474 kCountersOffset + kIntSize;
7475 static const int kProfilerTicksOffset =
7476 kAstNodeCountOffset + kIntSize;
7477
7478 // Total size.
7479 static const int kSize = kProfilerTicksOffset + kIntSize;
7480
7481 #elif V8_TARGET_BIG_ENDIAN
7482 static const int kFormalParameterCountOffset =
7483 kLastPointerFieldOffset + kPointerSize;
7484 static const int kLengthOffset = kFormalParameterCountOffset + kIntSize;
7485
7486 static const int kNumLiteralsOffset = kLengthOffset + kIntSize;
7487 static const int kExpectedNofPropertiesOffset = kNumLiteralsOffset + kIntSize;
7488
7489 static const int kStartPositionAndTypeOffset =
7490 kExpectedNofPropertiesOffset + kIntSize;
7491 static const int kEndPositionOffset = kStartPositionAndTypeOffset + kIntSize;
7492
7493 static const int kCompilerHintsOffset = kEndPositionOffset + kIntSize;
7494 static const int kFunctionTokenPositionOffset =
7495 kCompilerHintsOffset + kIntSize;
7496
7497 static const int kCountersOffset = kFunctionTokenPositionOffset + kIntSize;
7498 static const int kOptCountAndBailoutReasonOffset = kCountersOffset + kIntSize;
7499
7500 static const int kProfilerTicksOffset =
7501 kOptCountAndBailoutReasonOffset + kIntSize;
7502 static const int kAstNodeCountOffset = kProfilerTicksOffset + kIntSize;
7503
7504 // Total size.
7505 static const int kSize = kAstNodeCountOffset + kIntSize;
7506
7507 #else
7508 #error Unknown byte ordering
7509 #endif // Big endian
7510 #endif // 64-bit
7511
7512
7513 static const int kAlignedSize = POINTER_SIZE_ALIGN(kSize);
7514
7515 typedef FixedBodyDescriptor<kCodeOffset,
7516 kLastPointerFieldOffset + kPointerSize, kSize>
7517 BodyDescriptor;
7518 typedef FixedBodyDescriptor<kNameOffset,
7519 kLastPointerFieldOffset + kPointerSize, kSize>
7520 BodyDescriptorWeakCode;
7521
7522 // Bit positions in start_position_and_type.
7523 // The source code start position is in the 30 most significant bits of
7524 // the start_position_and_type field.
7525 static const int kIsNamedExpressionBit = 0;
7526 static const int kIsTopLevelBit = 1;
7527 static const int kStartPositionShift = 2;
7528 static const int kStartPositionMask = ~((1 << kStartPositionShift) - 1);
7529
7530 // Bit positions in compiler_hints.
7531 enum CompilerHints {
7532 // byte 0
7533 kAllowLazyCompilation,
7534 kMarkedForTierUp,
7535 kOptimizationDisabled,
7536 kHasDuplicateParameters,
7537 kNative,
7538 kStrictModeFunction,
7539 kUsesArguments,
7540 kNeedsHomeObject,
7541 // byte 1
7542 kForceInline,
7543 kIsAsmFunction,
7544 kMustUseIgnitionTurbo,
7545 kDontFlush,
7546 kIsDeclaration,
7547 kIsAsmWasmBroken,
7548
7549 kUnused1, // Unused fields.
7550 kUnused2,
7551
7552 // byte 2
7553 kFunctionKind,
7554 // rest of byte 2 and first two bits of byte 3 are used by FunctionKind
7555 // byte 3
7556 kCompilerHintsCount = kFunctionKind + 10, // Pseudo entry
7557 };
7558
7559 // Bit positions in debugger_hints.
7560 enum DebuggerHints {
7561 kIsAnonymousExpression,
7562 kNameShouldPrintAsAnonymous,
7563 kDeserialized,
7564 kHasNoSideEffect,
7565 kComputedHasNoSideEffect,
7566 kDebugIsBlackboxed,
7567 kComputedDebugIsBlackboxed,
7568 };
7569
7570 // kFunctionKind has to be byte-aligned
7571 STATIC_ASSERT((kFunctionKind % kBitsPerByte) == 0);
7572
7573 class FunctionKindBits : public BitField<FunctionKind, kFunctionKind, 10> {};
7574
7575 class DeoptCountBits : public BitField<int, 0, 4> {};
7576 class OptReenableTriesBits : public BitField<int, 4, 18> {};
7577 class ICAgeBits : public BitField<int, 22, 8> {};
7578
7579 class OptCountBits : public BitField<int, 0, 22> {};
7580 class DisabledOptimizationReasonBits : public BitField<int, 22, 8> {};
7581
7582 private:
7583 #if V8_HOST_ARCH_32_BIT
7584 // On 32 bit platforms, compiler hints is a smi.
7585 static const int kCompilerHintsSmiTagSize = kSmiTagSize;
7586 static const int kCompilerHintsSize = kPointerSize;
7587 #else
7588 // On 64 bit platforms, compiler hints is not a smi, see comment above.
7589 static const int kCompilerHintsSmiTagSize = 0;
7590 static const int kCompilerHintsSize = kIntSize;
7591 #endif
7592
7593 STATIC_ASSERT(SharedFunctionInfo::kCompilerHintsCount +
7594 SharedFunctionInfo::kCompilerHintsSmiTagSize <=
7595 SharedFunctionInfo::kCompilerHintsSize * kBitsPerByte);
7596
7597 public:
7598 // Constants for optimizing codegen for strict mode function and
7599 // native tests when using integer-width instructions.
7600 static const int kStrictModeBit =
7601 kStrictModeFunction + kCompilerHintsSmiTagSize;
7602 static const int kNativeBit = kNative + kCompilerHintsSmiTagSize;
7603 static const int kHasDuplicateParametersBit =
7604 kHasDuplicateParameters + kCompilerHintsSmiTagSize;
7605
7606 static const int kFunctionKindShift =
7607 kFunctionKind + kCompilerHintsSmiTagSize;
7608 static const int kAllFunctionKindBitsMask = FunctionKindBits::kMask
7609 << kCompilerHintsSmiTagSize;
7610
7611 static const int kMarkedForTierUpBit =
7612 kMarkedForTierUp + kCompilerHintsSmiTagSize;
7613
7614 // Constants for optimizing codegen for strict mode function and
7615 // native tests.
7616 // Allows to use byte-width instructions.
7617 static const int kStrictModeBitWithinByte = kStrictModeBit % kBitsPerByte;
7618 static const int kNativeBitWithinByte = kNativeBit % kBitsPerByte;
7619 static const int kHasDuplicateParametersBitWithinByte =
7620 kHasDuplicateParametersBit % kBitsPerByte;
7621
7622 static const int kClassConstructorBitsWithinByte =
7623 FunctionKind::kClassConstructor << kCompilerHintsSmiTagSize;
7624 STATIC_ASSERT(kClassConstructorBitsWithinByte < (1 << kBitsPerByte));
7625
7626 static const int kMarkedForTierUpBitWithinByte =
7627 kMarkedForTierUpBit % kBitsPerByte;
7628
7629 #if defined(V8_TARGET_LITTLE_ENDIAN)
7630 #define BYTE_OFFSET(compiler_hint) \
7631 kCompilerHintsOffset + \
7632 (compiler_hint + kCompilerHintsSmiTagSize) / kBitsPerByte
7633 #elif defined(V8_TARGET_BIG_ENDIAN)
7634 #define BYTE_OFFSET(compiler_hint) \
7635 kCompilerHintsOffset + (kCompilerHintsSize - 1) - \
7636 ((compiler_hint + kCompilerHintsSmiTagSize) / kBitsPerByte)
7637 #else
7638 #error Unknown byte ordering
7639 #endif
7640 static const int kStrictModeByteOffset = BYTE_OFFSET(kStrictModeFunction);
7641 static const int kNativeByteOffset = BYTE_OFFSET(kNative);
7642 static const int kFunctionKindByteOffset = BYTE_OFFSET(kFunctionKind);
7643 static const int kHasDuplicateParametersByteOffset =
7644 BYTE_OFFSET(kHasDuplicateParameters);
7645 static const int kMarkedForTierUpByteOffset = BYTE_OFFSET(kMarkedForTierUp);
7646 #undef BYTE_OFFSET
7647
7648 private:
7649 // Returns entry from optimized code map for specified context.
7650 // The result is either kNotFound, or a start index of the context-dependent
7651 // entry.
7652 int SearchOptimizedCodeMapEntry(Context* native_context);
7653
7654 DISALLOW_IMPLICIT_CONSTRUCTORS(SharedFunctionInfo);
7655 };
7656
7657
7658 // Printing support.
7659 struct SourceCodeOf {
7660 explicit SourceCodeOf(SharedFunctionInfo* v, int max = -1)
valueSourceCodeOf7661 : value(v), max_length(max) {}
7662 const SharedFunctionInfo* value;
7663 int max_length;
7664 };
7665
7666
7667 std::ostream& operator<<(std::ostream& os, const SourceCodeOf& v);
7668
7669
7670 class JSGeneratorObject: public JSObject {
7671 public:
7672 // [function]: The function corresponding to this generator object.
7673 DECL_ACCESSORS(function, JSFunction)
7674
7675 // [context]: The context of the suspended computation.
7676 DECL_ACCESSORS(context, Context)
7677
7678 // [receiver]: The receiver of the suspended computation.
7679 DECL_ACCESSORS(receiver, Object)
7680
7681 // [input_or_debug_pos]
7682 // For executing generators: the most recent input value.
7683 // For suspended generators: debug information (bytecode offset).
7684 // There is currently no need to remember the most recent input value for a
7685 // suspended generator.
7686 DECL_ACCESSORS(input_or_debug_pos, Object)
7687
7688 // [resume_mode]: The most recent resume mode.
7689 enum ResumeMode { kNext, kReturn, kThrow };
7690 DECL_INT_ACCESSORS(resume_mode)
7691
7692 // [continuation]
7693 //
7694 // A positive value indicates a suspended generator. The special
7695 // kGeneratorExecuting and kGeneratorClosed values indicate that a generator
7696 // cannot be resumed.
7697 inline int continuation() const;
7698 inline void set_continuation(int continuation);
7699 inline bool is_closed() const;
7700 inline bool is_executing() const;
7701 inline bool is_suspended() const;
7702
7703 // For suspended generators: the source position at which the generator
7704 // is suspended.
7705 int source_position() const;
7706
7707 // [register_file]: Saved interpreter register file.
7708 DECL_ACCESSORS(register_file, FixedArray)
7709
7710 DECLARE_CAST(JSGeneratorObject)
7711
7712 // Dispatched behavior.
7713 DECLARE_VERIFIER(JSGeneratorObject)
7714
7715 // Magic sentinel values for the continuation.
7716 static const int kGeneratorExecuting = -2;
7717 static const int kGeneratorClosed = -1;
7718
7719 // Layout description.
7720 static const int kFunctionOffset = JSObject::kHeaderSize;
7721 static const int kContextOffset = kFunctionOffset + kPointerSize;
7722 static const int kReceiverOffset = kContextOffset + kPointerSize;
7723 static const int kInputOrDebugPosOffset = kReceiverOffset + kPointerSize;
7724 static const int kResumeModeOffset = kInputOrDebugPosOffset + kPointerSize;
7725 static const int kContinuationOffset = kResumeModeOffset + kPointerSize;
7726 static const int kRegisterFileOffset = kContinuationOffset + kPointerSize;
7727 static const int kSize = kRegisterFileOffset + kPointerSize;
7728
7729 private:
7730 DISALLOW_IMPLICIT_CONSTRUCTORS(JSGeneratorObject);
7731 };
7732
7733 // When importing a module namespace (import * as foo from "bar"), a
7734 // JSModuleNamespace object (representing module "bar") is created and bound to
7735 // the declared variable (foo). A module can have at most one namespace object.
7736 class JSModuleNamespace : public JSObject {
7737 public:
7738 DECLARE_CAST(JSModuleNamespace)
7739 DECLARE_PRINTER(JSModuleNamespace)
7740 DECLARE_VERIFIER(JSModuleNamespace)
7741
7742 // The actual module whose namespace is being represented.
7743 DECL_ACCESSORS(module, Module)
7744
7745 // Retrieve the value exported by [module] under the given [name]. If there is
7746 // no such export, return Just(undefined). If the export is uninitialized,
7747 // schedule an exception and return Nothing.
7748 MUST_USE_RESULT MaybeHandle<Object> GetExport(Handle<String> name);
7749
7750 // In-object fields.
7751 enum {
7752 kToStringTagFieldIndex,
7753 kInObjectFieldCount,
7754 };
7755
7756 static const int kModuleOffset = JSObject::kHeaderSize;
7757 static const int kHeaderSize = kModuleOffset + kPointerSize;
7758
7759 static const int kSize = kHeaderSize + kPointerSize * kInObjectFieldCount;
7760
7761 private:
7762 DISALLOW_IMPLICIT_CONSTRUCTORS(JSModuleNamespace);
7763 };
7764
7765 // A Module object is a mapping from export names to cells
7766 // This is still very much in flux.
7767 class Module : public Struct {
7768 public:
7769 DECLARE_CAST(Module)
7770 DECLARE_VERIFIER(Module)
7771 DECLARE_PRINTER(Module)
7772
7773 // The code representing this Module, or an abstraction thereof.
7774 // This is either a SharedFunctionInfo or a JSFunction or a ModuleInfo
7775 // depending on whether the module has been instantiated and evaluated. See
7776 // Module::ModuleVerify() for the precise invariant.
7777 DECL_ACCESSORS(code, Object)
7778
7779 // Arrays of cells corresponding to regular exports and regular imports.
7780 // A cell's position in the array is determined by the cell index of the
7781 // associated module entry (which coincides with the variable index of the
7782 // associated variable).
7783 DECL_ACCESSORS(regular_exports, FixedArray)
7784 DECL_ACCESSORS(regular_imports, FixedArray)
7785
7786 // The complete export table, mapping an export name to its cell.
7787 // TODO(neis): We may want to remove the regular exports from the table.
7788 DECL_ACCESSORS(exports, ObjectHashTable)
7789
7790 // Hash for this object (a random non-zero Smi).
7791 DECL_INT_ACCESSORS(hash)
7792
7793 // The namespace object (or undefined).
7794 DECL_ACCESSORS(module_namespace, HeapObject)
7795
7796 // Modules imported or re-exported by this module.
7797 // Corresponds 1-to-1 to the module specifier strings in
7798 // ModuleInfo::module_requests.
7799 DECL_ACCESSORS(requested_modules, FixedArray)
7800
7801 // Get the ModuleInfo associated with the code.
7802 inline ModuleInfo* info() const;
7803
7804 inline bool instantiated() const;
7805 inline bool evaluated() const;
7806 inline void set_evaluated();
7807
7808 // Implementation of spec operation ModuleDeclarationInstantiation.
7809 // Returns false if an exception occurred during instantiation, true
7810 // otherwise.
7811 static MUST_USE_RESULT bool Instantiate(Handle<Module> module,
7812 v8::Local<v8::Context> context,
7813 v8::Module::ResolveCallback callback);
7814
7815 // Implementation of spec operation ModuleEvaluation.
7816 static MUST_USE_RESULT MaybeHandle<Object> Evaluate(Handle<Module> module);
7817
7818 static Handle<Object> LoadVariable(Handle<Module> module, int cell_index);
7819 static void StoreVariable(Handle<Module> module, int cell_index,
7820 Handle<Object> value);
7821
7822 // Get the namespace object for [module_request] of [module]. If it doesn't
7823 // exist yet, it is created.
7824 static Handle<JSModuleNamespace> GetModuleNamespace(Handle<Module> module,
7825 int module_request);
7826
7827 static const int kCodeOffset = HeapObject::kHeaderSize;
7828 static const int kExportsOffset = kCodeOffset + kPointerSize;
7829 static const int kRegularExportsOffset = kExportsOffset + kPointerSize;
7830 static const int kRegularImportsOffset = kRegularExportsOffset + kPointerSize;
7831 static const int kHashOffset = kRegularImportsOffset + kPointerSize;
7832 static const int kModuleNamespaceOffset = kHashOffset + kPointerSize;
7833 static const int kRequestedModulesOffset =
7834 kModuleNamespaceOffset + kPointerSize;
7835 static const int kSize = kRequestedModulesOffset + kPointerSize;
7836
7837 private:
7838 static void CreateExport(Handle<Module> module, int cell_index,
7839 Handle<FixedArray> names);
7840 static void CreateIndirectExport(Handle<Module> module, Handle<String> name,
7841 Handle<ModuleInfoEntry> entry);
7842
7843 // Get the namespace object for [module]. If it doesn't exist yet, it is
7844 // created.
7845 static Handle<JSModuleNamespace> GetModuleNamespace(Handle<Module> module);
7846
7847 // The [must_resolve] argument indicates whether or not an exception should be
7848 // thrown in case the module does not provide an export named [name]
7849 // (including when a cycle is detected). An exception is always thrown in the
7850 // case of conflicting star exports.
7851 //
7852 // If [must_resolve] is true, a null result indicates an exception. If
7853 // [must_resolve] is false, a null result may or may not indicate an
7854 // exception (so check manually!).
7855 class ResolveSet;
7856 static MUST_USE_RESULT MaybeHandle<Cell> ResolveExport(
7857 Handle<Module> module, Handle<String> name, MessageLocation loc,
7858 bool must_resolve, ResolveSet* resolve_set);
7859 static MUST_USE_RESULT MaybeHandle<Cell> ResolveImport(
7860 Handle<Module> module, Handle<String> name, int module_request,
7861 MessageLocation loc, bool must_resolve, ResolveSet* resolve_set);
7862
7863 // Helper for ResolveExport.
7864 static MUST_USE_RESULT MaybeHandle<Cell> ResolveExportUsingStarExports(
7865 Handle<Module> module, Handle<String> name, MessageLocation loc,
7866 bool must_resolve, ResolveSet* resolve_set);
7867
7868 DISALLOW_IMPLICIT_CONSTRUCTORS(Module);
7869 };
7870
7871 // JSBoundFunction describes a bound function exotic object.
7872 class JSBoundFunction : public JSObject {
7873 public:
7874 // [bound_target_function]: The wrapped function object.
7875 DECL_ACCESSORS(bound_target_function, JSReceiver)
7876
7877 // [bound_this]: The value that is always passed as the this value when
7878 // calling the wrapped function.
7879 DECL_ACCESSORS(bound_this, Object)
7880
7881 // [bound_arguments]: A list of values whose elements are used as the first
7882 // arguments to any call to the wrapped function.
7883 DECL_ACCESSORS(bound_arguments, FixedArray)
7884
7885 static MaybeHandle<String> GetName(Isolate* isolate,
7886 Handle<JSBoundFunction> function);
7887 static MaybeHandle<Context> GetFunctionRealm(
7888 Handle<JSBoundFunction> function);
7889
7890 DECLARE_CAST(JSBoundFunction)
7891
7892 // Dispatched behavior.
7893 DECLARE_PRINTER(JSBoundFunction)
7894 DECLARE_VERIFIER(JSBoundFunction)
7895
7896 // The bound function's string representation implemented according
7897 // to ES6 section 19.2.3.5 Function.prototype.toString ( ).
7898 static Handle<String> ToString(Handle<JSBoundFunction> function);
7899
7900 // Layout description.
7901 static const int kBoundTargetFunctionOffset = JSObject::kHeaderSize;
7902 static const int kBoundThisOffset = kBoundTargetFunctionOffset + kPointerSize;
7903 static const int kBoundArgumentsOffset = kBoundThisOffset + kPointerSize;
7904 static const int kSize = kBoundArgumentsOffset + kPointerSize;
7905
7906 private:
7907 DISALLOW_IMPLICIT_CONSTRUCTORS(JSBoundFunction);
7908 };
7909
7910
7911 // JSFunction describes JavaScript functions.
7912 class JSFunction: public JSObject {
7913 public:
7914 // [prototype_or_initial_map]:
7915 DECL_ACCESSORS(prototype_or_initial_map, Object)
7916
7917 // [shared]: The information about the function that
7918 // can be shared by instances.
7919 DECL_ACCESSORS(shared, SharedFunctionInfo)
7920
7921 static const int kLengthDescriptorIndex = 0;
7922 static const int kNameDescriptorIndex = 1;
7923
7924 // [context]: The context for this function.
7925 inline Context* context();
7926 inline bool has_context() const;
7927 inline void set_context(Object* context);
7928 inline JSObject* global_proxy();
7929 inline Context* native_context();
7930
7931 static Handle<Object> GetName(Isolate* isolate, Handle<JSFunction> function);
7932 static MaybeHandle<Smi> GetLength(Isolate* isolate,
7933 Handle<JSFunction> function);
7934 static Handle<Context> GetFunctionRealm(Handle<JSFunction> function);
7935
7936 // [code]: The generated code object for this function. Executed
7937 // when the function is invoked, e.g. foo() or new foo(). See
7938 // [[Call]] and [[Construct]] description in ECMA-262, section
7939 // 8.6.2, page 27.
7940 inline Code* code();
7941 inline void set_code(Code* code);
7942 inline void set_code_no_write_barrier(Code* code);
7943 inline void ReplaceCode(Code* code);
7944
7945 // Get the abstract code associated with the function, which will either be
7946 // a Code object or a BytecodeArray.
7947 inline AbstractCode* abstract_code();
7948
7949 // Tells whether this function inlines the given shared function info.
7950 bool Inlines(SharedFunctionInfo* candidate);
7951
7952 // Tells whether or not this function is interpreted.
7953 //
7954 // Note: function->IsInterpreted() does not necessarily return the same value
7955 // as function->shared()->IsInterpreted() because the shared function info
7956 // could tier up to baseline via a different function closure. The interpreter
7957 // entry stub will "self-heal" this divergence when the function is executed.
7958 inline bool IsInterpreted();
7959
7960 // Tells whether or not this function has been optimized.
7961 inline bool IsOptimized();
7962
7963 // Mark this function for lazy recompilation. The function will be recompiled
7964 // the next time it is executed.
7965 void MarkForBaseline();
7966 void MarkForOptimization();
7967 void AttemptConcurrentOptimization();
7968
7969 // Tells whether or not the function is already marked for lazy recompilation.
7970 inline bool IsMarkedForBaseline();
7971 inline bool IsMarkedForOptimization();
7972 inline bool IsMarkedForConcurrentOptimization();
7973
7974 // Tells whether or not the function is on the concurrent recompilation queue.
7975 inline bool IsInOptimizationQueue();
7976
7977 // Completes inobject slack tracking on initial map if it is active.
7978 inline void CompleteInobjectSlackTrackingIfActive();
7979
7980 // [feedback_vector_cell]: Fixed array holding the feedback vector.
7981 DECL_ACCESSORS(feedback_vector_cell, Cell)
7982
7983 enum FeedbackVectorState {
7984 TOP_LEVEL_SCRIPT_NEEDS_VECTOR,
7985 NEEDS_VECTOR,
7986 HAS_VECTOR
7987 };
7988
7989 inline FeedbackVectorState GetFeedbackVectorState(Isolate* isolate) const;
7990
7991 // feedback_vector() can be used once the function is compiled.
7992 inline FeedbackVector* feedback_vector() const;
7993 inline bool has_feedback_vector() const;
7994 static void EnsureLiterals(Handle<JSFunction> function);
7995
7996 // Unconditionally clear the type feedback vector.
7997 void ClearTypeFeedbackInfo();
7998
7999 // The initial map for an object created by this constructor.
8000 inline Map* initial_map();
8001 static void SetInitialMap(Handle<JSFunction> function, Handle<Map> map,
8002 Handle<Object> prototype);
8003 inline bool has_initial_map();
8004 static void EnsureHasInitialMap(Handle<JSFunction> function);
8005
8006 // Creates a map that matches the constructor's initial map, but with
8007 // [[prototype]] being new.target.prototype. Because new.target can be a
8008 // JSProxy, this can call back into JavaScript.
8009 static MUST_USE_RESULT MaybeHandle<Map> GetDerivedMap(
8010 Isolate* isolate, Handle<JSFunction> constructor,
8011 Handle<JSReceiver> new_target);
8012
8013 // Get and set the prototype property on a JSFunction. If the
8014 // function has an initial map the prototype is set on the initial
8015 // map. Otherwise, the prototype is put in the initial map field
8016 // until an initial map is needed.
8017 inline bool has_prototype();
8018 inline bool has_instance_prototype();
8019 inline Object* prototype();
8020 inline Object* instance_prototype();
8021 static void SetPrototype(Handle<JSFunction> function,
8022 Handle<Object> value);
8023 static void SetInstancePrototype(Handle<JSFunction> function,
8024 Handle<Object> value);
8025
8026 // After prototype is removed, it will not be created when accessed, and
8027 // [[Construct]] from this function will not be allowed.
8028 bool RemovePrototype();
8029
8030 // Returns if this function has been compiled to native code yet.
8031 inline bool is_compiled();
8032
8033 // [next_function_link]: Links functions into various lists, e.g. the list
8034 // of optimized functions hanging off the native_context. The CodeFlusher
8035 // uses this link to chain together flushing candidates. Treated weakly
8036 // by the garbage collector.
8037 DECL_ACCESSORS(next_function_link, Object)
8038
8039 // Prints the name of the function using PrintF.
8040 void PrintName(FILE* out = stdout);
8041
8042 DECLARE_CAST(JSFunction)
8043
8044 // Calculate the instance size and in-object properties count.
8045 void CalculateInstanceSize(InstanceType instance_type,
8046 int requested_internal_fields, int* instance_size,
8047 int* in_object_properties);
8048 void CalculateInstanceSizeForDerivedClass(InstanceType instance_type,
8049 int requested_internal_fields,
8050 int* instance_size,
8051 int* in_object_properties);
8052 static void CalculateInstanceSizeHelper(InstanceType instance_type,
8053 int requested_internal_fields,
8054 int requested_in_object_properties,
8055 int* instance_size,
8056 int* in_object_properties);
8057 // Visiting policy flags define whether the code entry or next function
8058 // should be visited or not.
8059 enum BodyVisitingPolicy {
8060 kVisitCodeEntry = 1 << 0,
8061 kVisitNextFunction = 1 << 1,
8062
8063 kSkipCodeEntryAndNextFunction = 0,
8064 kVisitCodeEntryAndNextFunction = kVisitCodeEntry | kVisitNextFunction
8065 };
8066 // Iterates the function object according to the visiting policy.
8067 template <BodyVisitingPolicy>
8068 class BodyDescriptorImpl;
8069
8070 // Visit the whole object.
8071 typedef BodyDescriptorImpl<kVisitCodeEntryAndNextFunction> BodyDescriptor;
8072
8073 // Don't visit next function.
8074 typedef BodyDescriptorImpl<kVisitCodeEntry> BodyDescriptorStrongCode;
8075 typedef BodyDescriptorImpl<kSkipCodeEntryAndNextFunction>
8076 BodyDescriptorWeakCode;
8077
8078 // Dispatched behavior.
8079 DECLARE_PRINTER(JSFunction)
8080 DECLARE_VERIFIER(JSFunction)
8081
8082 // The function's name if it is configured, otherwise shared function info
8083 // debug name.
8084 static Handle<String> GetName(Handle<JSFunction> function);
8085
8086 // ES6 section 9.2.11 SetFunctionName
8087 // Because of the way this abstract operation is used in the spec,
8088 // it should never fail.
8089 static void SetName(Handle<JSFunction> function, Handle<Name> name,
8090 Handle<String> prefix);
8091
8092 // The function's displayName if it is set, otherwise name if it is
8093 // configured, otherwise shared function info
8094 // debug name.
8095 static Handle<String> GetDebugName(Handle<JSFunction> function);
8096
8097 // The function's string representation implemented according to
8098 // ES6 section 19.2.3.5 Function.prototype.toString ( ).
8099 static Handle<String> ToString(Handle<JSFunction> function);
8100
8101 // Layout descriptors. The last property (from kNonWeakFieldsEndOffset to
8102 // kSize) is weak and has special handling during garbage collection.
8103 static const int kPrototypeOrInitialMapOffset = JSObject::kHeaderSize;
8104 static const int kSharedFunctionInfoOffset =
8105 kPrototypeOrInitialMapOffset + kPointerSize;
8106 static const int kContextOffset = kSharedFunctionInfoOffset + kPointerSize;
8107 static const int kFeedbackVectorOffset = kContextOffset + kPointerSize;
8108 static const int kNonWeakFieldsEndOffset =
8109 kFeedbackVectorOffset + kPointerSize;
8110 static const int kCodeEntryOffset = kNonWeakFieldsEndOffset;
8111 static const int kNextFunctionLinkOffset = kCodeEntryOffset + kPointerSize;
8112 static const int kSize = kNextFunctionLinkOffset + kPointerSize;
8113
8114 private:
8115 DISALLOW_IMPLICIT_CONSTRUCTORS(JSFunction);
8116 };
8117
8118
8119 // JSGlobalProxy's prototype must be a JSGlobalObject or null,
8120 // and the prototype is hidden. JSGlobalProxy always delegates
8121 // property accesses to its prototype if the prototype is not null.
8122 //
8123 // A JSGlobalProxy can be reinitialized which will preserve its identity.
8124 //
8125 // Accessing a JSGlobalProxy requires security check.
8126
8127 class JSGlobalProxy : public JSObject {
8128 public:
8129 // [native_context]: the owner native context of this global proxy object.
8130 // It is null value if this object is not used by any context.
8131 DECL_ACCESSORS(native_context, Object)
8132
8133 // [hash]: The hash code property (undefined if not initialized yet).
8134 DECL_ACCESSORS(hash, Object)
8135
8136 DECLARE_CAST(JSGlobalProxy)
8137
8138 inline bool IsDetachedFrom(JSGlobalObject* global) const;
8139
8140 static int SizeWithInternalFields(int internal_field_count);
8141
8142 // Dispatched behavior.
8143 DECLARE_PRINTER(JSGlobalProxy)
8144 DECLARE_VERIFIER(JSGlobalProxy)
8145
8146 // Layout description.
8147 static const int kNativeContextOffset = JSObject::kHeaderSize;
8148 static const int kHashOffset = kNativeContextOffset + kPointerSize;
8149 static const int kSize = kHashOffset + kPointerSize;
8150
8151 private:
8152 DISALLOW_IMPLICIT_CONSTRUCTORS(JSGlobalProxy);
8153 };
8154
8155
8156 // JavaScript global object.
8157 class JSGlobalObject : public JSObject {
8158 public:
8159 // [native context]: the natives corresponding to this global object.
8160 DECL_ACCESSORS(native_context, Context)
8161
8162 // [global proxy]: the global proxy object of the context
8163 DECL_ACCESSORS(global_proxy, JSObject)
8164
8165
8166 static void InvalidatePropertyCell(Handle<JSGlobalObject> object,
8167 Handle<Name> name);
8168 // Ensure that the global object has a cell for the given property name.
8169 static Handle<PropertyCell> EnsureEmptyPropertyCell(
8170 Handle<JSGlobalObject> global, Handle<Name> name,
8171 PropertyCellType cell_type, int* entry_out = nullptr);
8172
8173 DECLARE_CAST(JSGlobalObject)
8174
8175 inline bool IsDetached();
8176
8177 // Dispatched behavior.
8178 DECLARE_PRINTER(JSGlobalObject)
8179 DECLARE_VERIFIER(JSGlobalObject)
8180
8181 // Layout description.
8182 static const int kNativeContextOffset = JSObject::kHeaderSize;
8183 static const int kGlobalProxyOffset = kNativeContextOffset + kPointerSize;
8184 static const int kHeaderSize = kGlobalProxyOffset + kPointerSize;
8185 static const int kSize = kHeaderSize;
8186
8187 private:
8188 DISALLOW_IMPLICIT_CONSTRUCTORS(JSGlobalObject);
8189 };
8190
8191
8192 // Representation for JS Wrapper objects, String, Number, Boolean, etc.
8193 class JSValue: public JSObject {
8194 public:
8195 // [value]: the object being wrapped.
8196 DECL_ACCESSORS(value, Object)
8197
8198 DECLARE_CAST(JSValue)
8199
8200 // Dispatched behavior.
8201 DECLARE_PRINTER(JSValue)
8202 DECLARE_VERIFIER(JSValue)
8203
8204 // Layout description.
8205 static const int kValueOffset = JSObject::kHeaderSize;
8206 static const int kSize = kValueOffset + kPointerSize;
8207
8208 private:
8209 DISALLOW_IMPLICIT_CONSTRUCTORS(JSValue);
8210 };
8211
8212
8213 class DateCache;
8214
8215 // Representation for JS date objects.
8216 class JSDate: public JSObject {
8217 public:
8218 static MUST_USE_RESULT MaybeHandle<JSDate> New(Handle<JSFunction> constructor,
8219 Handle<JSReceiver> new_target,
8220 double tv);
8221
8222 // If one component is NaN, all of them are, indicating a NaN time value.
8223 // [value]: the time value.
8224 DECL_ACCESSORS(value, Object)
8225 // [year]: caches year. Either undefined, smi, or NaN.
8226 DECL_ACCESSORS(year, Object)
8227 // [month]: caches month. Either undefined, smi, or NaN.
8228 DECL_ACCESSORS(month, Object)
8229 // [day]: caches day. Either undefined, smi, or NaN.
8230 DECL_ACCESSORS(day, Object)
8231 // [weekday]: caches day of week. Either undefined, smi, or NaN.
8232 DECL_ACCESSORS(weekday, Object)
8233 // [hour]: caches hours. Either undefined, smi, or NaN.
8234 DECL_ACCESSORS(hour, Object)
8235 // [min]: caches minutes. Either undefined, smi, or NaN.
8236 DECL_ACCESSORS(min, Object)
8237 // [sec]: caches seconds. Either undefined, smi, or NaN.
8238 DECL_ACCESSORS(sec, Object)
8239 // [cache stamp]: sample of the date cache stamp at the
8240 // moment when chached fields were cached.
8241 DECL_ACCESSORS(cache_stamp, Object)
8242
8243 DECLARE_CAST(JSDate)
8244
8245 // Returns the time value (UTC) identifying the current time.
8246 static double CurrentTimeValue(Isolate* isolate);
8247
8248 // Returns the date field with the specified index.
8249 // See FieldIndex for the list of date fields.
8250 static Object* GetField(Object* date, Smi* index);
8251
8252 static Handle<Object> SetValue(Handle<JSDate> date, double v);
8253
8254 void SetValue(Object* value, bool is_value_nan);
8255
8256 // Dispatched behavior.
8257 DECLARE_PRINTER(JSDate)
8258 DECLARE_VERIFIER(JSDate)
8259
8260 // The order is important. It must be kept in sync with date macros
8261 // in macros.py.
8262 enum FieldIndex {
8263 kDateValue,
8264 kYear,
8265 kMonth,
8266 kDay,
8267 kWeekday,
8268 kHour,
8269 kMinute,
8270 kSecond,
8271 kFirstUncachedField,
8272 kMillisecond = kFirstUncachedField,
8273 kDays,
8274 kTimeInDay,
8275 kFirstUTCField,
8276 kYearUTC = kFirstUTCField,
8277 kMonthUTC,
8278 kDayUTC,
8279 kWeekdayUTC,
8280 kHourUTC,
8281 kMinuteUTC,
8282 kSecondUTC,
8283 kMillisecondUTC,
8284 kDaysUTC,
8285 kTimeInDayUTC,
8286 kTimezoneOffset
8287 };
8288
8289 // Layout description.
8290 static const int kValueOffset = JSObject::kHeaderSize;
8291 static const int kYearOffset = kValueOffset + kPointerSize;
8292 static const int kMonthOffset = kYearOffset + kPointerSize;
8293 static const int kDayOffset = kMonthOffset + kPointerSize;
8294 static const int kWeekdayOffset = kDayOffset + kPointerSize;
8295 static const int kHourOffset = kWeekdayOffset + kPointerSize;
8296 static const int kMinOffset = kHourOffset + kPointerSize;
8297 static const int kSecOffset = kMinOffset + kPointerSize;
8298 static const int kCacheStampOffset = kSecOffset + kPointerSize;
8299 static const int kSize = kCacheStampOffset + kPointerSize;
8300
8301 private:
8302 inline Object* DoGetField(FieldIndex index);
8303
8304 Object* GetUTCField(FieldIndex index, double value, DateCache* date_cache);
8305
8306 // Computes and caches the cacheable fields of the date.
8307 inline void SetCachedFields(int64_t local_time_ms, DateCache* date_cache);
8308
8309
8310 DISALLOW_IMPLICIT_CONSTRUCTORS(JSDate);
8311 };
8312
8313
8314 // Representation of message objects used for error reporting through
8315 // the API. The messages are formatted in JavaScript so this object is
8316 // a real JavaScript object. The information used for formatting the
8317 // error messages are not directly accessible from JavaScript to
8318 // prevent leaking information to user code called during error
8319 // formatting.
8320 class JSMessageObject: public JSObject {
8321 public:
8322 // [type]: the type of error message.
8323 inline int type() const;
8324 inline void set_type(int value);
8325
8326 // [arguments]: the arguments for formatting the error message.
8327 DECL_ACCESSORS(argument, Object)
8328
8329 // [script]: the script from which the error message originated.
8330 DECL_ACCESSORS(script, Object)
8331
8332 // [stack_frames]: an array of stack frames for this error object.
8333 DECL_ACCESSORS(stack_frames, Object)
8334
8335 // [start_position]: the start position in the script for the error message.
8336 inline int start_position() const;
8337 inline void set_start_position(int value);
8338
8339 // [end_position]: the end position in the script for the error message.
8340 inline int end_position() const;
8341 inline void set_end_position(int value);
8342
8343 int GetLineNumber() const;
8344
8345 // Returns the offset of the given position within the containing line.
8346 int GetColumnNumber() const;
8347
8348 // Returns the source code line containing the given source
8349 // position, or the empty string if the position is invalid.
8350 Handle<String> GetSourceLine() const;
8351
8352 inline int error_level() const;
8353 inline void set_error_level(int level);
8354
8355 DECLARE_CAST(JSMessageObject)
8356
8357 // Dispatched behavior.
8358 DECLARE_PRINTER(JSMessageObject)
8359 DECLARE_VERIFIER(JSMessageObject)
8360
8361 // Layout description.
8362 static const int kTypeOffset = JSObject::kHeaderSize;
8363 static const int kArgumentsOffset = kTypeOffset + kPointerSize;
8364 static const int kScriptOffset = kArgumentsOffset + kPointerSize;
8365 static const int kStackFramesOffset = kScriptOffset + kPointerSize;
8366 static const int kStartPositionOffset = kStackFramesOffset + kPointerSize;
8367 static const int kEndPositionOffset = kStartPositionOffset + kPointerSize;
8368 static const int kErrorLevelOffset = kEndPositionOffset + kPointerSize;
8369 static const int kSize = kErrorLevelOffset + kPointerSize;
8370
8371 typedef FixedBodyDescriptor<HeapObject::kMapOffset,
8372 kStackFramesOffset + kPointerSize,
8373 kSize> BodyDescriptor;
8374 };
8375
8376 class JSPromise;
8377
8378 // TODO(caitp): Make this a Struct once properties are no longer accessed from
8379 // JS
8380 class JSPromiseCapability : public JSObject {
8381 public:
8382 DECLARE_CAST(JSPromiseCapability)
8383
8384 DECLARE_VERIFIER(JSPromiseCapability)
8385
8386 DECL_ACCESSORS(promise, Object)
8387 DECL_ACCESSORS(resolve, Object)
8388 DECL_ACCESSORS(reject, Object)
8389
8390 static const int kPromiseOffset = JSObject::kHeaderSize;
8391 static const int kResolveOffset = kPromiseOffset + kPointerSize;
8392 static const int kRejectOffset = kResolveOffset + kPointerSize;
8393 static const int kSize = kRejectOffset + kPointerSize;
8394
8395 enum InObjectPropertyIndex {
8396 kPromiseIndex,
8397 kResolveIndex,
8398 kRejectIndex,
8399 kInObjectPropertyCount // Dummy.
8400 };
8401
8402 private:
8403 DISALLOW_IMPLICIT_CONSTRUCTORS(JSPromiseCapability);
8404 };
8405
8406 class JSPromise : public JSObject {
8407 public:
8408 DECL_INT_ACCESSORS(status)
8409 DECL_ACCESSORS(result, Object)
8410
8411 // There are 3 possible states for these fields --
8412 // 1) Undefined -- This is the zero state when there is no callback
8413 // or deferred fields registered.
8414 //
8415 // 2) Object -- There is a single callback directly attached to the
8416 // fulfill_reactions, reject_reactions and the deferred fields are
8417 // directly attached to the slots. In this state, deferred_promise
8418 // is a JSReceiver and deferred_on_{resolve, reject} are Callables.
8419 //
8420 // 3) FixedArray -- There is more than one callback and deferred
8421 // fields attached to a FixedArray.
8422 //
8423 // The callback can be a Callable or a Symbol.
8424 DECL_ACCESSORS(deferred_promise, Object)
8425 DECL_ACCESSORS(deferred_on_resolve, Object)
8426 DECL_ACCESSORS(deferred_on_reject, Object)
8427 DECL_ACCESSORS(fulfill_reactions, Object)
8428 DECL_ACCESSORS(reject_reactions, Object)
8429
8430 DECL_INT_ACCESSORS(flags)
8431
8432 // [has_handler]: Whether this promise has a reject handler or not.
8433 DECL_BOOLEAN_ACCESSORS(has_handler)
8434
8435 // [handled_hint]: Whether this promise will be handled by a catch
8436 // block in an async function.
8437 DECL_BOOLEAN_ACCESSORS(handled_hint)
8438
8439 static const char* Status(int status);
8440
8441 DECLARE_CAST(JSPromise)
8442
8443 // Dispatched behavior.
8444 DECLARE_PRINTER(JSPromise)
8445 DECLARE_VERIFIER(JSPromise)
8446
8447 // Layout description.
8448 static const int kStatusOffset = JSObject::kHeaderSize;
8449 static const int kResultOffset = kStatusOffset + kPointerSize;
8450 static const int kDeferredPromiseOffset = kResultOffset + kPointerSize;
8451 static const int kDeferredOnResolveOffset =
8452 kDeferredPromiseOffset + kPointerSize;
8453 static const int kDeferredOnRejectOffset =
8454 kDeferredOnResolveOffset + kPointerSize;
8455 static const int kFulfillReactionsOffset =
8456 kDeferredOnRejectOffset + kPointerSize;
8457 static const int kRejectReactionsOffset =
8458 kFulfillReactionsOffset + kPointerSize;
8459 static const int kFlagsOffset = kRejectReactionsOffset + kPointerSize;
8460 static const int kSize = kFlagsOffset + kPointerSize;
8461
8462 // Flags layout.
8463 static const int kHasHandlerBit = 0;
8464 static const int kHandledHintBit = 1;
8465 };
8466
8467 // Regular expressions
8468 // The regular expression holds a single reference to a FixedArray in
8469 // the kDataOffset field.
8470 // The FixedArray contains the following data:
8471 // - tag : type of regexp implementation (not compiled yet, atom or irregexp)
8472 // - reference to the original source string
8473 // - reference to the original flag string
8474 // If it is an atom regexp
8475 // - a reference to a literal string to search for
8476 // If it is an irregexp regexp:
8477 // - a reference to code for Latin1 inputs (bytecode or compiled), or a smi
8478 // used for tracking the last usage (used for code flushing).
8479 // - a reference to code for UC16 inputs (bytecode or compiled), or a smi
8480 // used for tracking the last usage (used for code flushing)..
8481 // - max number of registers used by irregexp implementations.
8482 // - number of capture registers (output values) of the regexp.
8483 class JSRegExp: public JSObject {
8484 public:
8485 // Meaning of Type:
8486 // NOT_COMPILED: Initial value. No data has been stored in the JSRegExp yet.
8487 // ATOM: A simple string to match against using an indexOf operation.
8488 // IRREGEXP: Compiled with Irregexp.
8489 enum Type { NOT_COMPILED, ATOM, IRREGEXP };
8490 enum Flag {
8491 kNone = 0,
8492 kGlobal = 1 << 0,
8493 kIgnoreCase = 1 << 1,
8494 kMultiline = 1 << 2,
8495 kSticky = 1 << 3,
8496 kUnicode = 1 << 4,
8497 };
8498 typedef base::Flags<Flag> Flags;
8499
8500 DECL_ACCESSORS(data, Object)
8501 DECL_ACCESSORS(flags, Object)
8502 DECL_ACCESSORS(source, Object)
8503
8504 V8_EXPORT_PRIVATE static MaybeHandle<JSRegExp> New(Handle<String> source,
8505 Flags flags);
8506 static Handle<JSRegExp> Copy(Handle<JSRegExp> regexp);
8507
8508 static MaybeHandle<JSRegExp> Initialize(Handle<JSRegExp> regexp,
8509 Handle<String> source, Flags flags);
8510 static MaybeHandle<JSRegExp> Initialize(Handle<JSRegExp> regexp,
8511 Handle<String> source,
8512 Handle<String> flags_string);
8513
8514 inline Type TypeTag();
8515 inline int CaptureCount();
8516 inline Flags GetFlags();
8517 inline String* Pattern();
8518 inline Object* DataAt(int index);
8519 // Set implementation data after the object has been prepared.
8520 inline void SetDataAt(int index, Object* value);
8521
8522 inline void SetLastIndex(int index);
8523 inline Object* LastIndex();
8524
code_index(bool is_latin1)8525 static int code_index(bool is_latin1) {
8526 if (is_latin1) {
8527 return kIrregexpLatin1CodeIndex;
8528 } else {
8529 return kIrregexpUC16CodeIndex;
8530 }
8531 }
8532
saved_code_index(bool is_latin1)8533 static int saved_code_index(bool is_latin1) {
8534 if (is_latin1) {
8535 return kIrregexpLatin1CodeSavedIndex;
8536 } else {
8537 return kIrregexpUC16CodeSavedIndex;
8538 }
8539 }
8540
8541 DECLARE_CAST(JSRegExp)
8542
8543 // Dispatched behavior.
8544 DECLARE_PRINTER(JSRegExp)
8545 DECLARE_VERIFIER(JSRegExp)
8546
8547 static const int kDataOffset = JSObject::kHeaderSize;
8548 static const int kSourceOffset = kDataOffset + kPointerSize;
8549 static const int kFlagsOffset = kSourceOffset + kPointerSize;
8550 static const int kSize = kFlagsOffset + kPointerSize;
8551
8552 // Indices in the data array.
8553 static const int kTagIndex = 0;
8554 static const int kSourceIndex = kTagIndex + 1;
8555 static const int kFlagsIndex = kSourceIndex + 1;
8556 static const int kDataIndex = kFlagsIndex + 1;
8557 // The data fields are used in different ways depending on the
8558 // value of the tag.
8559 // Atom regexps (literal strings).
8560 static const int kAtomPatternIndex = kDataIndex;
8561
8562 static const int kAtomDataSize = kAtomPatternIndex + 1;
8563
8564 // Irregexp compiled code or bytecode for Latin1. If compilation
8565 // fails, this fields hold an exception object that should be
8566 // thrown if the regexp is used again.
8567 static const int kIrregexpLatin1CodeIndex = kDataIndex;
8568 // Irregexp compiled code or bytecode for UC16. If compilation
8569 // fails, this fields hold an exception object that should be
8570 // thrown if the regexp is used again.
8571 static const int kIrregexpUC16CodeIndex = kDataIndex + 1;
8572
8573 // Saved instance of Irregexp compiled code or bytecode for Latin1 that
8574 // is a potential candidate for flushing.
8575 static const int kIrregexpLatin1CodeSavedIndex = kDataIndex + 2;
8576 // Saved instance of Irregexp compiled code or bytecode for UC16 that is
8577 // a potential candidate for flushing.
8578 static const int kIrregexpUC16CodeSavedIndex = kDataIndex + 3;
8579
8580 // Maximal number of registers used by either Latin1 or UC16.
8581 // Only used to check that there is enough stack space
8582 static const int kIrregexpMaxRegisterCountIndex = kDataIndex + 4;
8583 // Number of captures in the compiled regexp.
8584 static const int kIrregexpCaptureCountIndex = kDataIndex + 5;
8585 // Maps names of named capture groups (at indices 2i) to their corresponding
8586 // capture group indices (at indices 2i + 1).
8587 static const int kIrregexpCaptureNameMapIndex = kDataIndex + 6;
8588
8589 static const int kIrregexpDataSize = kIrregexpCaptureNameMapIndex + 1;
8590
8591 // Offsets directly into the data fixed array.
8592 static const int kDataTagOffset =
8593 FixedArray::kHeaderSize + kTagIndex * kPointerSize;
8594 static const int kDataOneByteCodeOffset =
8595 FixedArray::kHeaderSize + kIrregexpLatin1CodeIndex * kPointerSize;
8596 static const int kDataUC16CodeOffset =
8597 FixedArray::kHeaderSize + kIrregexpUC16CodeIndex * kPointerSize;
8598 static const int kIrregexpCaptureCountOffset =
8599 FixedArray::kHeaderSize + kIrregexpCaptureCountIndex * kPointerSize;
8600
8601 // In-object fields.
8602 static const int kLastIndexFieldIndex = 0;
8603 static const int kInObjectFieldCount = 1;
8604
8605 // The uninitialized value for a regexp code object.
8606 static const int kUninitializedValue = -1;
8607
8608 // The compilation error value for the regexp code object. The real error
8609 // object is in the saved code field.
8610 static const int kCompilationErrorValue = -2;
8611
8612 // When we store the sweep generation at which we moved the code from the
8613 // code index to the saved code index we mask it of to be in the [0:255]
8614 // range.
8615 static const int kCodeAgeMask = 0xff;
8616 };
8617
DEFINE_OPERATORS_FOR_FLAGS(JSRegExp::Flags)8618 DEFINE_OPERATORS_FOR_FLAGS(JSRegExp::Flags)
8619
8620
8621 class CompilationCacheShape : public BaseShape<HashTableKey*> {
8622 public:
8623 static inline bool IsMatch(HashTableKey* key, Object* value) {
8624 return key->IsMatch(value);
8625 }
8626
8627 static inline uint32_t Hash(HashTableKey* key) {
8628 return key->Hash();
8629 }
8630
8631 static inline uint32_t HashForObject(HashTableKey* key, Object* object) {
8632 return key->HashForObject(object);
8633 }
8634
8635 static inline Handle<Object> AsHandle(Isolate* isolate, HashTableKey* key);
8636
8637 static const int kPrefixSize = 0;
8638 static const int kEntrySize = 3;
8639 };
8640
8641 class InfoVectorPair {
8642 public:
InfoVectorPair()8643 InfoVectorPair() : shared_(nullptr), vector_cell_(nullptr) {}
InfoVectorPair(SharedFunctionInfo * shared,Cell * vector_cell)8644 InfoVectorPair(SharedFunctionInfo* shared, Cell* vector_cell)
8645 : shared_(shared), vector_cell_(vector_cell) {}
8646
shared()8647 SharedFunctionInfo* shared() const { return shared_; }
vector()8648 Cell* vector() const { return vector_cell_; }
8649
has_shared()8650 bool has_shared() const { return shared_ != nullptr; }
has_vector()8651 bool has_vector() const { return vector_cell_ != nullptr; }
8652
8653 private:
8654 SharedFunctionInfo* shared_;
8655 Cell* vector_cell_;
8656 };
8657
8658 // This cache is used in two different variants. For regexp caching, it simply
8659 // maps identifying info of the regexp to the cached regexp object. Scripts and
8660 // eval code only gets cached after a second probe for the code object. To do
8661 // so, on first "put" only a hash identifying the source is entered into the
8662 // cache, mapping it to a lifetime count of the hash. On each call to Age all
8663 // such lifetimes get reduced, and removed once they reach zero. If a second put
8664 // is called while such a hash is live in the cache, the hash gets replaced by
8665 // an actual cache entry. Age also removes stale live entries from the cache.
8666 // Such entries are identified by SharedFunctionInfos pointing to either the
8667 // recompilation stub, or to "old" code. This avoids memory leaks due to
8668 // premature caching of scripts and eval strings that are never needed later.
8669 class CompilationCacheTable: public HashTable<CompilationCacheTable,
8670 CompilationCacheShape,
8671 HashTableKey*> {
8672 public:
8673 // Find cached value for a string key, otherwise return null.
8674 Handle<Object> Lookup(
8675 Handle<String> src, Handle<Context> context, LanguageMode language_mode);
8676 InfoVectorPair LookupScript(Handle<String> src, Handle<Context> context,
8677 LanguageMode language_mode);
8678 InfoVectorPair LookupEval(Handle<String> src,
8679 Handle<SharedFunctionInfo> shared,
8680 Handle<Context> native_context,
8681 LanguageMode language_mode, int position);
8682 Handle<Object> LookupRegExp(Handle<String> source, JSRegExp::Flags flags);
8683 static Handle<CompilationCacheTable> Put(
8684 Handle<CompilationCacheTable> cache, Handle<String> src,
8685 Handle<Context> context, LanguageMode language_mode,
8686 Handle<Object> value);
8687 static Handle<CompilationCacheTable> PutScript(
8688 Handle<CompilationCacheTable> cache, Handle<String> src,
8689 Handle<Context> context, LanguageMode language_mode,
8690 Handle<SharedFunctionInfo> value, Handle<Cell> literals);
8691 static Handle<CompilationCacheTable> PutEval(
8692 Handle<CompilationCacheTable> cache, Handle<String> src,
8693 Handle<SharedFunctionInfo> outer_info, Handle<SharedFunctionInfo> value,
8694 Handle<Context> native_context, Handle<Cell> literals, int position);
8695 static Handle<CompilationCacheTable> PutRegExp(
8696 Handle<CompilationCacheTable> cache, Handle<String> src,
8697 JSRegExp::Flags flags, Handle<FixedArray> value);
8698 void Remove(Object* value);
8699 void Age();
8700 static const int kHashGenerations = 10;
8701
8702 DECLARE_CAST(CompilationCacheTable)
8703
8704 private:
8705 DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationCacheTable);
8706 };
8707
8708
8709 class CodeCacheHashTableShape : public BaseShape<HashTableKey*> {
8710 public:
IsMatch(HashTableKey * key,Object * value)8711 static inline bool IsMatch(HashTableKey* key, Object* value) {
8712 return key->IsMatch(value);
8713 }
8714
Hash(HashTableKey * key)8715 static inline uint32_t Hash(HashTableKey* key) {
8716 return key->Hash();
8717 }
8718
HashForObject(HashTableKey * key,Object * object)8719 static inline uint32_t HashForObject(HashTableKey* key, Object* object) {
8720 return key->HashForObject(object);
8721 }
8722
8723 static inline Handle<Object> AsHandle(Isolate* isolate, HashTableKey* key);
8724
8725 static const int kPrefixSize = 0;
8726 // The both the key (name + flags) and value (code object) can be derived from
8727 // the fixed array that stores both the name and code.
8728 // TODO(verwaest): Don't allocate a fixed array but inline name and code.
8729 // Rewrite IsMatch to get table + index as input rather than just the raw key.
8730 static const int kEntrySize = 1;
8731 };
8732
8733
8734 class CodeCacheHashTable: public HashTable<CodeCacheHashTable,
8735 CodeCacheHashTableShape,
8736 HashTableKey*> {
8737 public:
8738 static Handle<CodeCacheHashTable> Put(
8739 Handle<CodeCacheHashTable> table,
8740 Handle<Name> name,
8741 Handle<Code> code);
8742
8743 Code* Lookup(Name* name, Code::Flags flags);
8744
8745 DECLARE_CAST(CodeCacheHashTable)
8746
8747 private:
8748 DISALLOW_IMPLICIT_CONSTRUCTORS(CodeCacheHashTable);
8749 };
8750
8751
8752 class TypeFeedbackInfo: public Struct {
8753 public:
8754 inline int ic_total_count();
8755 inline void set_ic_total_count(int count);
8756
8757 inline int ic_with_type_info_count();
8758 inline void change_ic_with_type_info_count(int delta);
8759
8760 inline int ic_generic_count();
8761 inline void change_ic_generic_count(int delta);
8762
8763 inline void initialize_storage();
8764
8765 inline void change_own_type_change_checksum();
8766 inline int own_type_change_checksum();
8767
8768 inline void set_inlined_type_change_checksum(int checksum);
8769 inline bool matches_inlined_type_change_checksum(int checksum);
8770
8771 DECLARE_CAST(TypeFeedbackInfo)
8772
8773 // Dispatched behavior.
8774 DECLARE_PRINTER(TypeFeedbackInfo)
8775 DECLARE_VERIFIER(TypeFeedbackInfo)
8776
8777 static const int kStorage1Offset = HeapObject::kHeaderSize;
8778 static const int kStorage2Offset = kStorage1Offset + kPointerSize;
8779 static const int kStorage3Offset = kStorage2Offset + kPointerSize;
8780 static const int kSize = kStorage3Offset + kPointerSize;
8781
8782 private:
8783 static const int kTypeChangeChecksumBits = 7;
8784
8785 class ICTotalCountField: public BitField<int, 0,
8786 kSmiValueSize - kTypeChangeChecksumBits> {}; // NOLINT
8787 class OwnTypeChangeChecksum: public BitField<int,
8788 kSmiValueSize - kTypeChangeChecksumBits,
8789 kTypeChangeChecksumBits> {}; // NOLINT
8790 class ICsWithTypeInfoCountField: public BitField<int, 0,
8791 kSmiValueSize - kTypeChangeChecksumBits> {}; // NOLINT
8792 class InlinedTypeChangeChecksum: public BitField<int,
8793 kSmiValueSize - kTypeChangeChecksumBits,
8794 kTypeChangeChecksumBits> {}; // NOLINT
8795
8796 DISALLOW_IMPLICIT_CONSTRUCTORS(TypeFeedbackInfo);
8797 };
8798
8799 class AllocationSite: public Struct {
8800 public:
8801 static const uint32_t kMaximumArrayBytesToPretransition = 8 * 1024;
8802 static const double kPretenureRatio;
8803 static const int kPretenureMinimumCreated = 100;
8804
8805 // Values for pretenure decision field.
8806 enum PretenureDecision {
8807 kUndecided = 0,
8808 kDontTenure = 1,
8809 kMaybeTenure = 2,
8810 kTenure = 3,
8811 kZombie = 4,
8812 kLastPretenureDecisionValue = kZombie
8813 };
8814
8815 const char* PretenureDecisionName(PretenureDecision decision);
8816
8817 DECL_ACCESSORS(transition_info, Object)
8818 // nested_site threads a list of sites that represent nested literals
8819 // walked in a particular order. So [[1, 2], 1, 2] will have one
8820 // nested_site, but [[1, 2], 3, [4]] will have a list of two.
8821 DECL_ACCESSORS(nested_site, Object)
8822 DECL_INT_ACCESSORS(pretenure_data)
8823 DECL_INT_ACCESSORS(pretenure_create_count)
8824 DECL_ACCESSORS(dependent_code, DependentCode)
8825 DECL_ACCESSORS(weak_next, Object)
8826
8827 inline void Initialize();
8828
8829 // This method is expensive, it should only be called for reporting.
8830 bool IsNestedSite();
8831
8832 // transition_info bitfields, for constructed array transition info.
8833 class ElementsKindBits: public BitField<ElementsKind, 0, 15> {};
8834 class UnusedBits: public BitField<int, 15, 14> {};
8835 class DoNotInlineBit: public BitField<bool, 29, 1> {};
8836
8837 // Bitfields for pretenure_data
8838 class MementoFoundCountBits: public BitField<int, 0, 26> {};
8839 class PretenureDecisionBits: public BitField<PretenureDecision, 26, 3> {};
8840 class DeoptDependentCodeBit: public BitField<bool, 29, 1> {};
8841 STATIC_ASSERT(PretenureDecisionBits::kMax >= kLastPretenureDecisionValue);
8842
8843 // Increments the mementos found counter and returns true when the first
8844 // memento was found for a given allocation site.
8845 inline bool IncrementMementoFoundCount(int increment = 1);
8846
8847 inline void IncrementMementoCreateCount();
8848
8849 PretenureFlag GetPretenureMode();
8850
8851 void ResetPretenureDecision();
8852
8853 inline PretenureDecision pretenure_decision();
8854 inline void set_pretenure_decision(PretenureDecision decision);
8855
8856 inline bool deopt_dependent_code();
8857 inline void set_deopt_dependent_code(bool deopt);
8858
8859 inline int memento_found_count();
8860 inline void set_memento_found_count(int count);
8861
8862 inline int memento_create_count();
8863 inline void set_memento_create_count(int count);
8864
8865 // The pretenuring decision is made during gc, and the zombie state allows
8866 // us to recognize when an allocation site is just being kept alive because
8867 // a later traversal of new space may discover AllocationMementos that point
8868 // to this AllocationSite.
8869 inline bool IsZombie();
8870
8871 inline bool IsMaybeTenure();
8872
8873 inline void MarkZombie();
8874
8875 inline bool MakePretenureDecision(PretenureDecision current_decision,
8876 double ratio,
8877 bool maximum_size_scavenge);
8878
8879 inline bool DigestPretenuringFeedback(bool maximum_size_scavenge);
8880
8881 inline ElementsKind GetElementsKind();
8882 inline void SetElementsKind(ElementsKind kind);
8883
8884 inline bool CanInlineCall();
8885 inline void SetDoNotInlineCall();
8886
8887 inline bool SitePointsToLiteral();
8888
8889 template <AllocationSiteUpdateMode update_or_check =
8890 AllocationSiteUpdateMode::kUpdate>
8891 static bool DigestTransitionFeedback(Handle<AllocationSite> site,
8892 ElementsKind to_kind);
8893
8894 DECLARE_PRINTER(AllocationSite)
8895 DECLARE_VERIFIER(AllocationSite)
8896
8897 DECLARE_CAST(AllocationSite)
8898 static inline AllocationSiteMode GetMode(
8899 ElementsKind boilerplate_elements_kind);
8900 static AllocationSiteMode GetMode(ElementsKind from, ElementsKind to);
8901 static inline bool CanTrack(InstanceType type);
8902
8903 static const int kTransitionInfoOffset = HeapObject::kHeaderSize;
8904 static const int kNestedSiteOffset = kTransitionInfoOffset + kPointerSize;
8905 static const int kPretenureDataOffset = kNestedSiteOffset + kPointerSize;
8906 static const int kPretenureCreateCountOffset =
8907 kPretenureDataOffset + kPointerSize;
8908 static const int kDependentCodeOffset =
8909 kPretenureCreateCountOffset + kPointerSize;
8910 static const int kWeakNextOffset = kDependentCodeOffset + kPointerSize;
8911 static const int kSize = kWeakNextOffset + kPointerSize;
8912
8913 // During mark compact we need to take special care for the dependent code
8914 // field.
8915 static const int kPointerFieldsBeginOffset = kTransitionInfoOffset;
8916 static const int kPointerFieldsEndOffset = kWeakNextOffset;
8917
8918 typedef FixedBodyDescriptor<kPointerFieldsBeginOffset,
8919 kPointerFieldsEndOffset, kSize>
8920 MarkingBodyDescriptor;
8921
8922 // For other visitors, use the fixed body descriptor below.
8923 typedef FixedBodyDescriptor<HeapObject::kHeaderSize, kSize, kSize>
8924 BodyDescriptor;
8925
8926 private:
8927 inline bool PretenuringDecisionMade();
8928
8929 DISALLOW_IMPLICIT_CONSTRUCTORS(AllocationSite);
8930 };
8931
8932
8933 class AllocationMemento: public Struct {
8934 public:
8935 static const int kAllocationSiteOffset = HeapObject::kHeaderSize;
8936 static const int kSize = kAllocationSiteOffset + kPointerSize;
8937
8938 DECL_ACCESSORS(allocation_site, Object)
8939
8940 inline bool IsValid();
8941 inline AllocationSite* GetAllocationSite();
8942 inline Address GetAllocationSiteUnchecked();
8943
8944 DECLARE_PRINTER(AllocationMemento)
8945 DECLARE_VERIFIER(AllocationMemento)
8946
8947 DECLARE_CAST(AllocationMemento)
8948
8949 private:
8950 DISALLOW_IMPLICIT_CONSTRUCTORS(AllocationMemento);
8951 };
8952
8953
8954 // Representation of a slow alias as part of a sloppy arguments objects.
8955 // For fast aliases (if HasSloppyArgumentsElements()):
8956 // - the parameter map contains an index into the context
8957 // - all attributes of the element have default values
8958 // For slow aliases (if HasDictionaryArgumentsElements()):
8959 // - the parameter map contains no fast alias mapping (i.e. the hole)
8960 // - this struct (in the slow backing store) contains an index into the context
8961 // - all attributes are available as part if the property details
8962 class AliasedArgumentsEntry: public Struct {
8963 public:
8964 inline int aliased_context_slot() const;
8965 inline void set_aliased_context_slot(int count);
8966
8967 DECLARE_CAST(AliasedArgumentsEntry)
8968
8969 // Dispatched behavior.
8970 DECLARE_PRINTER(AliasedArgumentsEntry)
8971 DECLARE_VERIFIER(AliasedArgumentsEntry)
8972
8973 static const int kAliasedContextSlot = HeapObject::kHeaderSize;
8974 static const int kSize = kAliasedContextSlot + kPointerSize;
8975
8976 private:
8977 DISALLOW_IMPLICIT_CONSTRUCTORS(AliasedArgumentsEntry);
8978 };
8979
8980
8981 enum AllowNullsFlag {ALLOW_NULLS, DISALLOW_NULLS};
8982 enum RobustnessFlag {ROBUST_STRING_TRAVERSAL, FAST_STRING_TRAVERSAL};
8983
8984 class V8_EXPORT_PRIVATE StringHasher {
8985 public:
8986 explicit inline StringHasher(int length, uint32_t seed);
8987
8988 template <typename schar>
8989 static inline uint32_t HashSequentialString(const schar* chars,
8990 int length,
8991 uint32_t seed);
8992
8993 // Reads all the data, even for long strings and computes the utf16 length.
8994 static uint32_t ComputeUtf8Hash(Vector<const char> chars,
8995 uint32_t seed,
8996 int* utf16_length_out);
8997
8998 // Calculated hash value for a string consisting of 1 to
8999 // String::kMaxArrayIndexSize digits with no leading zeros (except "0").
9000 // value is represented decimal value.
9001 static uint32_t MakeArrayIndexHash(uint32_t value, int length);
9002
9003 // No string is allowed to have a hash of zero. That value is reserved
9004 // for internal properties. If the hash calculation yields zero then we
9005 // use 27 instead.
9006 static const int kZeroHash = 27;
9007
9008 // Reusable parts of the hashing algorithm.
9009 INLINE(static uint32_t AddCharacterCore(uint32_t running_hash, uint16_t c));
9010 INLINE(static uint32_t GetHashCore(uint32_t running_hash));
9011 INLINE(static uint32_t ComputeRunningHash(uint32_t running_hash,
9012 const uc16* chars, int length));
9013 INLINE(static uint32_t ComputeRunningHashOneByte(uint32_t running_hash,
9014 const char* chars,
9015 int length));
9016
9017 protected:
9018 // Returns the value to store in the hash field of a string with
9019 // the given length and contents.
9020 uint32_t GetHashField();
9021 // Returns true if the hash of this string can be computed without
9022 // looking at the contents.
9023 inline bool has_trivial_hash();
9024 // Adds a block of characters to the hash.
9025 template<typename Char>
9026 inline void AddCharacters(const Char* chars, int len);
9027
9028 private:
9029 // Add a character to the hash.
9030 inline void AddCharacter(uint16_t c);
9031 // Update index. Returns true if string is still an index.
9032 inline bool UpdateIndex(uint16_t c);
9033
9034 int length_;
9035 uint32_t raw_running_hash_;
9036 uint32_t array_index_;
9037 bool is_array_index_;
9038 bool is_first_char_;
9039 DISALLOW_COPY_AND_ASSIGN(StringHasher);
9040 };
9041
9042
9043 class IteratingStringHasher : public StringHasher {
9044 public:
9045 static inline uint32_t Hash(String* string, uint32_t seed);
9046 inline void VisitOneByteString(const uint8_t* chars, int length);
9047 inline void VisitTwoByteString(const uint16_t* chars, int length);
9048
9049 private:
9050 inline IteratingStringHasher(int len, uint32_t seed);
9051 void VisitConsString(ConsString* cons_string);
9052 DISALLOW_COPY_AND_ASSIGN(IteratingStringHasher);
9053 };
9054
9055
9056 // The characteristics of a string are stored in its map. Retrieving these
9057 // few bits of information is moderately expensive, involving two memory
9058 // loads where the second is dependent on the first. To improve efficiency
9059 // the shape of the string is given its own class so that it can be retrieved
9060 // once and used for several string operations. A StringShape is small enough
9061 // to be passed by value and is immutable, but be aware that flattening a
9062 // string can potentially alter its shape. Also be aware that a GC caused by
9063 // something else can alter the shape of a string due to ConsString
9064 // shortcutting. Keeping these restrictions in mind has proven to be error-
9065 // prone and so we no longer put StringShapes in variables unless there is a
9066 // concrete performance benefit at that particular point in the code.
9067 class StringShape BASE_EMBEDDED {
9068 public:
9069 inline explicit StringShape(const String* s);
9070 inline explicit StringShape(Map* s);
9071 inline explicit StringShape(InstanceType t);
9072 inline bool IsSequential();
9073 inline bool IsExternal();
9074 inline bool IsCons();
9075 inline bool IsSliced();
9076 inline bool IsThin();
9077 inline bool IsIndirect();
9078 inline bool IsExternalOneByte();
9079 inline bool IsExternalTwoByte();
9080 inline bool IsSequentialOneByte();
9081 inline bool IsSequentialTwoByte();
9082 inline bool IsInternalized();
9083 inline StringRepresentationTag representation_tag();
9084 inline uint32_t encoding_tag();
9085 inline uint32_t full_representation_tag();
9086 inline uint32_t size_tag();
9087 #ifdef DEBUG
type()9088 inline uint32_t type() { return type_; }
invalidate()9089 inline void invalidate() { valid_ = false; }
valid()9090 inline bool valid() { return valid_; }
9091 #else
invalidate()9092 inline void invalidate() { }
9093 #endif
9094
9095 private:
9096 uint32_t type_;
9097 #ifdef DEBUG
set_valid()9098 inline void set_valid() { valid_ = true; }
9099 bool valid_;
9100 #else
set_valid()9101 inline void set_valid() { }
9102 #endif
9103 };
9104
9105
9106 // The Name abstract class captures anything that can be used as a property
9107 // name, i.e., strings and symbols. All names store a hash value.
9108 class Name: public HeapObject {
9109 public:
9110 // Get and set the hash field of the name.
9111 inline uint32_t hash_field();
9112 inline void set_hash_field(uint32_t value);
9113
9114 // Tells whether the hash code has been computed.
9115 inline bool HasHashCode();
9116
9117 // Returns a hash value used for the property table
9118 inline uint32_t Hash();
9119
9120 // Equality operations.
9121 inline bool Equals(Name* other);
9122 inline static bool Equals(Handle<Name> one, Handle<Name> two);
9123
9124 // Conversion.
9125 inline bool AsArrayIndex(uint32_t* index);
9126
9127 // If the name is private, it can only name own properties.
9128 inline bool IsPrivate();
9129
9130 inline bool IsUniqueName() const;
9131
9132 // Return a string version of this name that is converted according to the
9133 // rules described in ES6 section 9.2.11.
9134 MUST_USE_RESULT static MaybeHandle<String> ToFunctionName(Handle<Name> name);
9135 MUST_USE_RESULT static MaybeHandle<String> ToFunctionName(
9136 Handle<Name> name, Handle<String> prefix);
9137
9138 DECLARE_CAST(Name)
9139
9140 DECLARE_PRINTER(Name)
9141 #if TRACE_MAPS
9142 void NameShortPrint();
9143 int NameShortPrint(Vector<char> str);
9144 #endif
9145
9146 // Layout description.
9147 static const int kHashFieldSlot = HeapObject::kHeaderSize;
9148 #if V8_TARGET_LITTLE_ENDIAN || !V8_HOST_ARCH_64_BIT
9149 static const int kHashFieldOffset = kHashFieldSlot;
9150 #else
9151 static const int kHashFieldOffset = kHashFieldSlot + kIntSize;
9152 #endif
9153 static const int kSize = kHashFieldSlot + kPointerSize;
9154
9155 // Mask constant for checking if a name has a computed hash code
9156 // and if it is a string that is an array index. The least significant bit
9157 // indicates whether a hash code has been computed. If the hash code has
9158 // been computed the 2nd bit tells whether the string can be used as an
9159 // array index.
9160 static const int kHashNotComputedMask = 1;
9161 static const int kIsNotArrayIndexMask = 1 << 1;
9162 static const int kNofHashBitFields = 2;
9163
9164 // Shift constant retrieving hash code from hash field.
9165 static const int kHashShift = kNofHashBitFields;
9166
9167 // Only these bits are relevant in the hash, since the top two are shifted
9168 // out.
9169 static const uint32_t kHashBitMask = 0xffffffffu >> kHashShift;
9170
9171 // Array index strings this short can keep their index in the hash field.
9172 static const int kMaxCachedArrayIndexLength = 7;
9173
9174 // Maximum number of characters to consider when trying to convert a string
9175 // value into an array index.
9176 static const int kMaxArrayIndexSize = 10;
9177
9178 // For strings which are array indexes the hash value has the string length
9179 // mixed into the hash, mainly to avoid a hash value of zero which would be
9180 // the case for the string '0'. 24 bits are used for the array index value.
9181 static const int kArrayIndexValueBits = 24;
9182 static const int kArrayIndexLengthBits =
9183 kBitsPerInt - kArrayIndexValueBits - kNofHashBitFields;
9184
9185 STATIC_ASSERT(kArrayIndexLengthBits > 0);
9186 STATIC_ASSERT(kMaxArrayIndexSize < (1 << kArrayIndexLengthBits));
9187
9188 class ArrayIndexValueBits : public BitField<unsigned int, kNofHashBitFields,
9189 kArrayIndexValueBits> {}; // NOLINT
9190 class ArrayIndexLengthBits : public BitField<unsigned int,
9191 kNofHashBitFields + kArrayIndexValueBits,
9192 kArrayIndexLengthBits> {}; // NOLINT
9193
9194 // Check that kMaxCachedArrayIndexLength + 1 is a power of two so we
9195 // could use a mask to test if the length of string is less than or equal to
9196 // kMaxCachedArrayIndexLength.
9197 STATIC_ASSERT(IS_POWER_OF_TWO(kMaxCachedArrayIndexLength + 1));
9198
9199 static const unsigned int kContainsCachedArrayIndexMask =
9200 (~static_cast<unsigned>(kMaxCachedArrayIndexLength)
9201 << ArrayIndexLengthBits::kShift) |
9202 kIsNotArrayIndexMask;
9203
9204 // Value of empty hash field indicating that the hash is not computed.
9205 static const int kEmptyHashField =
9206 kIsNotArrayIndexMask | kHashNotComputedMask;
9207
9208 protected:
9209 static inline bool IsHashFieldComputed(uint32_t field);
9210
9211 private:
9212 DISALLOW_IMPLICIT_CONSTRUCTORS(Name);
9213 };
9214
9215
9216 // ES6 symbols.
9217 class Symbol: public Name {
9218 public:
9219 // [name]: The print name of a symbol, or undefined if none.
9220 DECL_ACCESSORS(name, Object)
9221
9222 DECL_INT_ACCESSORS(flags)
9223
9224 // [is_private]: Whether this is a private symbol. Private symbols can only
9225 // be used to designate own properties of objects.
9226 DECL_BOOLEAN_ACCESSORS(is_private)
9227
9228 // [is_well_known_symbol]: Whether this is a spec-defined well-known symbol,
9229 // or not. Well-known symbols do not throw when an access check fails during
9230 // a load.
9231 DECL_BOOLEAN_ACCESSORS(is_well_known_symbol)
9232
9233 // [is_public]: Whether this is a symbol created by Symbol.for. Calling
9234 // Symbol.keyFor on such a symbol simply needs to return the attached name.
9235 DECL_BOOLEAN_ACCESSORS(is_public)
9236
9237 DECLARE_CAST(Symbol)
9238
9239 // Dispatched behavior.
9240 DECLARE_PRINTER(Symbol)
9241 DECLARE_VERIFIER(Symbol)
9242
9243 // Layout description.
9244 static const int kNameOffset = Name::kSize;
9245 static const int kFlagsOffset = kNameOffset + kPointerSize;
9246 static const int kSize = kFlagsOffset + kPointerSize;
9247
9248 // Flags layout.
9249 static const int kPrivateBit = 0;
9250 static const int kWellKnownSymbolBit = 1;
9251 static const int kPublicBit = 2;
9252
9253 typedef FixedBodyDescriptor<kNameOffset, kFlagsOffset, kSize> BodyDescriptor;
9254
9255 void SymbolShortPrint(std::ostream& os);
9256
9257 private:
9258 const char* PrivateSymbolToName() const;
9259
9260 #if TRACE_MAPS
9261 friend class Name; // For PrivateSymbolToName.
9262 #endif
9263
9264 DISALLOW_IMPLICIT_CONSTRUCTORS(Symbol);
9265 };
9266
9267
9268 class ConsString;
9269
9270 // The String abstract class captures JavaScript string values:
9271 //
9272 // Ecma-262:
9273 // 4.3.16 String Value
9274 // A string value is a member of the type String and is a finite
9275 // ordered sequence of zero or more 16-bit unsigned integer values.
9276 //
9277 // All string values have a length field.
9278 class String: public Name {
9279 public:
9280 enum Encoding { ONE_BYTE_ENCODING, TWO_BYTE_ENCODING };
9281
9282 class SubStringRange {
9283 public:
9284 explicit inline SubStringRange(String* string, int first = 0,
9285 int length = -1);
9286 class iterator;
9287 inline iterator begin();
9288 inline iterator end();
9289
9290 private:
9291 String* string_;
9292 int first_;
9293 int length_;
9294 };
9295
9296 // Representation of the flat content of a String.
9297 // A non-flat string doesn't have flat content.
9298 // A flat string has content that's encoded as a sequence of either
9299 // one-byte chars or two-byte UC16.
9300 // Returned by String::GetFlatContent().
9301 class FlatContent {
9302 public:
9303 // Returns true if the string is flat and this structure contains content.
IsFlat()9304 bool IsFlat() const { return state_ != NON_FLAT; }
9305 // Returns true if the structure contains one-byte content.
IsOneByte()9306 bool IsOneByte() const { return state_ == ONE_BYTE; }
9307 // Returns true if the structure contains two-byte content.
IsTwoByte()9308 bool IsTwoByte() const { return state_ == TWO_BYTE; }
9309
9310 // Return the one byte content of the string. Only use if IsOneByte()
9311 // returns true.
ToOneByteVector()9312 Vector<const uint8_t> ToOneByteVector() const {
9313 DCHECK_EQ(ONE_BYTE, state_);
9314 return Vector<const uint8_t>(onebyte_start, length_);
9315 }
9316 // Return the two-byte content of the string. Only use if IsTwoByte()
9317 // returns true.
ToUC16Vector()9318 Vector<const uc16> ToUC16Vector() const {
9319 DCHECK_EQ(TWO_BYTE, state_);
9320 return Vector<const uc16>(twobyte_start, length_);
9321 }
9322
Get(int i)9323 uc16 Get(int i) const {
9324 DCHECK(i < length_);
9325 DCHECK(state_ != NON_FLAT);
9326 if (state_ == ONE_BYTE) return onebyte_start[i];
9327 return twobyte_start[i];
9328 }
9329
UsesSameString(const FlatContent & other)9330 bool UsesSameString(const FlatContent& other) const {
9331 return onebyte_start == other.onebyte_start;
9332 }
9333
9334 private:
9335 enum State { NON_FLAT, ONE_BYTE, TWO_BYTE };
9336
9337 // Constructors only used by String::GetFlatContent().
FlatContent(const uint8_t * start,int length)9338 explicit FlatContent(const uint8_t* start, int length)
9339 : onebyte_start(start), length_(length), state_(ONE_BYTE) {}
FlatContent(const uc16 * start,int length)9340 explicit FlatContent(const uc16* start, int length)
9341 : twobyte_start(start), length_(length), state_(TWO_BYTE) { }
FlatContent()9342 FlatContent() : onebyte_start(NULL), length_(0), state_(NON_FLAT) { }
9343
9344 union {
9345 const uint8_t* onebyte_start;
9346 const uc16* twobyte_start;
9347 };
9348 int length_;
9349 State state_;
9350
9351 friend class String;
9352 friend class IterableSubString;
9353 };
9354
9355 template <typename Char>
9356 INLINE(Vector<const Char> GetCharVector());
9357
9358 // Get and set the length of the string.
9359 inline int length() const;
9360 inline void set_length(int value);
9361
9362 // Get and set the length of the string using acquire loads and release
9363 // stores.
9364 inline int synchronized_length() const;
9365 inline void synchronized_set_length(int value);
9366
9367 // Returns whether this string has only one-byte chars, i.e. all of them can
9368 // be one-byte encoded. This might be the case even if the string is
9369 // two-byte. Such strings may appear when the embedder prefers
9370 // two-byte external representations even for one-byte data.
9371 inline bool IsOneByteRepresentation() const;
9372 inline bool IsTwoByteRepresentation() const;
9373
9374 // Cons and slices have an encoding flag that may not represent the actual
9375 // encoding of the underlying string. This is taken into account here.
9376 // Requires: this->IsFlat()
9377 inline bool IsOneByteRepresentationUnderneath();
9378 inline bool IsTwoByteRepresentationUnderneath();
9379
9380 // NOTE: this should be considered only a hint. False negatives are
9381 // possible.
9382 inline bool HasOnlyOneByteChars();
9383
9384 // Get and set individual two byte chars in the string.
9385 inline void Set(int index, uint16_t value);
9386 // Get individual two byte char in the string. Repeated calls
9387 // to this method are not efficient unless the string is flat.
9388 INLINE(uint16_t Get(int index));
9389
9390 // ES6 section 7.1.3.1 ToNumber Applied to the String Type
9391 static Handle<Object> ToNumber(Handle<String> subject);
9392
9393 // Flattens the string. Checks first inline to see if it is
9394 // necessary. Does nothing if the string is not a cons string.
9395 // Flattening allocates a sequential string with the same data as
9396 // the given string and mutates the cons string to a degenerate
9397 // form, where the first component is the new sequential string and
9398 // the second component is the empty string. If allocation fails,
9399 // this function returns a failure. If flattening succeeds, this
9400 // function returns the sequential string that is now the first
9401 // component of the cons string.
9402 //
9403 // Degenerate cons strings are handled specially by the garbage
9404 // collector (see IsShortcutCandidate).
9405
9406 static inline Handle<String> Flatten(Handle<String> string,
9407 PretenureFlag pretenure = NOT_TENURED);
9408
9409 // Tries to return the content of a flat string as a structure holding either
9410 // a flat vector of char or of uc16.
9411 // If the string isn't flat, and therefore doesn't have flat content, the
9412 // returned structure will report so, and can't provide a vector of either
9413 // kind.
9414 FlatContent GetFlatContent();
9415
9416 // Returns the parent of a sliced string or first part of a flat cons string.
9417 // Requires: StringShape(this).IsIndirect() && this->IsFlat()
9418 inline String* GetUnderlying();
9419
9420 // String relational comparison, implemented according to ES6 section 7.2.11
9421 // Abstract Relational Comparison (step 5): The comparison of Strings uses a
9422 // simple lexicographic ordering on sequences of code unit values. There is no
9423 // attempt to use the more complex, semantically oriented definitions of
9424 // character or string equality and collating order defined in the Unicode
9425 // specification. Therefore String values that are canonically equal according
9426 // to the Unicode standard could test as unequal. In effect this algorithm
9427 // assumes that both Strings are already in normalized form. Also, note that
9428 // for strings containing supplementary characters, lexicographic ordering on
9429 // sequences of UTF-16 code unit values differs from that on sequences of code
9430 // point values.
9431 MUST_USE_RESULT static ComparisonResult Compare(Handle<String> x,
9432 Handle<String> y);
9433
9434 // Perform ES6 21.1.3.8, including checking arguments.
9435 static Object* IndexOf(Isolate* isolate, Handle<Object> receiver,
9436 Handle<Object> search, Handle<Object> position);
9437 // Perform string match of pattern on subject, starting at start index.
9438 // Caller must ensure that 0 <= start_index <= sub->length(), as this does not
9439 // check any arguments.
9440 static int IndexOf(Isolate* isolate, Handle<String> receiver,
9441 Handle<String> search, int start_index);
9442
9443 static Object* LastIndexOf(Isolate* isolate, Handle<Object> receiver,
9444 Handle<Object> search, Handle<Object> position);
9445
9446 // Encapsulates logic related to a match and its capture groups as required
9447 // by GetSubstitution.
9448 class Match {
9449 public:
9450 virtual Handle<String> GetMatch() = 0;
9451 virtual MaybeHandle<String> GetCapture(int i, bool* capture_exists) = 0;
9452 virtual Handle<String> GetPrefix() = 0;
9453 virtual Handle<String> GetSuffix() = 0;
9454 virtual int CaptureCount() = 0;
~Match()9455 virtual ~Match() {}
9456 };
9457
9458 // ES#sec-getsubstitution
9459 // GetSubstitution(matched, str, position, captures, replacement)
9460 // Expand the $-expressions in the string and return a new string with
9461 // the result.
9462 MUST_USE_RESULT static MaybeHandle<String> GetSubstitution(
9463 Isolate* isolate, Match* match, Handle<String> replacement);
9464
9465 // String equality operations.
9466 inline bool Equals(String* other);
9467 inline static bool Equals(Handle<String> one, Handle<String> two);
9468 bool IsUtf8EqualTo(Vector<const char> str, bool allow_prefix_match = false);
9469 bool IsOneByteEqualTo(Vector<const uint8_t> str);
9470 bool IsTwoByteEqualTo(Vector<const uc16> str);
9471
9472 // Return a UTF8 representation of the string. The string is null
9473 // terminated but may optionally contain nulls. Length is returned
9474 // in length_output if length_output is not a null pointer The string
9475 // should be nearly flat, otherwise the performance of this method may
9476 // be very slow (quadratic in the length). Setting robustness_flag to
9477 // ROBUST_STRING_TRAVERSAL invokes behaviour that is robust This means it
9478 // handles unexpected data without causing assert failures and it does not
9479 // do any heap allocations. This is useful when printing stack traces.
9480 std::unique_ptr<char[]> ToCString(AllowNullsFlag allow_nulls,
9481 RobustnessFlag robustness_flag, int offset,
9482 int length, int* length_output = 0);
9483 std::unique_ptr<char[]> ToCString(
9484 AllowNullsFlag allow_nulls = DISALLOW_NULLS,
9485 RobustnessFlag robustness_flag = FAST_STRING_TRAVERSAL,
9486 int* length_output = 0);
9487
9488 bool ComputeArrayIndex(uint32_t* index);
9489
9490 // Externalization.
9491 bool MakeExternal(v8::String::ExternalStringResource* resource);
9492 bool MakeExternal(v8::String::ExternalOneByteStringResource* resource);
9493
9494 // Conversion.
9495 inline bool AsArrayIndex(uint32_t* index);
9496 uint32_t inline ToValidIndex(Object* number);
9497
9498 // Trimming.
9499 enum TrimMode { kTrim, kTrimLeft, kTrimRight };
9500 static Handle<String> Trim(Handle<String> string, TrimMode mode);
9501
9502 DECLARE_CAST(String)
9503
9504 void PrintOn(FILE* out);
9505
9506 // For use during stack traces. Performs rudimentary sanity check.
9507 bool LooksValid();
9508
9509 // Dispatched behavior.
9510 void StringShortPrint(StringStream* accumulator, bool show_details = true);
9511 void PrintUC16(std::ostream& os, int start = 0, int end = -1); // NOLINT
9512 #if defined(DEBUG) || defined(OBJECT_PRINT)
9513 char* ToAsciiArray();
9514 #endif
9515 DECLARE_PRINTER(String)
9516 DECLARE_VERIFIER(String)
9517
9518 inline bool IsFlat();
9519
9520 // Layout description.
9521 static const int kLengthOffset = Name::kSize;
9522 static const int kSize = kLengthOffset + kPointerSize;
9523
9524 // Max char codes.
9525 static const int32_t kMaxOneByteCharCode = unibrow::Latin1::kMaxChar;
9526 static const uint32_t kMaxOneByteCharCodeU = unibrow::Latin1::kMaxChar;
9527 static const int kMaxUtf16CodeUnit = 0xffff;
9528 static const uint32_t kMaxUtf16CodeUnitU = kMaxUtf16CodeUnit;
9529 static const uc32 kMaxCodePoint = 0x10ffff;
9530
9531 // Maximal string length.
9532 static const int kMaxLength = (1 << 28) - 16;
9533
9534 // Max length for computing hash. For strings longer than this limit the
9535 // string length is used as the hash value.
9536 static const int kMaxHashCalcLength = 16383;
9537
9538 // Limit for truncation in short printing.
9539 static const int kMaxShortPrintLength = 1024;
9540
9541 // Support for regular expressions.
9542 const uc16* GetTwoByteData(unsigned start);
9543
9544 // Helper function for flattening strings.
9545 template <typename sinkchar>
9546 static void WriteToFlat(String* source,
9547 sinkchar* sink,
9548 int from,
9549 int to);
9550
9551 // The return value may point to the first aligned word containing the first
9552 // non-one-byte character, rather than directly to the non-one-byte character.
9553 // If the return value is >= the passed length, the entire string was
9554 // one-byte.
NonAsciiStart(const char * chars,int length)9555 static inline int NonAsciiStart(const char* chars, int length) {
9556 const char* start = chars;
9557 const char* limit = chars + length;
9558
9559 if (length >= kIntptrSize) {
9560 // Check unaligned bytes.
9561 while (!IsAligned(reinterpret_cast<intptr_t>(chars), sizeof(uintptr_t))) {
9562 if (static_cast<uint8_t>(*chars) > unibrow::Utf8::kMaxOneByteChar) {
9563 return static_cast<int>(chars - start);
9564 }
9565 ++chars;
9566 }
9567 // Check aligned words.
9568 DCHECK(unibrow::Utf8::kMaxOneByteChar == 0x7F);
9569 const uintptr_t non_one_byte_mask = kUintptrAllBitsSet / 0xFF * 0x80;
9570 while (chars + sizeof(uintptr_t) <= limit) {
9571 if (*reinterpret_cast<const uintptr_t*>(chars) & non_one_byte_mask) {
9572 return static_cast<int>(chars - start);
9573 }
9574 chars += sizeof(uintptr_t);
9575 }
9576 }
9577 // Check remaining unaligned bytes.
9578 while (chars < limit) {
9579 if (static_cast<uint8_t>(*chars) > unibrow::Utf8::kMaxOneByteChar) {
9580 return static_cast<int>(chars - start);
9581 }
9582 ++chars;
9583 }
9584
9585 return static_cast<int>(chars - start);
9586 }
9587
IsAscii(const char * chars,int length)9588 static inline bool IsAscii(const char* chars, int length) {
9589 return NonAsciiStart(chars, length) >= length;
9590 }
9591
IsAscii(const uint8_t * chars,int length)9592 static inline bool IsAscii(const uint8_t* chars, int length) {
9593 return
9594 NonAsciiStart(reinterpret_cast<const char*>(chars), length) >= length;
9595 }
9596
NonOneByteStart(const uc16 * chars,int length)9597 static inline int NonOneByteStart(const uc16* chars, int length) {
9598 const uc16* limit = chars + length;
9599 const uc16* start = chars;
9600 while (chars < limit) {
9601 if (*chars > kMaxOneByteCharCodeU) return static_cast<int>(chars - start);
9602 ++chars;
9603 }
9604 return static_cast<int>(chars - start);
9605 }
9606
IsOneByte(const uc16 * chars,int length)9607 static inline bool IsOneByte(const uc16* chars, int length) {
9608 return NonOneByteStart(chars, length) >= length;
9609 }
9610
9611 template<class Visitor>
9612 static inline ConsString* VisitFlat(Visitor* visitor,
9613 String* string,
9614 int offset = 0);
9615
9616 static Handle<FixedArray> CalculateLineEnds(Handle<String> string,
9617 bool include_ending_line);
9618
9619 // Use the hash field to forward to the canonical internalized string
9620 // when deserializing an internalized string.
9621 inline void SetForwardedInternalizedString(String* string);
9622 inline String* GetForwardedInternalizedString();
9623
9624 private:
9625 friend class Name;
9626 friend class StringTableInsertionKey;
9627
9628 static Handle<String> SlowFlatten(Handle<ConsString> cons,
9629 PretenureFlag tenure);
9630
9631 // Slow case of String::Equals. This implementation works on any strings
9632 // but it is most efficient on strings that are almost flat.
9633 bool SlowEquals(String* other);
9634
9635 static bool SlowEquals(Handle<String> one, Handle<String> two);
9636
9637 // Slow case of AsArrayIndex.
9638 V8_EXPORT_PRIVATE bool SlowAsArrayIndex(uint32_t* index);
9639
9640 // Compute and set the hash code.
9641 uint32_t ComputeAndSetHash();
9642
9643 DISALLOW_IMPLICIT_CONSTRUCTORS(String);
9644 };
9645
9646
9647 // The SeqString abstract class captures sequential string values.
9648 class SeqString: public String {
9649 public:
9650 DECLARE_CAST(SeqString)
9651
9652 // Layout description.
9653 static const int kHeaderSize = String::kSize;
9654
9655 // Truncate the string in-place if possible and return the result.
9656 // In case of new_length == 0, the empty string is returned without
9657 // truncating the original string.
9658 MUST_USE_RESULT static Handle<String> Truncate(Handle<SeqString> string,
9659 int new_length);
9660 private:
9661 DISALLOW_IMPLICIT_CONSTRUCTORS(SeqString);
9662 };
9663
9664
9665 // The OneByteString class captures sequential one-byte string objects.
9666 // Each character in the OneByteString is an one-byte character.
9667 class SeqOneByteString: public SeqString {
9668 public:
9669 static const bool kHasOneByteEncoding = true;
9670
9671 // Dispatched behavior.
9672 inline uint16_t SeqOneByteStringGet(int index);
9673 inline void SeqOneByteStringSet(int index, uint16_t value);
9674
9675 // Get the address of the characters in this string.
9676 inline Address GetCharsAddress();
9677
9678 inline uint8_t* GetChars();
9679
9680 DECLARE_CAST(SeqOneByteString)
9681
9682 // Garbage collection support. This method is called by the
9683 // garbage collector to compute the actual size of an OneByteString
9684 // instance.
9685 inline int SeqOneByteStringSize(InstanceType instance_type);
9686
9687 // Computes the size for an OneByteString instance of a given length.
SizeFor(int length)9688 static int SizeFor(int length) {
9689 return OBJECT_POINTER_ALIGN(kHeaderSize + length * kCharSize);
9690 }
9691
9692 // Maximal memory usage for a single sequential one-byte string.
9693 static const int kMaxSize = 512 * MB - 1;
9694 STATIC_ASSERT((kMaxSize - kHeaderSize) >= String::kMaxLength);
9695
9696 private:
9697 DISALLOW_IMPLICIT_CONSTRUCTORS(SeqOneByteString);
9698 };
9699
9700
9701 // The TwoByteString class captures sequential unicode string objects.
9702 // Each character in the TwoByteString is a two-byte uint16_t.
9703 class SeqTwoByteString: public SeqString {
9704 public:
9705 static const bool kHasOneByteEncoding = false;
9706
9707 // Dispatched behavior.
9708 inline uint16_t SeqTwoByteStringGet(int index);
9709 inline void SeqTwoByteStringSet(int index, uint16_t value);
9710
9711 // Get the address of the characters in this string.
9712 inline Address GetCharsAddress();
9713
9714 inline uc16* GetChars();
9715
9716 // For regexp code.
9717 const uint16_t* SeqTwoByteStringGetData(unsigned start);
9718
9719 DECLARE_CAST(SeqTwoByteString)
9720
9721 // Garbage collection support. This method is called by the
9722 // garbage collector to compute the actual size of a TwoByteString
9723 // instance.
9724 inline int SeqTwoByteStringSize(InstanceType instance_type);
9725
9726 // Computes the size for a TwoByteString instance of a given length.
SizeFor(int length)9727 static int SizeFor(int length) {
9728 return OBJECT_POINTER_ALIGN(kHeaderSize + length * kShortSize);
9729 }
9730
9731 // Maximal memory usage for a single sequential two-byte string.
9732 static const int kMaxSize = 512 * MB - 1;
9733 STATIC_ASSERT(static_cast<int>((kMaxSize - kHeaderSize)/sizeof(uint16_t)) >=
9734 String::kMaxLength);
9735
9736 private:
9737 DISALLOW_IMPLICIT_CONSTRUCTORS(SeqTwoByteString);
9738 };
9739
9740
9741 // The ConsString class describes string values built by using the
9742 // addition operator on strings. A ConsString is a pair where the
9743 // first and second components are pointers to other string values.
9744 // One or both components of a ConsString can be pointers to other
9745 // ConsStrings, creating a binary tree of ConsStrings where the leaves
9746 // are non-ConsString string values. The string value represented by
9747 // a ConsString can be obtained by concatenating the leaf string
9748 // values in a left-to-right depth-first traversal of the tree.
9749 class ConsString: public String {
9750 public:
9751 // First string of the cons cell.
9752 inline String* first();
9753 // Doesn't check that the result is a string, even in debug mode. This is
9754 // useful during GC where the mark bits confuse the checks.
9755 inline Object* unchecked_first();
9756 inline void set_first(String* first,
9757 WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
9758
9759 // Second string of the cons cell.
9760 inline String* second();
9761 // Doesn't check that the result is a string, even in debug mode. This is
9762 // useful during GC where the mark bits confuse the checks.
9763 inline Object* unchecked_second();
9764 inline void set_second(String* second,
9765 WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
9766
9767 // Dispatched behavior.
9768 V8_EXPORT_PRIVATE uint16_t ConsStringGet(int index);
9769
9770 DECLARE_CAST(ConsString)
9771
9772 // Layout description.
9773 static const int kFirstOffset = POINTER_SIZE_ALIGN(String::kSize);
9774 static const int kSecondOffset = kFirstOffset + kPointerSize;
9775 static const int kSize = kSecondOffset + kPointerSize;
9776
9777 // Minimum length for a cons string.
9778 static const int kMinLength = 13;
9779
9780 typedef FixedBodyDescriptor<kFirstOffset, kSecondOffset + kPointerSize, kSize>
9781 BodyDescriptor;
9782
9783 DECLARE_VERIFIER(ConsString)
9784
9785 private:
9786 DISALLOW_IMPLICIT_CONSTRUCTORS(ConsString);
9787 };
9788
9789 // The ThinString class describes string objects that are just references
9790 // to another string object. They are used for in-place internalization when
9791 // the original string cannot actually be internalized in-place: in these
9792 // cases, the original string is converted to a ThinString pointing at its
9793 // internalized version (which is allocated as a new object).
9794 // In terms of memory layout and most algorithms operating on strings,
9795 // ThinStrings can be thought of as "one-part cons strings".
9796 class ThinString : public String {
9797 public:
9798 // Actual string that this ThinString refers to.
9799 inline String* actual() const;
9800 inline void set_actual(String* s,
9801 WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
9802
9803 V8_EXPORT_PRIVATE uint16_t ThinStringGet(int index);
9804
9805 DECLARE_CAST(ThinString)
9806 DECLARE_VERIFIER(ThinString)
9807
9808 // Layout description.
9809 static const int kActualOffset = String::kSize;
9810 static const int kSize = kActualOffset + kPointerSize;
9811
9812 typedef FixedBodyDescriptor<kActualOffset, kSize, kSize> BodyDescriptor;
9813
9814 private:
9815 DISALLOW_COPY_AND_ASSIGN(ThinString);
9816 };
9817
9818 // The Sliced String class describes strings that are substrings of another
9819 // sequential string. The motivation is to save time and memory when creating
9820 // a substring. A Sliced String is described as a pointer to the parent,
9821 // the offset from the start of the parent string and the length. Using
9822 // a Sliced String therefore requires unpacking of the parent string and
9823 // adding the offset to the start address. A substring of a Sliced String
9824 // are not nested since the double indirection is simplified when creating
9825 // such a substring.
9826 // Currently missing features are:
9827 // - handling externalized parent strings
9828 // - external strings as parent
9829 // - truncating sliced string to enable otherwise unneeded parent to be GC'ed.
9830 class SlicedString: public String {
9831 public:
9832 inline String* parent();
9833 inline void set_parent(String* parent,
9834 WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
9835 inline int offset() const;
9836 inline void set_offset(int offset);
9837
9838 // Dispatched behavior.
9839 V8_EXPORT_PRIVATE uint16_t SlicedStringGet(int index);
9840
9841 DECLARE_CAST(SlicedString)
9842
9843 // Layout description.
9844 static const int kParentOffset = POINTER_SIZE_ALIGN(String::kSize);
9845 static const int kOffsetOffset = kParentOffset + kPointerSize;
9846 static const int kSize = kOffsetOffset + kPointerSize;
9847
9848 // Minimum length for a sliced string.
9849 static const int kMinLength = 13;
9850
9851 typedef FixedBodyDescriptor<kParentOffset,
9852 kOffsetOffset + kPointerSize, kSize>
9853 BodyDescriptor;
9854
9855 DECLARE_VERIFIER(SlicedString)
9856
9857 private:
9858 DISALLOW_IMPLICIT_CONSTRUCTORS(SlicedString);
9859 };
9860
9861
9862 // The ExternalString class describes string values that are backed by
9863 // a string resource that lies outside the V8 heap. ExternalStrings
9864 // consist of the length field common to all strings, a pointer to the
9865 // external resource. It is important to ensure (externally) that the
9866 // resource is not deallocated while the ExternalString is live in the
9867 // V8 heap.
9868 //
9869 // The API expects that all ExternalStrings are created through the
9870 // API. Therefore, ExternalStrings should not be used internally.
9871 class ExternalString: public String {
9872 public:
9873 DECLARE_CAST(ExternalString)
9874
9875 // Layout description.
9876 static const int kResourceOffset = POINTER_SIZE_ALIGN(String::kSize);
9877 static const int kShortSize = kResourceOffset + kPointerSize;
9878 static const int kResourceDataOffset = kResourceOffset + kPointerSize;
9879 static const int kSize = kResourceDataOffset + kPointerSize;
9880
9881 // Return whether external string is short (data pointer is not cached).
9882 inline bool is_short();
9883
9884 STATIC_ASSERT(kResourceOffset == Internals::kStringResourceOffset);
9885
9886 private:
9887 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalString);
9888 };
9889
9890
9891 // The ExternalOneByteString class is an external string backed by an
9892 // one-byte string.
9893 class ExternalOneByteString : public ExternalString {
9894 public:
9895 static const bool kHasOneByteEncoding = true;
9896
9897 typedef v8::String::ExternalOneByteStringResource Resource;
9898
9899 // The underlying resource.
9900 inline const Resource* resource();
9901 inline void set_resource(const Resource* buffer);
9902
9903 // Update the pointer cache to the external character array.
9904 // The cached pointer is always valid, as the external character array does =
9905 // not move during lifetime. Deserialization is the only exception, after
9906 // which the pointer cache has to be refreshed.
9907 inline void update_data_cache();
9908
9909 inline const uint8_t* GetChars();
9910
9911 // Dispatched behavior.
9912 inline uint16_t ExternalOneByteStringGet(int index);
9913
9914 DECLARE_CAST(ExternalOneByteString)
9915
9916 class BodyDescriptor;
9917
9918 private:
9919 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalOneByteString);
9920 };
9921
9922
9923 // The ExternalTwoByteString class is an external string backed by a UTF-16
9924 // encoded string.
9925 class ExternalTwoByteString: public ExternalString {
9926 public:
9927 static const bool kHasOneByteEncoding = false;
9928
9929 typedef v8::String::ExternalStringResource Resource;
9930
9931 // The underlying string resource.
9932 inline const Resource* resource();
9933 inline void set_resource(const Resource* buffer);
9934
9935 // Update the pointer cache to the external character array.
9936 // The cached pointer is always valid, as the external character array does =
9937 // not move during lifetime. Deserialization is the only exception, after
9938 // which the pointer cache has to be refreshed.
9939 inline void update_data_cache();
9940
9941 inline const uint16_t* GetChars();
9942
9943 // Dispatched behavior.
9944 inline uint16_t ExternalTwoByteStringGet(int index);
9945
9946 // For regexp code.
9947 inline const uint16_t* ExternalTwoByteStringGetData(unsigned start);
9948
9949 DECLARE_CAST(ExternalTwoByteString)
9950
9951 class BodyDescriptor;
9952
9953 private:
9954 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalTwoByteString);
9955 };
9956
9957
9958 // Utility superclass for stack-allocated objects that must be updated
9959 // on gc. It provides two ways for the gc to update instances, either
9960 // iterating or updating after gc.
9961 class Relocatable BASE_EMBEDDED {
9962 public:
9963 explicit inline Relocatable(Isolate* isolate);
9964 inline virtual ~Relocatable();
IterateInstance(ObjectVisitor * v)9965 virtual void IterateInstance(ObjectVisitor* v) { }
PostGarbageCollection()9966 virtual void PostGarbageCollection() { }
9967
9968 static void PostGarbageCollectionProcessing(Isolate* isolate);
9969 static int ArchiveSpacePerThread();
9970 static char* ArchiveState(Isolate* isolate, char* to);
9971 static char* RestoreState(Isolate* isolate, char* from);
9972 static void Iterate(Isolate* isolate, ObjectVisitor* v);
9973 static void Iterate(ObjectVisitor* v, Relocatable* top);
9974 static char* Iterate(ObjectVisitor* v, char* t);
9975
9976 private:
9977 Isolate* isolate_;
9978 Relocatable* prev_;
9979 };
9980
9981
9982 // A flat string reader provides random access to the contents of a
9983 // string independent of the character width of the string. The handle
9984 // must be valid as long as the reader is being used.
9985 class FlatStringReader : public Relocatable {
9986 public:
9987 FlatStringReader(Isolate* isolate, Handle<String> str);
9988 FlatStringReader(Isolate* isolate, Vector<const char> input);
9989 void PostGarbageCollection();
9990 inline uc32 Get(int index);
9991 template <typename Char>
9992 inline Char Get(int index);
length()9993 int length() { return length_; }
9994 private:
9995 String** str_;
9996 bool is_one_byte_;
9997 int length_;
9998 const void* start_;
9999 };
10000
10001
10002 // This maintains an off-stack representation of the stack frames required
10003 // to traverse a ConsString, allowing an entirely iterative and restartable
10004 // traversal of the entire string
10005 class ConsStringIterator {
10006 public:
ConsStringIterator()10007 inline ConsStringIterator() {}
10008 inline explicit ConsStringIterator(ConsString* cons_string, int offset = 0) {
10009 Reset(cons_string, offset);
10010 }
10011 inline void Reset(ConsString* cons_string, int offset = 0) {
10012 depth_ = 0;
10013 // Next will always return NULL.
10014 if (cons_string == NULL) return;
10015 Initialize(cons_string, offset);
10016 }
10017 // Returns NULL when complete.
Next(int * offset_out)10018 inline String* Next(int* offset_out) {
10019 *offset_out = 0;
10020 if (depth_ == 0) return NULL;
10021 return Continue(offset_out);
10022 }
10023
10024 private:
10025 static const int kStackSize = 32;
10026 // Use a mask instead of doing modulo operations for stack wrapping.
10027 static const int kDepthMask = kStackSize-1;
10028 STATIC_ASSERT(IS_POWER_OF_TWO(kStackSize));
10029 static inline int OffsetForDepth(int depth);
10030
10031 inline void PushLeft(ConsString* string);
10032 inline void PushRight(ConsString* string);
10033 inline void AdjustMaximumDepth();
10034 inline void Pop();
StackBlown()10035 inline bool StackBlown() { return maximum_depth_ - depth_ == kStackSize; }
10036 void Initialize(ConsString* cons_string, int offset);
10037 String* Continue(int* offset_out);
10038 String* NextLeaf(bool* blew_stack);
10039 String* Search(int* offset_out);
10040
10041 // Stack must always contain only frames for which right traversal
10042 // has not yet been performed.
10043 ConsString* frames_[kStackSize];
10044 ConsString* root_;
10045 int depth_;
10046 int maximum_depth_;
10047 int consumed_;
10048 DISALLOW_COPY_AND_ASSIGN(ConsStringIterator);
10049 };
10050
10051
10052 class StringCharacterStream {
10053 public:
10054 inline StringCharacterStream(String* string,
10055 int offset = 0);
10056 inline uint16_t GetNext();
10057 inline bool HasMore();
10058 inline void Reset(String* string, int offset = 0);
10059 inline void VisitOneByteString(const uint8_t* chars, int length);
10060 inline void VisitTwoByteString(const uint16_t* chars, int length);
10061
10062 private:
10063 ConsStringIterator iter_;
10064 bool is_one_byte_;
10065 union {
10066 const uint8_t* buffer8_;
10067 const uint16_t* buffer16_;
10068 };
10069 const uint8_t* end_;
10070 DISALLOW_COPY_AND_ASSIGN(StringCharacterStream);
10071 };
10072
10073
10074 template <typename T>
10075 class VectorIterator {
10076 public:
VectorIterator(T * d,int l)10077 VectorIterator(T* d, int l) : data_(Vector<const T>(d, l)), index_(0) { }
VectorIterator(Vector<const T> data)10078 explicit VectorIterator(Vector<const T> data) : data_(data), index_(0) { }
GetNext()10079 T GetNext() { return data_[index_++]; }
has_more()10080 bool has_more() { return index_ < data_.length(); }
10081 private:
10082 Vector<const T> data_;
10083 int index_;
10084 };
10085
10086
10087 // The Oddball describes objects null, undefined, true, and false.
10088 class Oddball: public HeapObject {
10089 public:
10090 // [to_number_raw]: Cached raw to_number computed at startup.
10091 inline double to_number_raw() const;
10092 inline void set_to_number_raw(double value);
10093
10094 // [to_string]: Cached to_string computed at startup.
10095 DECL_ACCESSORS(to_string, String)
10096
10097 // [to_number]: Cached to_number computed at startup.
10098 DECL_ACCESSORS(to_number, Object)
10099
10100 // [typeof]: Cached type_of computed at startup.
10101 DECL_ACCESSORS(type_of, String)
10102
10103 inline byte kind() const;
10104 inline void set_kind(byte kind);
10105
10106 // ES6 section 7.1.3 ToNumber for Boolean, Null, Undefined.
10107 MUST_USE_RESULT static inline Handle<Object> ToNumber(Handle<Oddball> input);
10108
10109 DECLARE_CAST(Oddball)
10110
10111 // Dispatched behavior.
10112 DECLARE_VERIFIER(Oddball)
10113
10114 // Initialize the fields.
10115 static void Initialize(Isolate* isolate, Handle<Oddball> oddball,
10116 const char* to_string, Handle<Object> to_number,
10117 const char* type_of, byte kind);
10118
10119 // Layout description.
10120 static const int kToNumberRawOffset = HeapObject::kHeaderSize;
10121 static const int kToStringOffset = kToNumberRawOffset + kDoubleSize;
10122 static const int kToNumberOffset = kToStringOffset + kPointerSize;
10123 static const int kTypeOfOffset = kToNumberOffset + kPointerSize;
10124 static const int kKindOffset = kTypeOfOffset + kPointerSize;
10125 static const int kSize = kKindOffset + kPointerSize;
10126
10127 static const byte kFalse = 0;
10128 static const byte kTrue = 1;
10129 static const byte kNotBooleanMask = ~1;
10130 static const byte kTheHole = 2;
10131 static const byte kNull = 3;
10132 static const byte kArgumentsMarker = 4;
10133 static const byte kUndefined = 5;
10134 static const byte kUninitialized = 6;
10135 static const byte kOther = 7;
10136 static const byte kException = 8;
10137 static const byte kOptimizedOut = 9;
10138 static const byte kStaleRegister = 10;
10139
10140 typedef FixedBodyDescriptor<kToStringOffset, kTypeOfOffset + kPointerSize,
10141 kSize> BodyDescriptor;
10142
10143 STATIC_ASSERT(kToNumberRawOffset == HeapNumber::kValueOffset);
10144 STATIC_ASSERT(kKindOffset == Internals::kOddballKindOffset);
10145 STATIC_ASSERT(kNull == Internals::kNullOddballKind);
10146 STATIC_ASSERT(kUndefined == Internals::kUndefinedOddballKind);
10147
10148 private:
10149 DISALLOW_IMPLICIT_CONSTRUCTORS(Oddball);
10150 };
10151
10152
10153 class Cell: public HeapObject {
10154 public:
10155 // [value]: value of the cell.
DECL_ACCESSORS(value,Object)10156 DECL_ACCESSORS(value, Object)
10157
10158 DECLARE_CAST(Cell)
10159
10160 static inline Cell* FromValueAddress(Address value) {
10161 Object* result = FromAddress(value - kValueOffset);
10162 return static_cast<Cell*>(result);
10163 }
10164
ValueAddress()10165 inline Address ValueAddress() {
10166 return address() + kValueOffset;
10167 }
10168
10169 // Dispatched behavior.
10170 DECLARE_PRINTER(Cell)
10171 DECLARE_VERIFIER(Cell)
10172
10173 // Layout description.
10174 static const int kValueOffset = HeapObject::kHeaderSize;
10175 static const int kSize = kValueOffset + kPointerSize;
10176
10177 typedef FixedBodyDescriptor<kValueOffset,
10178 kValueOffset + kPointerSize,
10179 kSize> BodyDescriptor;
10180
10181 private:
10182 DISALLOW_IMPLICIT_CONSTRUCTORS(Cell);
10183 };
10184
10185
10186 class PropertyCell : public HeapObject {
10187 public:
10188 // [property_details]: details of the global property.
10189 DECL_ACCESSORS(property_details_raw, Object)
10190 // [value]: value of the global property.
10191 DECL_ACCESSORS(value, Object)
10192 // [dependent_code]: dependent code that depends on the type of the global
10193 // property.
10194 DECL_ACCESSORS(dependent_code, DependentCode)
10195
10196 inline PropertyDetails property_details();
10197 inline void set_property_details(PropertyDetails details);
10198
10199 PropertyCellConstantType GetConstantType();
10200
10201 // Computes the new type of the cell's contents for the given value, but
10202 // without actually modifying the details.
10203 static PropertyCellType UpdatedType(Handle<PropertyCell> cell,
10204 Handle<Object> value,
10205 PropertyDetails details);
10206 // Prepares property cell at given entry for receiving given value.
10207 // As a result the old cell could be invalidated and/or dependent code could
10208 // be deoptimized. Returns the prepared property cell.
10209 static Handle<PropertyCell> PrepareForValue(
10210 Handle<GlobalDictionary> dictionary, int entry, Handle<Object> value,
10211 PropertyDetails details);
10212
10213 static Handle<PropertyCell> InvalidateEntry(
10214 Handle<GlobalDictionary> dictionary, int entry);
10215
10216 static void SetValueWithInvalidation(Handle<PropertyCell> cell,
10217 Handle<Object> new_value);
10218
10219 DECLARE_CAST(PropertyCell)
10220
10221 // Dispatched behavior.
10222 DECLARE_PRINTER(PropertyCell)
10223 DECLARE_VERIFIER(PropertyCell)
10224
10225 // Layout description.
10226 static const int kDetailsOffset = HeapObject::kHeaderSize;
10227 static const int kValueOffset = kDetailsOffset + kPointerSize;
10228 static const int kDependentCodeOffset = kValueOffset + kPointerSize;
10229 static const int kSize = kDependentCodeOffset + kPointerSize;
10230
10231 typedef FixedBodyDescriptor<kValueOffset,
10232 kSize,
10233 kSize> BodyDescriptor;
10234
10235 private:
10236 DISALLOW_IMPLICIT_CONSTRUCTORS(PropertyCell);
10237 };
10238
10239
10240 class WeakCell : public HeapObject {
10241 public:
10242 inline Object* value() const;
10243
10244 // This should not be called by anyone except GC.
10245 inline void clear();
10246
10247 // This should not be called by anyone except allocator.
10248 inline void initialize(HeapObject* value);
10249
10250 inline bool cleared() const;
10251
10252 DECL_ACCESSORS(next, Object)
10253
10254 inline void clear_next(Object* the_hole_value);
10255
10256 inline bool next_cleared();
10257
10258 DECLARE_CAST(WeakCell)
10259
10260 DECLARE_PRINTER(WeakCell)
10261 DECLARE_VERIFIER(WeakCell)
10262
10263 // Layout description.
10264 static const int kValueOffset = HeapObject::kHeaderSize;
10265 static const int kNextOffset = kValueOffset + kPointerSize;
10266 static const int kSize = kNextOffset + kPointerSize;
10267
10268 typedef FixedBodyDescriptor<kValueOffset, kSize, kSize> BodyDescriptor;
10269
10270 private:
10271 DISALLOW_IMPLICIT_CONSTRUCTORS(WeakCell);
10272 };
10273
10274
10275 // The JSProxy describes EcmaScript Harmony proxies
10276 class JSProxy: public JSReceiver {
10277 public:
10278 MUST_USE_RESULT static MaybeHandle<JSProxy> New(Isolate* isolate,
10279 Handle<Object>,
10280 Handle<Object>);
10281
10282 // [handler]: The handler property.
10283 DECL_ACCESSORS(handler, Object)
10284 // [target]: The target property.
10285 DECL_ACCESSORS(target, JSReceiver)
10286 // [hash]: The hash code property (undefined if not initialized yet).
10287 DECL_ACCESSORS(hash, Object)
10288
10289 static MaybeHandle<Context> GetFunctionRealm(Handle<JSProxy> proxy);
10290
10291 DECLARE_CAST(JSProxy)
10292
10293 INLINE(bool IsRevoked() const);
10294 static void Revoke(Handle<JSProxy> proxy);
10295
10296 // ES6 9.5.1
10297 static MaybeHandle<Object> GetPrototype(Handle<JSProxy> receiver);
10298
10299 // ES6 9.5.2
10300 MUST_USE_RESULT static Maybe<bool> SetPrototype(Handle<JSProxy> proxy,
10301 Handle<Object> value,
10302 bool from_javascript,
10303 ShouldThrow should_throw);
10304 // ES6 9.5.3
10305 MUST_USE_RESULT static Maybe<bool> IsExtensible(Handle<JSProxy> proxy);
10306
10307 // ES6 9.5.4 (when passed DONT_THROW)
10308 MUST_USE_RESULT static Maybe<bool> PreventExtensions(
10309 Handle<JSProxy> proxy, ShouldThrow should_throw);
10310
10311 // ES6 9.5.5
10312 MUST_USE_RESULT static Maybe<bool> GetOwnPropertyDescriptor(
10313 Isolate* isolate, Handle<JSProxy> proxy, Handle<Name> name,
10314 PropertyDescriptor* desc);
10315
10316 // ES6 9.5.6
10317 MUST_USE_RESULT static Maybe<bool> DefineOwnProperty(
10318 Isolate* isolate, Handle<JSProxy> object, Handle<Object> key,
10319 PropertyDescriptor* desc, ShouldThrow should_throw);
10320
10321 // ES6 9.5.7
10322 MUST_USE_RESULT static Maybe<bool> HasProperty(Isolate* isolate,
10323 Handle<JSProxy> proxy,
10324 Handle<Name> name);
10325
10326 // ES6 9.5.8
10327 MUST_USE_RESULT static MaybeHandle<Object> GetProperty(
10328 Isolate* isolate, Handle<JSProxy> proxy, Handle<Name> name,
10329 Handle<Object> receiver, bool* was_found);
10330
10331 // ES6 9.5.9
10332 MUST_USE_RESULT static Maybe<bool> SetProperty(Handle<JSProxy> proxy,
10333 Handle<Name> name,
10334 Handle<Object> value,
10335 Handle<Object> receiver,
10336 LanguageMode language_mode);
10337
10338 // ES6 9.5.10 (when passed SLOPPY)
10339 MUST_USE_RESULT static Maybe<bool> DeletePropertyOrElement(
10340 Handle<JSProxy> proxy, Handle<Name> name, LanguageMode language_mode);
10341
10342 // ES6 9.5.12
10343 MUST_USE_RESULT static Maybe<bool> OwnPropertyKeys(
10344 Isolate* isolate, Handle<JSReceiver> receiver, Handle<JSProxy> proxy,
10345 PropertyFilter filter, KeyAccumulator* accumulator);
10346
10347 MUST_USE_RESULT static Maybe<PropertyAttributes> GetPropertyAttributes(
10348 LookupIterator* it);
10349
10350 // Dispatched behavior.
10351 DECLARE_PRINTER(JSProxy)
10352 DECLARE_VERIFIER(JSProxy)
10353
10354 // Layout description.
10355 static const int kTargetOffset = JSReceiver::kHeaderSize;
10356 static const int kHandlerOffset = kTargetOffset + kPointerSize;
10357 static const int kHashOffset = kHandlerOffset + kPointerSize;
10358 static const int kSize = kHashOffset + kPointerSize;
10359
10360 typedef FixedBodyDescriptor<JSReceiver::kPropertiesOffset, kSize, kSize>
10361 BodyDescriptor;
10362
10363 static Object* GetIdentityHash(Handle<JSProxy> receiver);
10364
10365 static Smi* GetOrCreateIdentityHash(Isolate* isolate, Handle<JSProxy> proxy);
10366
10367 static Maybe<bool> SetPrivateProperty(Isolate* isolate, Handle<JSProxy> proxy,
10368 Handle<Symbol> private_name,
10369 PropertyDescriptor* desc,
10370 ShouldThrow should_throw);
10371
10372 private:
10373 DISALLOW_IMPLICIT_CONSTRUCTORS(JSProxy);
10374 };
10375
10376
10377 class JSCollection : public JSObject {
10378 public:
10379 // [table]: the backing hash table
10380 DECL_ACCESSORS(table, Object)
10381
10382 static const int kTableOffset = JSObject::kHeaderSize;
10383 static const int kSize = kTableOffset + kPointerSize;
10384
10385 private:
10386 DISALLOW_IMPLICIT_CONSTRUCTORS(JSCollection);
10387 };
10388
10389
10390 // The JSSet describes EcmaScript Harmony sets
10391 class JSSet : public JSCollection {
10392 public:
10393 DECLARE_CAST(JSSet)
10394
10395 static void Initialize(Handle<JSSet> set, Isolate* isolate);
10396 static void Clear(Handle<JSSet> set);
10397
10398 // Dispatched behavior.
10399 DECLARE_PRINTER(JSSet)
10400 DECLARE_VERIFIER(JSSet)
10401
10402 private:
10403 DISALLOW_IMPLICIT_CONSTRUCTORS(JSSet);
10404 };
10405
10406
10407 // The JSMap describes EcmaScript Harmony maps
10408 class JSMap : public JSCollection {
10409 public:
10410 DECLARE_CAST(JSMap)
10411
10412 static void Initialize(Handle<JSMap> map, Isolate* isolate);
10413 static void Clear(Handle<JSMap> map);
10414
10415 // Dispatched behavior.
10416 DECLARE_PRINTER(JSMap)
10417 DECLARE_VERIFIER(JSMap)
10418
10419 private:
10420 DISALLOW_IMPLICIT_CONSTRUCTORS(JSMap);
10421 };
10422
10423 class JSArrayIterator : public JSObject {
10424 public:
10425 DECLARE_PRINTER(JSArrayIterator)
10426 DECLARE_VERIFIER(JSArrayIterator)
10427
10428 DECLARE_CAST(JSArrayIterator)
10429
10430 // [object]: the [[IteratedObject]] internal field.
10431 DECL_ACCESSORS(object, Object)
10432
10433 // [index]: The [[ArrayIteratorNextIndex]] internal field.
10434 DECL_ACCESSORS(index, Object)
10435
10436 // [map]: The Map of the [[IteratedObject]] field at the time the iterator is
10437 // allocated.
10438 DECL_ACCESSORS(object_map, Object)
10439
10440 // Return the ElementsKind that a JSArrayIterator's [[IteratedObject]] is
10441 // expected to have, based on its instance type.
10442 static ElementsKind ElementsKindForInstanceType(InstanceType instance_type);
10443
10444 static const int kIteratedObjectOffset = JSObject::kHeaderSize;
10445 static const int kNextIndexOffset = kIteratedObjectOffset + kPointerSize;
10446 static const int kIteratedObjectMapOffset = kNextIndexOffset + kPointerSize;
10447 static const int kSize = kIteratedObjectMapOffset + kPointerSize;
10448
10449 private:
10450 DISALLOW_IMPLICIT_CONSTRUCTORS(JSArrayIterator);
10451 };
10452
10453 // The [Async-from-Sync Iterator] object
10454 // (proposal-async-iteration/#sec-async-from-sync-iterator-objects)
10455 // An object which wraps an ordinary Iterator and converts it to behave
10456 // according to the Async Iterator protocol.
10457 // (See https://tc39.github.io/proposal-async-iteration/#sec-iteration)
10458 class JSAsyncFromSyncIterator : public JSObject {
10459 public:
10460 DECLARE_CAST(JSAsyncFromSyncIterator)
10461 DECLARE_PRINTER(JSAsyncFromSyncIterator)
10462 DECLARE_VERIFIER(JSAsyncFromSyncIterator)
10463
10464 // Async-from-Sync Iterator instances are ordinary objects that inherit
10465 // properties from the %AsyncFromSyncIteratorPrototype% intrinsic object.
10466 // Async-from-Sync Iterator instances are initially created with the internal
10467 // slots listed in Table 4.
10468 // (proposal-async-iteration/#table-async-from-sync-iterator-internal-slots)
10469 DECL_ACCESSORS(sync_iterator, JSReceiver)
10470
10471 // Offsets of object fields.
10472 static const int kSyncIteratorOffset = JSObject::kHeaderSize;
10473 static const int kSize = kSyncIteratorOffset + kPointerSize;
10474
10475 private:
10476 DISALLOW_IMPLICIT_CONSTRUCTORS(JSAsyncFromSyncIterator);
10477 };
10478
10479 class JSStringIterator : public JSObject {
10480 public:
10481 // Dispatched behavior.
10482 DECLARE_PRINTER(JSStringIterator)
10483 DECLARE_VERIFIER(JSStringIterator)
10484
10485 DECLARE_CAST(JSStringIterator)
10486
10487 // [string]: the [[IteratedString]] internal field.
10488 DECL_ACCESSORS(string, String)
10489
10490 // [index]: The [[StringIteratorNextIndex]] internal field.
10491 inline int index() const;
10492 inline void set_index(int value);
10493
10494 static const int kStringOffset = JSObject::kHeaderSize;
10495 static const int kNextIndexOffset = kStringOffset + kPointerSize;
10496 static const int kSize = kNextIndexOffset + kPointerSize;
10497
10498 private:
10499 DISALLOW_IMPLICIT_CONSTRUCTORS(JSStringIterator);
10500 };
10501
10502 // OrderedHashTableIterator is an iterator that iterates over the keys and
10503 // values of an OrderedHashTable.
10504 //
10505 // The iterator has a reference to the underlying OrderedHashTable data,
10506 // [table], as well as the current [index] the iterator is at.
10507 //
10508 // When the OrderedHashTable is rehashed it adds a reference from the old table
10509 // to the new table as well as storing enough data about the changes so that the
10510 // iterator [index] can be adjusted accordingly.
10511 //
10512 // When the [Next] result from the iterator is requested, the iterator checks if
10513 // there is a newer table that it needs to transition to.
10514 template<class Derived, class TableType>
10515 class OrderedHashTableIterator: public JSObject {
10516 public:
10517 // [table]: the backing hash table mapping keys to values.
10518 DECL_ACCESSORS(table, Object)
10519
10520 // [index]: The index into the data table.
10521 DECL_ACCESSORS(index, Object)
10522
10523 // [kind]: The kind of iteration this is. One of the [Kind] enum values.
10524 DECL_ACCESSORS(kind, Object)
10525
10526 #ifdef OBJECT_PRINT
10527 void OrderedHashTableIteratorPrint(std::ostream& os); // NOLINT
10528 #endif
10529
10530 static const int kTableOffset = JSObject::kHeaderSize;
10531 static const int kIndexOffset = kTableOffset + kPointerSize;
10532 static const int kKindOffset = kIndexOffset + kPointerSize;
10533 static const int kSize = kKindOffset + kPointerSize;
10534
10535 enum Kind {
10536 kKindKeys = 1,
10537 kKindValues = 2,
10538 kKindEntries = 3
10539 };
10540
10541 // Whether the iterator has more elements. This needs to be called before
10542 // calling |CurrentKey| and/or |CurrentValue|.
10543 bool HasMore();
10544
10545 // Move the index forward one.
MoveNext()10546 void MoveNext() {
10547 set_index(Smi::FromInt(Smi::cast(index())->value() + 1));
10548 }
10549
10550 // Populates the array with the next key and value and then moves the iterator
10551 // forward.
10552 // This returns the |kind| or 0 if the iterator is already at the end.
10553 Smi* Next(JSArray* value_array);
10554
10555 // Returns the current key of the iterator. This should only be called when
10556 // |HasMore| returns true.
10557 inline Object* CurrentKey();
10558
10559 private:
10560 // Transitions the iterator to the non obsolete backing store. This is a NOP
10561 // if the [table] is not obsolete.
10562 void Transition();
10563
10564 DISALLOW_IMPLICIT_CONSTRUCTORS(OrderedHashTableIterator);
10565 };
10566
10567
10568 class JSSetIterator: public OrderedHashTableIterator<JSSetIterator,
10569 OrderedHashSet> {
10570 public:
10571 // Dispatched behavior.
10572 DECLARE_PRINTER(JSSetIterator)
10573 DECLARE_VERIFIER(JSSetIterator)
10574
10575 DECLARE_CAST(JSSetIterator)
10576
10577 // Called by |Next| to populate the array. This allows the subclasses to
10578 // populate the array differently.
10579 inline void PopulateValueArray(FixedArray* array);
10580
10581 private:
10582 DISALLOW_IMPLICIT_CONSTRUCTORS(JSSetIterator);
10583 };
10584
10585
10586 class JSMapIterator: public OrderedHashTableIterator<JSMapIterator,
10587 OrderedHashMap> {
10588 public:
10589 // Dispatched behavior.
10590 DECLARE_PRINTER(JSMapIterator)
10591 DECLARE_VERIFIER(JSMapIterator)
10592
10593 DECLARE_CAST(JSMapIterator)
10594
10595 // Called by |Next| to populate the array. This allows the subclasses to
10596 // populate the array differently.
10597 inline void PopulateValueArray(FixedArray* array);
10598
10599 private:
10600 // Returns the current value of the iterator. This should only be called when
10601 // |HasMore| returns true.
10602 inline Object* CurrentValue();
10603
10604 DISALLOW_IMPLICIT_CONSTRUCTORS(JSMapIterator);
10605 };
10606
10607
10608 // Base class for both JSWeakMap and JSWeakSet
10609 class JSWeakCollection: public JSObject {
10610 public:
10611 DECLARE_CAST(JSWeakCollection)
10612
10613 // [table]: the backing hash table mapping keys to values.
10614 DECL_ACCESSORS(table, Object)
10615
10616 // [next]: linked list of encountered weak maps during GC.
10617 DECL_ACCESSORS(next, Object)
10618
10619 static void Initialize(Handle<JSWeakCollection> collection, Isolate* isolate);
10620 static void Set(Handle<JSWeakCollection> collection, Handle<Object> key,
10621 Handle<Object> value, int32_t hash);
10622 static bool Delete(Handle<JSWeakCollection> collection, Handle<Object> key,
10623 int32_t hash);
10624 static Handle<JSArray> GetEntries(Handle<JSWeakCollection> holder,
10625 int max_entries);
10626
10627 static const int kTableOffset = JSObject::kHeaderSize;
10628 static const int kNextOffset = kTableOffset + kPointerSize;
10629 static const int kSize = kNextOffset + kPointerSize;
10630
10631 // Visiting policy defines whether the table and next collection fields
10632 // should be visited or not.
10633 enum BodyVisitingPolicy { kVisitStrong, kVisitWeak };
10634
10635 // Iterates the function object according to the visiting policy.
10636 template <BodyVisitingPolicy>
10637 class BodyDescriptorImpl;
10638
10639 // Visit the whole object.
10640 typedef BodyDescriptorImpl<kVisitStrong> BodyDescriptor;
10641
10642 // Don't visit table and next collection fields.
10643 typedef BodyDescriptorImpl<kVisitWeak> BodyDescriptorWeak;
10644
10645 private:
10646 DISALLOW_IMPLICIT_CONSTRUCTORS(JSWeakCollection);
10647 };
10648
10649
10650 // The JSWeakMap describes EcmaScript Harmony weak maps
10651 class JSWeakMap: public JSWeakCollection {
10652 public:
10653 DECLARE_CAST(JSWeakMap)
10654
10655 // Dispatched behavior.
10656 DECLARE_PRINTER(JSWeakMap)
10657 DECLARE_VERIFIER(JSWeakMap)
10658
10659 private:
10660 DISALLOW_IMPLICIT_CONSTRUCTORS(JSWeakMap);
10661 };
10662
10663
10664 // The JSWeakSet describes EcmaScript Harmony weak sets
10665 class JSWeakSet: public JSWeakCollection {
10666 public:
10667 DECLARE_CAST(JSWeakSet)
10668
10669 // Dispatched behavior.
10670 DECLARE_PRINTER(JSWeakSet)
10671 DECLARE_VERIFIER(JSWeakSet)
10672
10673 private:
10674 DISALLOW_IMPLICIT_CONSTRUCTORS(JSWeakSet);
10675 };
10676
10677
10678 // Whether a JSArrayBuffer is a SharedArrayBuffer or not.
10679 enum class SharedFlag { kNotShared, kShared };
10680
10681
10682 class JSArrayBuffer: public JSObject {
10683 public:
10684 // [backing_store]: backing memory for this array
10685 DECL_ACCESSORS(backing_store, void)
10686
10687 // [byte_length]: length in bytes
10688 DECL_ACCESSORS(byte_length, Object)
10689
10690 inline uint32_t bit_field() const;
10691 inline void set_bit_field(uint32_t bits);
10692
10693 inline bool is_external();
10694 inline void set_is_external(bool value);
10695
10696 inline bool is_neuterable();
10697 inline void set_is_neuterable(bool value);
10698
10699 inline bool was_neutered();
10700 inline void set_was_neutered(bool value);
10701
10702 inline bool is_shared();
10703 inline void set_is_shared(bool value);
10704
10705 inline bool has_guard_region();
10706 inline void set_has_guard_region(bool value);
10707
10708 DECLARE_CAST(JSArrayBuffer)
10709
10710 void Neuter();
10711
10712 V8_EXPORT_PRIVATE static void Setup(
10713 Handle<JSArrayBuffer> array_buffer, Isolate* isolate, bool is_external,
10714 void* data, size_t allocated_length,
10715 SharedFlag shared = SharedFlag::kNotShared);
10716
10717 // Returns false if array buffer contents could not be allocated.
10718 // In this case, |array_buffer| will not be set up.
10719 static bool SetupAllocatingData(
10720 Handle<JSArrayBuffer> array_buffer, Isolate* isolate,
10721 size_t allocated_length, bool initialize = true,
10722 SharedFlag shared = SharedFlag::kNotShared) WARN_UNUSED_RESULT;
10723
10724 // Dispatched behavior.
10725 DECLARE_PRINTER(JSArrayBuffer)
10726 DECLARE_VERIFIER(JSArrayBuffer)
10727
10728 static const int kByteLengthOffset = JSObject::kHeaderSize;
10729 static const int kBackingStoreOffset = kByteLengthOffset + kPointerSize;
10730 static const int kBitFieldSlot = kBackingStoreOffset + kPointerSize;
10731 #if V8_TARGET_LITTLE_ENDIAN || !V8_HOST_ARCH_64_BIT
10732 static const int kBitFieldOffset = kBitFieldSlot;
10733 #else
10734 static const int kBitFieldOffset = kBitFieldSlot + kIntSize;
10735 #endif
10736 static const int kSize = kBitFieldSlot + kPointerSize;
10737
10738 static const int kSizeWithInternalFields =
10739 kSize + v8::ArrayBuffer::kInternalFieldCount * kPointerSize;
10740
10741 // Iterates all fields in the object including internal ones except
10742 // kBackingStoreOffset and kBitFieldSlot.
10743 class BodyDescriptor;
10744
10745 class IsExternal : public BitField<bool, 1, 1> {};
10746 class IsNeuterable : public BitField<bool, 2, 1> {};
10747 class WasNeutered : public BitField<bool, 3, 1> {};
10748 class IsShared : public BitField<bool, 4, 1> {};
10749 class HasGuardRegion : public BitField<bool, 5, 1> {};
10750
10751 private:
10752 DISALLOW_IMPLICIT_CONSTRUCTORS(JSArrayBuffer);
10753 };
10754
10755
10756 class JSArrayBufferView: public JSObject {
10757 public:
10758 // [buffer]: ArrayBuffer that this typed array views.
10759 DECL_ACCESSORS(buffer, Object)
10760
10761 // [byte_offset]: offset of typed array in bytes.
10762 DECL_ACCESSORS(byte_offset, Object)
10763
10764 // [byte_length]: length of typed array in bytes.
10765 DECL_ACCESSORS(byte_length, Object)
10766
10767 DECLARE_CAST(JSArrayBufferView)
10768
10769 DECLARE_VERIFIER(JSArrayBufferView)
10770
10771 inline bool WasNeutered() const;
10772
10773 static const int kBufferOffset = JSObject::kHeaderSize;
10774 static const int kByteOffsetOffset = kBufferOffset + kPointerSize;
10775 static const int kByteLengthOffset = kByteOffsetOffset + kPointerSize;
10776 static const int kViewSize = kByteLengthOffset + kPointerSize;
10777
10778 private:
10779 #ifdef VERIFY_HEAP
10780 DECL_ACCESSORS(raw_byte_offset, Object)
10781 DECL_ACCESSORS(raw_byte_length, Object)
10782 #endif
10783
10784 DISALLOW_IMPLICIT_CONSTRUCTORS(JSArrayBufferView);
10785 };
10786
10787
10788 class JSTypedArray: public JSArrayBufferView {
10789 public:
10790 // [length]: length of typed array in elements.
10791 DECL_ACCESSORS(length, Object)
10792 inline uint32_t length_value() const;
10793
10794 // ES6 9.4.5.3
10795 MUST_USE_RESULT static Maybe<bool> DefineOwnProperty(
10796 Isolate* isolate, Handle<JSTypedArray> o, Handle<Object> key,
10797 PropertyDescriptor* desc, ShouldThrow should_throw);
10798
10799 DECLARE_CAST(JSTypedArray)
10800
10801 ExternalArrayType type();
10802 V8_EXPORT_PRIVATE size_t element_size();
10803
10804 Handle<JSArrayBuffer> GetBuffer();
10805
10806 static inline MaybeHandle<JSTypedArray> Validate(Isolate* isolate,
10807 Handle<Object> receiver,
10808 const char* method_name);
10809
10810 // Dispatched behavior.
10811 DECLARE_PRINTER(JSTypedArray)
10812 DECLARE_VERIFIER(JSTypedArray)
10813
10814 static const int kLengthOffset = kViewSize + kPointerSize;
10815 static const int kSize = kLengthOffset + kPointerSize;
10816
10817 static const int kSizeWithInternalFields =
10818 kSize + v8::ArrayBufferView::kInternalFieldCount * kPointerSize;
10819
10820 private:
10821 static Handle<JSArrayBuffer> MaterializeArrayBuffer(
10822 Handle<JSTypedArray> typed_array);
10823 #ifdef VERIFY_HEAP
10824 DECL_ACCESSORS(raw_length, Object)
10825 #endif
10826
10827 DISALLOW_IMPLICIT_CONSTRUCTORS(JSTypedArray);
10828 };
10829
10830
10831 class JSDataView: public JSArrayBufferView {
10832 public:
10833 DECLARE_CAST(JSDataView)
10834
10835 // Dispatched behavior.
10836 DECLARE_PRINTER(JSDataView)
10837 DECLARE_VERIFIER(JSDataView)
10838
10839 static const int kSize = kViewSize;
10840
10841 static const int kSizeWithInternalFields =
10842 kSize + v8::ArrayBufferView::kInternalFieldCount * kPointerSize;
10843
10844 private:
10845 DISALLOW_IMPLICIT_CONSTRUCTORS(JSDataView);
10846 };
10847
10848
10849 // Foreign describes objects pointing from JavaScript to C structures.
10850 class Foreign: public HeapObject {
10851 public:
10852 // [address]: field containing the address.
10853 inline Address foreign_address();
10854 inline void set_foreign_address(Address value);
10855
10856 DECLARE_CAST(Foreign)
10857
10858 // Dispatched behavior.
10859 DECLARE_PRINTER(Foreign)
10860 DECLARE_VERIFIER(Foreign)
10861
10862 // Layout description.
10863
10864 static const int kForeignAddressOffset = HeapObject::kHeaderSize;
10865 static const int kSize = kForeignAddressOffset + kPointerSize;
10866
10867 STATIC_ASSERT(kForeignAddressOffset == Internals::kForeignAddressOffset);
10868
10869 class BodyDescriptor;
10870
10871 private:
10872 DISALLOW_IMPLICIT_CONSTRUCTORS(Foreign);
10873 };
10874
10875
10876 // The JSArray describes JavaScript Arrays
10877 // Such an array can be in one of two modes:
10878 // - fast, backing storage is a FixedArray and length <= elements.length();
10879 // Please note: push and pop can be used to grow and shrink the array.
10880 // - slow, backing storage is a HashTable with numbers as keys.
10881 class JSArray: public JSObject {
10882 public:
10883 // [length]: The length property.
10884 DECL_ACCESSORS(length, Object)
10885
10886 // Overload the length setter to skip write barrier when the length
10887 // is set to a smi. This matches the set function on FixedArray.
10888 inline void set_length(Smi* length);
10889
10890 static bool HasReadOnlyLength(Handle<JSArray> array);
10891 static bool WouldChangeReadOnlyLength(Handle<JSArray> array, uint32_t index);
10892
10893 // Initialize the array with the given capacity. The function may
10894 // fail due to out-of-memory situations, but only if the requested
10895 // capacity is non-zero.
10896 static void Initialize(Handle<JSArray> array, int capacity, int length = 0);
10897
10898 // If the JSArray has fast elements, and new_length would result in
10899 // normalization, returns true.
10900 bool SetLengthWouldNormalize(uint32_t new_length);
10901 static inline bool SetLengthWouldNormalize(Heap* heap, uint32_t new_length);
10902
10903 // Initializes the array to a certain length.
10904 inline bool AllowsSetLength();
10905
10906 static void SetLength(Handle<JSArray> array, uint32_t length);
10907
10908 // Set the content of the array to the content of storage.
10909 static inline void SetContent(Handle<JSArray> array,
10910 Handle<FixedArrayBase> storage);
10911
10912 // ES6 9.4.2.1
10913 MUST_USE_RESULT static Maybe<bool> DefineOwnProperty(
10914 Isolate* isolate, Handle<JSArray> o, Handle<Object> name,
10915 PropertyDescriptor* desc, ShouldThrow should_throw);
10916
10917 static bool AnythingToArrayLength(Isolate* isolate,
10918 Handle<Object> length_object,
10919 uint32_t* output);
10920 MUST_USE_RESULT static Maybe<bool> ArraySetLength(Isolate* isolate,
10921 Handle<JSArray> a,
10922 PropertyDescriptor* desc,
10923 ShouldThrow should_throw);
10924
10925 // Checks whether the Array has the current realm's Array.prototype as its
10926 // prototype. This function is best-effort and only gives a conservative
10927 // approximation, erring on the side of false, in particular with respect
10928 // to Proxies and objects with a hidden prototype.
10929 inline bool HasArrayPrototype(Isolate* isolate);
10930
10931 DECLARE_CAST(JSArray)
10932
10933 // Dispatched behavior.
10934 DECLARE_PRINTER(JSArray)
10935 DECLARE_VERIFIER(JSArray)
10936
10937 // Number of element slots to pre-allocate for an empty array.
10938 static const int kPreallocatedArrayElements = 4;
10939
10940 // Layout description.
10941 static const int kLengthOffset = JSObject::kHeaderSize;
10942 static const int kSize = kLengthOffset + kPointerSize;
10943
10944 static const int kInitialMaxFastElementArray =
10945 (kMaxRegularHeapObjectSize - FixedArray::kHeaderSize - kSize -
10946 AllocationMemento::kSize) /
10947 kPointerSize;
10948
10949 private:
10950 DISALLOW_IMPLICIT_CONSTRUCTORS(JSArray);
10951 };
10952
10953
10954 Handle<Object> CacheInitialJSArrayMaps(Handle<Context> native_context,
10955 Handle<Map> initial_map);
10956
10957
10958 // JSRegExpResult is just a JSArray with a specific initial map.
10959 // This initial map adds in-object properties for "index" and "input"
10960 // properties, as assigned by RegExp.prototype.exec, which allows
10961 // faster creation of RegExp exec results.
10962 // This class just holds constants used when creating the result.
10963 // After creation the result must be treated as a JSArray in all regards.
10964 class JSRegExpResult: public JSArray {
10965 public:
10966 // Offsets of object fields.
10967 static const int kIndexOffset = JSArray::kSize;
10968 static const int kInputOffset = kIndexOffset + kPointerSize;
10969 static const int kSize = kInputOffset + kPointerSize;
10970 // Indices of in-object properties.
10971 static const int kIndexIndex = 0;
10972 static const int kInputIndex = 1;
10973 private:
10974 DISALLOW_IMPLICIT_CONSTRUCTORS(JSRegExpResult);
10975 };
10976
10977
10978 // An accessor must have a getter, but can have no setter.
10979 //
10980 // When setting a property, V8 searches accessors in prototypes.
10981 // If an accessor was found and it does not have a setter,
10982 // the request is ignored.
10983 //
10984 // If the accessor in the prototype has the READ_ONLY property attribute, then
10985 // a new value is added to the derived object when the property is set.
10986 // This shadows the accessor in the prototype.
10987 class AccessorInfo: public Struct {
10988 public:
10989 DECL_ACCESSORS(name, Object)
10990 DECL_INT_ACCESSORS(flag)
10991 DECL_ACCESSORS(expected_receiver_type, Object)
10992 // This directly points at a foreign C function to be used from the runtime.
10993 DECL_ACCESSORS(getter, Object)
10994 DECL_ACCESSORS(setter, Object)
10995 // This either points at the same as above, or a trampoline in case we are
10996 // running with the simulator. Use these entries from generated code.
10997 DECL_ACCESSORS(js_getter, Object)
10998 DECL_ACCESSORS(data, Object)
10999
11000 static Address redirect(Isolate* isolate, Address address,
11001 AccessorComponent component);
11002 Address redirected_getter() const;
11003
11004 // Dispatched behavior.
11005 DECLARE_PRINTER(AccessorInfo)
11006
11007 inline bool all_can_read();
11008 inline void set_all_can_read(bool value);
11009
11010 inline bool all_can_write();
11011 inline void set_all_can_write(bool value);
11012
11013 inline bool is_special_data_property();
11014 inline void set_is_special_data_property(bool value);
11015
11016 inline bool replace_on_access();
11017 inline void set_replace_on_access(bool value);
11018
11019 inline bool is_sloppy();
11020 inline void set_is_sloppy(bool value);
11021
11022 inline PropertyAttributes property_attributes();
11023 inline void set_property_attributes(PropertyAttributes attributes);
11024
11025 // Checks whether the given receiver is compatible with this accessor.
11026 static bool IsCompatibleReceiverMap(Isolate* isolate,
11027 Handle<AccessorInfo> info,
11028 Handle<Map> map);
11029 inline bool IsCompatibleReceiver(Object* receiver);
11030
11031 DECLARE_CAST(AccessorInfo)
11032
11033 // Dispatched behavior.
11034 DECLARE_VERIFIER(AccessorInfo)
11035
11036 // Append all descriptors to the array that are not already there.
11037 // Return number added.
11038 static int AppendUnique(Handle<Object> descriptors,
11039 Handle<FixedArray> array,
11040 int valid_descriptors);
11041
11042 static const int kNameOffset = HeapObject::kHeaderSize;
11043 static const int kFlagOffset = kNameOffset + kPointerSize;
11044 static const int kExpectedReceiverTypeOffset = kFlagOffset + kPointerSize;
11045 static const int kSetterOffset = kExpectedReceiverTypeOffset + kPointerSize;
11046 static const int kGetterOffset = kSetterOffset + kPointerSize;
11047 static const int kJsGetterOffset = kGetterOffset + kPointerSize;
11048 static const int kDataOffset = kJsGetterOffset + kPointerSize;
11049 static const int kSize = kDataOffset + kPointerSize;
11050
11051
11052 private:
11053 inline bool HasExpectedReceiverType();
11054
11055 // Bit positions in flag.
11056 static const int kAllCanReadBit = 0;
11057 static const int kAllCanWriteBit = 1;
11058 static const int kSpecialDataProperty = 2;
11059 static const int kIsSloppy = 3;
11060 static const int kReplaceOnAccess = 4;
11061 class AttributesField : public BitField<PropertyAttributes, 5, 3> {};
11062
11063 DISALLOW_IMPLICIT_CONSTRUCTORS(AccessorInfo);
11064 };
11065
11066
11067 // Support for JavaScript accessors: A pair of a getter and a setter. Each
11068 // accessor can either be
11069 // * a pointer to a JavaScript function or proxy: a real accessor
11070 // * undefined: considered an accessor by the spec, too, strangely enough
11071 // * the hole: an accessor which has not been set
11072 // * a pointer to a map: a transition used to ensure map sharing
11073 class AccessorPair: public Struct {
11074 public:
11075 DECL_ACCESSORS(getter, Object)
11076 DECL_ACCESSORS(setter, Object)
11077
11078 DECLARE_CAST(AccessorPair)
11079
11080 static Handle<AccessorPair> Copy(Handle<AccessorPair> pair);
11081
11082 inline Object* get(AccessorComponent component);
11083 inline void set(AccessorComponent component, Object* value);
11084
11085 // Note: Returns undefined instead in case of a hole.
11086 static Handle<Object> GetComponent(Handle<AccessorPair> accessor_pair,
11087 AccessorComponent component);
11088
11089 // Set both components, skipping arguments which are a JavaScript null.
11090 inline void SetComponents(Object* getter, Object* setter);
11091
11092 inline bool Equals(AccessorPair* pair);
11093 inline bool Equals(Object* getter_value, Object* setter_value);
11094
11095 inline bool ContainsAccessor();
11096
11097 // Dispatched behavior.
11098 DECLARE_PRINTER(AccessorPair)
11099 DECLARE_VERIFIER(AccessorPair)
11100
11101 static const int kGetterOffset = HeapObject::kHeaderSize;
11102 static const int kSetterOffset = kGetterOffset + kPointerSize;
11103 static const int kSize = kSetterOffset + kPointerSize;
11104
11105 private:
11106 // Strangely enough, in addition to functions and harmony proxies, the spec
11107 // requires us to consider undefined as a kind of accessor, too:
11108 // var obj = {};
11109 // Object.defineProperty(obj, "foo", {get: undefined});
11110 // assertTrue("foo" in obj);
11111 inline bool IsJSAccessor(Object* obj);
11112
11113 DISALLOW_IMPLICIT_CONSTRUCTORS(AccessorPair);
11114 };
11115
11116
11117 class AccessCheckInfo: public Struct {
11118 public:
11119 DECL_ACCESSORS(callback, Object)
11120 DECL_ACCESSORS(named_interceptor, Object)
11121 DECL_ACCESSORS(indexed_interceptor, Object)
11122 DECL_ACCESSORS(data, Object)
11123
11124 DECLARE_CAST(AccessCheckInfo)
11125
11126 // Dispatched behavior.
11127 DECLARE_PRINTER(AccessCheckInfo)
11128 DECLARE_VERIFIER(AccessCheckInfo)
11129
11130 static AccessCheckInfo* Get(Isolate* isolate, Handle<JSObject> receiver);
11131
11132 static const int kCallbackOffset = HeapObject::kHeaderSize;
11133 static const int kNamedInterceptorOffset = kCallbackOffset + kPointerSize;
11134 static const int kIndexedInterceptorOffset =
11135 kNamedInterceptorOffset + kPointerSize;
11136 static const int kDataOffset = kIndexedInterceptorOffset + kPointerSize;
11137 static const int kSize = kDataOffset + kPointerSize;
11138
11139 private:
11140 DISALLOW_IMPLICIT_CONSTRUCTORS(AccessCheckInfo);
11141 };
11142
11143
11144 class InterceptorInfo: public Struct {
11145 public:
11146 DECL_ACCESSORS(getter, Object)
11147 DECL_ACCESSORS(setter, Object)
11148 DECL_ACCESSORS(query, Object)
11149 DECL_ACCESSORS(descriptor, Object)
11150 DECL_ACCESSORS(deleter, Object)
11151 DECL_ACCESSORS(enumerator, Object)
11152 DECL_ACCESSORS(definer, Object)
11153 DECL_ACCESSORS(data, Object)
11154 DECL_BOOLEAN_ACCESSORS(can_intercept_symbols)
11155 DECL_BOOLEAN_ACCESSORS(all_can_read)
11156 DECL_BOOLEAN_ACCESSORS(non_masking)
11157
11158 inline int flags() const;
11159 inline void set_flags(int flags);
11160
11161 DECLARE_CAST(InterceptorInfo)
11162
11163 // Dispatched behavior.
11164 DECLARE_PRINTER(InterceptorInfo)
11165 DECLARE_VERIFIER(InterceptorInfo)
11166
11167 static const int kGetterOffset = HeapObject::kHeaderSize;
11168 static const int kSetterOffset = kGetterOffset + kPointerSize;
11169 static const int kQueryOffset = kSetterOffset + kPointerSize;
11170 static const int kDescriptorOffset = kQueryOffset + kPointerSize;
11171 static const int kDeleterOffset = kDescriptorOffset + kPointerSize;
11172 static const int kEnumeratorOffset = kDeleterOffset + kPointerSize;
11173 static const int kDefinerOffset = kEnumeratorOffset + kPointerSize;
11174 static const int kDataOffset = kDefinerOffset + kPointerSize;
11175 static const int kFlagsOffset = kDataOffset + kPointerSize;
11176 static const int kSize = kFlagsOffset + kPointerSize;
11177
11178 static const int kCanInterceptSymbolsBit = 0;
11179 static const int kAllCanReadBit = 1;
11180 static const int kNonMasking = 2;
11181
11182 private:
11183 DISALLOW_IMPLICIT_CONSTRUCTORS(InterceptorInfo);
11184 };
11185
11186
11187 class CallHandlerInfo: public Struct {
11188 public:
11189 DECL_ACCESSORS(callback, Object)
11190 DECL_ACCESSORS(data, Object)
11191 DECL_ACCESSORS(fast_handler, Object)
11192
11193 DECLARE_CAST(CallHandlerInfo)
11194
11195 // Dispatched behavior.
11196 DECLARE_PRINTER(CallHandlerInfo)
11197 DECLARE_VERIFIER(CallHandlerInfo)
11198
11199 static const int kCallbackOffset = HeapObject::kHeaderSize;
11200 static const int kDataOffset = kCallbackOffset + kPointerSize;
11201 static const int kFastHandlerOffset = kDataOffset + kPointerSize;
11202 static const int kSize = kFastHandlerOffset + kPointerSize;
11203
11204 private:
11205 DISALLOW_IMPLICIT_CONSTRUCTORS(CallHandlerInfo);
11206 };
11207
11208
11209 class TemplateInfo: public Struct {
11210 public:
11211 DECL_ACCESSORS(tag, Object)
11212 DECL_ACCESSORS(serial_number, Object)
11213 DECL_INT_ACCESSORS(number_of_properties)
11214 DECL_ACCESSORS(property_list, Object)
11215 DECL_ACCESSORS(property_accessors, Object)
11216
11217 DECLARE_VERIFIER(TemplateInfo)
11218
11219 DECLARE_CAST(TemplateInfo)
11220
11221 static const int kTagOffset = HeapObject::kHeaderSize;
11222 static const int kSerialNumberOffset = kTagOffset + kPointerSize;
11223 static const int kNumberOfProperties = kSerialNumberOffset + kPointerSize;
11224 static const int kPropertyListOffset = kNumberOfProperties + kPointerSize;
11225 static const int kPropertyAccessorsOffset =
11226 kPropertyListOffset + kPointerSize;
11227 static const int kHeaderSize = kPropertyAccessorsOffset + kPointerSize;
11228
11229 static const int kFastTemplateInstantiationsCacheSize = 1 * KB;
11230
11231 private:
11232 DISALLOW_IMPLICIT_CONSTRUCTORS(TemplateInfo);
11233 };
11234
11235
11236 class FunctionTemplateInfo: public TemplateInfo {
11237 public:
11238 DECL_ACCESSORS(call_code, Object)
11239 DECL_ACCESSORS(prototype_template, Object)
11240 DECL_ACCESSORS(prototype_provider_template, Object)
11241 DECL_ACCESSORS(parent_template, Object)
11242 DECL_ACCESSORS(named_property_handler, Object)
11243 DECL_ACCESSORS(indexed_property_handler, Object)
11244 DECL_ACCESSORS(instance_template, Object)
11245 DECL_ACCESSORS(class_name, Object)
11246 DECL_ACCESSORS(signature, Object)
11247 DECL_ACCESSORS(instance_call_handler, Object)
11248 DECL_ACCESSORS(access_check_info, Object)
11249 DECL_ACCESSORS(shared_function_info, Object)
11250 DECL_ACCESSORS(js_function, Object)
11251 DECL_INT_ACCESSORS(flag)
11252
11253 inline int length() const;
11254 inline void set_length(int value);
11255
11256 // Following properties use flag bits.
11257 DECL_BOOLEAN_ACCESSORS(hidden_prototype)
11258 DECL_BOOLEAN_ACCESSORS(undetectable)
11259 // If the bit is set, object instances created by this function
11260 // requires access check.
11261 DECL_BOOLEAN_ACCESSORS(needs_access_check)
11262 DECL_BOOLEAN_ACCESSORS(read_only_prototype)
11263 DECL_BOOLEAN_ACCESSORS(remove_prototype)
11264 DECL_BOOLEAN_ACCESSORS(do_not_cache)
11265 DECL_BOOLEAN_ACCESSORS(accept_any_receiver)
11266
11267 DECL_ACCESSORS(cached_property_name, Object)
11268
11269 DECLARE_CAST(FunctionTemplateInfo)
11270
11271 // Dispatched behavior.
11272 DECLARE_PRINTER(FunctionTemplateInfo)
11273 DECLARE_VERIFIER(FunctionTemplateInfo)
11274
11275 static const int kInvalidSerialNumber = 0;
11276
11277 static const int kCallCodeOffset = TemplateInfo::kHeaderSize;
11278 static const int kPrototypeTemplateOffset =
11279 kCallCodeOffset + kPointerSize;
11280 static const int kPrototypeProviderTemplateOffset =
11281 kPrototypeTemplateOffset + kPointerSize;
11282 static const int kParentTemplateOffset =
11283 kPrototypeProviderTemplateOffset + kPointerSize;
11284 static const int kNamedPropertyHandlerOffset =
11285 kParentTemplateOffset + kPointerSize;
11286 static const int kIndexedPropertyHandlerOffset =
11287 kNamedPropertyHandlerOffset + kPointerSize;
11288 static const int kInstanceTemplateOffset =
11289 kIndexedPropertyHandlerOffset + kPointerSize;
11290 static const int kClassNameOffset = kInstanceTemplateOffset + kPointerSize;
11291 static const int kSignatureOffset = kClassNameOffset + kPointerSize;
11292 static const int kInstanceCallHandlerOffset = kSignatureOffset + kPointerSize;
11293 static const int kAccessCheckInfoOffset =
11294 kInstanceCallHandlerOffset + kPointerSize;
11295 static const int kSharedFunctionInfoOffset =
11296 kAccessCheckInfoOffset + kPointerSize;
11297 static const int kFlagOffset = kSharedFunctionInfoOffset + kPointerSize;
11298 static const int kLengthOffset = kFlagOffset + kPointerSize;
11299 static const int kCachedPropertyNameOffset = kLengthOffset + kPointerSize;
11300 static const int kSize = kCachedPropertyNameOffset + kPointerSize;
11301
11302 static Handle<SharedFunctionInfo> GetOrCreateSharedFunctionInfo(
11303 Isolate* isolate, Handle<FunctionTemplateInfo> info);
11304 // Returns parent function template or null.
11305 inline FunctionTemplateInfo* GetParent(Isolate* isolate);
11306 // Returns true if |object| is an instance of this function template.
11307 inline bool IsTemplateFor(JSObject* object);
11308 bool IsTemplateFor(Map* map);
11309 inline bool instantiated();
11310
11311 // Helper function for cached accessors.
11312 static MaybeHandle<Name> TryGetCachedPropertyName(Isolate* isolate,
11313 Handle<Object> getter);
11314
11315 private:
11316 // Bit position in the flag, from least significant bit position.
11317 static const int kHiddenPrototypeBit = 0;
11318 static const int kUndetectableBit = 1;
11319 static const int kNeedsAccessCheckBit = 2;
11320 static const int kReadOnlyPrototypeBit = 3;
11321 static const int kRemovePrototypeBit = 4;
11322 static const int kDoNotCacheBit = 5;
11323 static const int kAcceptAnyReceiver = 6;
11324
11325 DISALLOW_IMPLICIT_CONSTRUCTORS(FunctionTemplateInfo);
11326 };
11327
11328
11329 class ObjectTemplateInfo: public TemplateInfo {
11330 public:
11331 DECL_ACCESSORS(constructor, Object)
11332 DECL_ACCESSORS(data, Object)
11333 DECL_INT_ACCESSORS(internal_field_count)
11334 DECL_BOOLEAN_ACCESSORS(immutable_proto)
11335
11336 DECLARE_CAST(ObjectTemplateInfo)
11337
11338 // Dispatched behavior.
11339 DECLARE_PRINTER(ObjectTemplateInfo)
11340 DECLARE_VERIFIER(ObjectTemplateInfo)
11341
11342 static const int kConstructorOffset = TemplateInfo::kHeaderSize;
11343 // LSB is for immutable_proto, higher bits for internal_field_count
11344 static const int kDataOffset = kConstructorOffset + kPointerSize;
11345 static const int kSize = kDataOffset + kPointerSize;
11346
11347 // Starting from given object template's constructor walk up the inheritance
11348 // chain till a function template that has an instance template is found.
11349 inline ObjectTemplateInfo* GetParent(Isolate* isolate);
11350
11351 private:
11352 class IsImmutablePrototype : public BitField<bool, 0, 1> {};
11353 class InternalFieldCount
11354 : public BitField<int, IsImmutablePrototype::kNext, 29> {};
11355 };
11356
11357
11358 // The DebugInfo class holds additional information for a function being
11359 // debugged.
11360 class DebugInfo: public Struct {
11361 public:
11362 // The shared function info for the source being debugged.
11363 DECL_ACCESSORS(shared, SharedFunctionInfo)
11364
11365 // Bit field containing various information collected for debugging.
11366 DECL_INT_ACCESSORS(debugger_hints)
11367
11368 DECL_ACCESSORS(debug_bytecode_array, Object)
11369 // Fixed array holding status information for each active break point.
11370 DECL_ACCESSORS(break_points, FixedArray)
11371
11372 // Check if there is a break point at a source position.
11373 bool HasBreakPoint(int source_position);
11374 // Attempt to clear a break point. Return true if successful.
11375 static bool ClearBreakPoint(Handle<DebugInfo> debug_info,
11376 Handle<Object> break_point_object);
11377 // Set a break point.
11378 static void SetBreakPoint(Handle<DebugInfo> debug_info, int source_position,
11379 Handle<Object> break_point_object);
11380 // Get the break point objects for a source position.
11381 Handle<Object> GetBreakPointObjects(int source_position);
11382 // Find the break point info holding this break point object.
11383 static Handle<Object> FindBreakPointInfo(Handle<DebugInfo> debug_info,
11384 Handle<Object> break_point_object);
11385 // Get the number of break points for this function.
11386 int GetBreakPointCount();
11387
11388 inline bool HasDebugBytecodeArray();
11389 inline bool HasDebugCode();
11390
11391 inline BytecodeArray* OriginalBytecodeArray();
11392 inline BytecodeArray* DebugBytecodeArray();
11393 inline Code* DebugCode();
11394
11395 DECLARE_CAST(DebugInfo)
11396
11397 // Dispatched behavior.
11398 DECLARE_PRINTER(DebugInfo)
11399 DECLARE_VERIFIER(DebugInfo)
11400
11401 static const int kSharedFunctionInfoIndex = Struct::kHeaderSize;
11402 static const int kDebuggerHintsIndex =
11403 kSharedFunctionInfoIndex + kPointerSize;
11404 static const int kDebugBytecodeArrayIndex =
11405 kDebuggerHintsIndex + kPointerSize;
11406 static const int kBreakPointsStateIndex =
11407 kDebugBytecodeArrayIndex + kPointerSize;
11408 static const int kSize = kBreakPointsStateIndex + kPointerSize;
11409
11410 static const int kEstimatedNofBreakPointsInFunction = 4;
11411
11412 private:
11413 // Get the break point info object for a source position.
11414 Object* GetBreakPointInfo(int source_position);
11415
11416 DISALLOW_IMPLICIT_CONSTRUCTORS(DebugInfo);
11417 };
11418
11419
11420 // The BreakPointInfo class holds information for break points set in a
11421 // function. The DebugInfo object holds a BreakPointInfo object for each code
11422 // position with one or more break points.
11423 class BreakPointInfo: public Struct {
11424 public:
11425 // The position in the source for the break position.
11426 DECL_INT_ACCESSORS(source_position)
11427 // List of related JavaScript break points.
11428 DECL_ACCESSORS(break_point_objects, Object)
11429
11430 // Removes a break point.
11431 static void ClearBreakPoint(Handle<BreakPointInfo> info,
11432 Handle<Object> break_point_object);
11433 // Set a break point.
11434 static void SetBreakPoint(Handle<BreakPointInfo> info,
11435 Handle<Object> break_point_object);
11436 // Check if break point info has this break point object.
11437 static bool HasBreakPointObject(Handle<BreakPointInfo> info,
11438 Handle<Object> break_point_object);
11439 // Get the number of break points for this code offset.
11440 int GetBreakPointCount();
11441
11442 int GetStatementPosition(Handle<DebugInfo> debug_info);
11443
11444 DECLARE_CAST(BreakPointInfo)
11445
11446 // Dispatched behavior.
11447 DECLARE_PRINTER(BreakPointInfo)
11448 DECLARE_VERIFIER(BreakPointInfo)
11449
11450 static const int kSourcePositionIndex = Struct::kHeaderSize;
11451 static const int kBreakPointObjectsIndex =
11452 kSourcePositionIndex + kPointerSize;
11453 static const int kSize = kBreakPointObjectsIndex + kPointerSize;
11454
11455 private:
11456 DISALLOW_IMPLICIT_CONSTRUCTORS(BreakPointInfo);
11457 };
11458
11459
11460 #define VISITOR_SYNCHRONIZATION_TAGS_LIST(V) \
11461 V(kStringTable, "string_table", "(Internalized strings)") \
11462 V(kExternalStringsTable, "external_strings_table", "(External strings)") \
11463 V(kStrongRootList, "strong_root_list", "(Strong roots)") \
11464 V(kSmiRootList, "smi_root_list", "(Smi roots)") \
11465 V(kBootstrapper, "bootstrapper", "(Bootstrapper)") \
11466 V(kTop, "top", "(Isolate)") \
11467 V(kRelocatable, "relocatable", "(Relocatable)") \
11468 V(kDebug, "debug", "(Debugger)") \
11469 V(kCompilationCache, "compilationcache", "(Compilation cache)") \
11470 V(kHandleScope, "handlescope", "(Handle scope)") \
11471 V(kDispatchTable, "dispatchtable", "(Dispatch table)") \
11472 V(kBuiltins, "builtins", "(Builtins)") \
11473 V(kGlobalHandles, "globalhandles", "(Global handles)") \
11474 V(kEternalHandles, "eternalhandles", "(Eternal handles)") \
11475 V(kThreadManager, "threadmanager", "(Thread manager)") \
11476 V(kStrongRoots, "strong roots", "(Strong roots)") \
11477 V(kExtensions, "Extensions", "(Extensions)")
11478
11479 class VisitorSynchronization : public AllStatic {
11480 public:
11481 #define DECLARE_ENUM(enum_item, ignore1, ignore2) enum_item,
11482 enum SyncTag {
11483 VISITOR_SYNCHRONIZATION_TAGS_LIST(DECLARE_ENUM)
11484 kNumberOfSyncTags
11485 };
11486 #undef DECLARE_ENUM
11487
11488 static const char* const kTags[kNumberOfSyncTags];
11489 static const char* const kTagNames[kNumberOfSyncTags];
11490 };
11491
11492 // Abstract base class for visiting, and optionally modifying, the
11493 // pointers contained in Objects. Used in GC and serialization/deserialization.
11494 class ObjectVisitor BASE_EMBEDDED {
11495 public:
~ObjectVisitor()11496 virtual ~ObjectVisitor() {}
11497
11498 // Visits a contiguous arrays of pointers in the half-open range
11499 // [start, end). Any or all of the values may be modified on return.
11500 virtual void VisitPointers(Object** start, Object** end) = 0;
11501
11502 // Handy shorthand for visiting a single pointer.
VisitPointer(Object ** p)11503 virtual void VisitPointer(Object** p) { VisitPointers(p, p + 1); }
11504
11505 // Visit weak next_code_link in Code object.
VisitNextCodeLink(Object ** p)11506 virtual void VisitNextCodeLink(Object** p) { VisitPointers(p, p + 1); }
11507
11508 // To allow lazy clearing of inline caches the visitor has
11509 // a rich interface for iterating over Code objects..
11510
11511 // Visits a code target in the instruction stream.
11512 virtual void VisitCodeTarget(RelocInfo* rinfo);
11513
11514 // Visits a code entry in a JS function.
11515 virtual void VisitCodeEntry(Address entry_address);
11516
11517 // Visits a global property cell reference in the instruction stream.
11518 virtual void VisitCell(RelocInfo* rinfo);
11519
11520 // Visits a runtime entry in the instruction stream.
VisitRuntimeEntry(RelocInfo * rinfo)11521 virtual void VisitRuntimeEntry(RelocInfo* rinfo) {}
11522
11523 // Visits the resource of an one-byte or two-byte string.
VisitExternalOneByteString(v8::String::ExternalOneByteStringResource ** resource)11524 virtual void VisitExternalOneByteString(
11525 v8::String::ExternalOneByteStringResource** resource) {}
VisitExternalTwoByteString(v8::String::ExternalStringResource ** resource)11526 virtual void VisitExternalTwoByteString(
11527 v8::String::ExternalStringResource** resource) {}
11528
11529 // Visits a debug call target in the instruction stream.
11530 virtual void VisitDebugTarget(RelocInfo* rinfo);
11531
11532 // Visits the byte sequence in a function's prologue that contains information
11533 // about the code's age.
11534 virtual void VisitCodeAgeSequence(RelocInfo* rinfo);
11535
11536 // Visit pointer embedded into a code object.
11537 virtual void VisitEmbeddedPointer(RelocInfo* rinfo);
11538
11539 // Visits an external reference embedded into a code object.
11540 virtual void VisitExternalReference(RelocInfo* rinfo);
11541
11542 // Visits an external reference.
VisitExternalReference(Address * p)11543 virtual void VisitExternalReference(Address* p) {}
11544
11545 // Visits an (encoded) internal reference.
VisitInternalReference(RelocInfo * rinfo)11546 virtual void VisitInternalReference(RelocInfo* rinfo) {}
11547
11548 // Visits a handle that has an embedder-assigned class ID.
VisitEmbedderReference(Object ** p,uint16_t class_id)11549 virtual void VisitEmbedderReference(Object** p, uint16_t class_id) {}
11550
11551 // Intended for serialization/deserialization checking: insert, or
11552 // check for the presence of, a tag at this position in the stream.
11553 // Also used for marking up GC roots in heap snapshots.
Synchronize(VisitorSynchronization::SyncTag tag)11554 virtual void Synchronize(VisitorSynchronization::SyncTag tag) {}
11555 };
11556
11557
11558 // BooleanBit is a helper class for setting and getting a bit in an integer.
11559 class BooleanBit : public AllStatic {
11560 public:
get(int value,int bit_position)11561 static inline bool get(int value, int bit_position) {
11562 return (value & (1 << bit_position)) != 0;
11563 }
11564
set(int value,int bit_position,bool v)11565 static inline int set(int value, int bit_position, bool v) {
11566 if (v) {
11567 value |= (1 << bit_position);
11568 } else {
11569 value &= ~(1 << bit_position);
11570 }
11571 return value;
11572 }
11573 };
11574
11575
11576 } // NOLINT, false-positive due to second-order macros.
11577 } // NOLINT, false-positive due to second-order macros.
11578
11579 #include "src/objects/object-macros-undef.h"
11580
11581 #endif // V8_OBJECTS_H_
11582