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