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