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