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