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