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