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