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