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