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 "builtins.h" 33 #include "list.h" 34 #include "property-details.h" 35 #include "smart-array-pointer.h" 36 #include "unicode-inl.h" 37 #if V8_TARGET_ARCH_ARM 38 #include "arm/constants-arm.h" 39 #elif V8_TARGET_ARCH_MIPS 40 #include "mips/constants-mips.h" 41 #endif 42 #include "v8checks.h" 43 44 45 // 46 // Most object types in the V8 JavaScript are described in this file. 47 // 48 // Inheritance hierarchy: 49 // - MaybeObject (an object or a failure) 50 // - Failure (immediate for marking failed operation) 51 // - Object 52 // - Smi (immediate small integer) 53 // - HeapObject (superclass for everything allocated in the heap) 54 // - JSReceiver (suitable for property access) 55 // - JSObject 56 // - JSArray 57 // - JSSet 58 // - JSMap 59 // - JSWeakMap 60 // - JSRegExp 61 // - JSFunction 62 // - GlobalObject 63 // - JSGlobalObject 64 // - JSBuiltinsObject 65 // - JSGlobalProxy 66 // - JSValue 67 // - JSDate 68 // - JSMessageObject 69 // - JSProxy 70 // - JSFunctionProxy 71 // - FixedArrayBase 72 // - ByteArray 73 // - FixedArray 74 // - DescriptorArray 75 // - HashTable 76 // - Dictionary 77 // - SymbolTable 78 // - CompilationCacheTable 79 // - CodeCacheHashTable 80 // - MapCache 81 // - Context 82 // - JSFunctionResultCache 83 // - ScopeInfo 84 // - FixedDoubleArray 85 // - ExternalArray 86 // - ExternalPixelArray 87 // - ExternalByteArray 88 // - ExternalUnsignedByteArray 89 // - ExternalShortArray 90 // - ExternalUnsignedShortArray 91 // - ExternalIntArray 92 // - ExternalUnsignedIntArray 93 // - ExternalFloatArray 94 // - String 95 // - SeqString 96 // - SeqAsciiString 97 // - SeqTwoByteString 98 // - SlicedString 99 // - ConsString 100 // - ExternalString 101 // - ExternalAsciiString 102 // - ExternalTwoByteString 103 // - HeapNumber 104 // - Code 105 // - Map 106 // - Oddball 107 // - Foreign 108 // - SharedFunctionInfo 109 // - Struct 110 // - AccessorInfo 111 // - AccessorPair 112 // - AccessCheckInfo 113 // - InterceptorInfo 114 // - CallHandlerInfo 115 // - TemplateInfo 116 // - FunctionTemplateInfo 117 // - ObjectTemplateInfo 118 // - Script 119 // - SignatureInfo 120 // - TypeSwitchInfo 121 // - DebugInfo 122 // - BreakPointInfo 123 // - CodeCache 124 // 125 // Formats of Object*: 126 // Smi: [31 bit signed int] 0 127 // HeapObject: [32 bit direct pointer] (4 byte aligned) | 01 128 // Failure: [30 bit signed int] 11 129 130 namespace v8 { 131 namespace internal { 132 133 enum ElementsKind { 134 // The "fast" kind for elements that only contain SMI values. Must be first 135 // to make it possible to efficiently check maps for this kind. 136 FAST_SMI_ONLY_ELEMENTS, 137 138 // The "fast" kind for tagged values. Must be second to make it possible to 139 // efficiently check maps for this and the FAST_SMI_ONLY_ELEMENTS kind 140 // together at once. 141 FAST_ELEMENTS, 142 143 // The "fast" kind for unwrapped, non-tagged double values. 144 FAST_DOUBLE_ELEMENTS, 145 146 // The "slow" kind. 147 DICTIONARY_ELEMENTS, 148 NON_STRICT_ARGUMENTS_ELEMENTS, 149 // The "fast" kind for external arrays 150 EXTERNAL_BYTE_ELEMENTS, 151 EXTERNAL_UNSIGNED_BYTE_ELEMENTS, 152 EXTERNAL_SHORT_ELEMENTS, 153 EXTERNAL_UNSIGNED_SHORT_ELEMENTS, 154 EXTERNAL_INT_ELEMENTS, 155 EXTERNAL_UNSIGNED_INT_ELEMENTS, 156 EXTERNAL_FLOAT_ELEMENTS, 157 EXTERNAL_DOUBLE_ELEMENTS, 158 EXTERNAL_PIXEL_ELEMENTS, 159 160 // Derived constants from ElementsKind 161 FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND = EXTERNAL_BYTE_ELEMENTS, 162 LAST_EXTERNAL_ARRAY_ELEMENTS_KIND = EXTERNAL_PIXEL_ELEMENTS, 163 FIRST_ELEMENTS_KIND = FAST_SMI_ONLY_ELEMENTS, 164 LAST_ELEMENTS_KIND = EXTERNAL_PIXEL_ELEMENTS 165 }; 166 167 enum CompareMapMode { 168 REQUIRE_EXACT_MAP, 169 ALLOW_ELEMENT_TRANSITION_MAPS 170 }; 171 172 enum KeyedAccessGrowMode { 173 DO_NOT_ALLOW_JSARRAY_GROWTH, 174 ALLOW_JSARRAY_GROWTH 175 }; 176 177 const int kElementsKindCount = LAST_ELEMENTS_KIND - FIRST_ELEMENTS_KIND + 1; 178 179 void PrintElementsKind(FILE* out, ElementsKind kind); 180 181 inline bool IsMoreGeneralElementsKindTransition(ElementsKind from_kind, 182 ElementsKind to_kind); 183 184 // Setter that skips the write barrier if mode is SKIP_WRITE_BARRIER. 185 enum WriteBarrierMode { SKIP_WRITE_BARRIER, UPDATE_WRITE_BARRIER }; 186 187 188 // PropertyNormalizationMode is used to specify whether to keep 189 // inobject properties when normalizing properties of a JSObject. 190 enum PropertyNormalizationMode { 191 CLEAR_INOBJECT_PROPERTIES, 192 KEEP_INOBJECT_PROPERTIES 193 }; 194 195 196 // NormalizedMapSharingMode is used to specify whether a map may be shared 197 // by different objects with normalized properties. 198 enum NormalizedMapSharingMode { 199 UNIQUE_NORMALIZED_MAP, 200 SHARED_NORMALIZED_MAP 201 }; 202 203 204 // Indicates whether a get method should implicitly create the object looked up. 205 enum CreationFlag { 206 ALLOW_CREATION, 207 OMIT_CREATION 208 }; 209 210 211 // Instance size sentinel for objects of variable size. 212 const int kVariableSizeSentinel = 0; 213 214 215 // All Maps have a field instance_type containing a InstanceType. 216 // It describes the type of the instances. 217 // 218 // As an example, a JavaScript object is a heap object and its map 219 // instance_type is JS_OBJECT_TYPE. 220 // 221 // The names of the string instance types are intended to systematically 222 // mirror their encoding in the instance_type field of the map. The default 223 // encoding is considered TWO_BYTE. It is not mentioned in the name. ASCII 224 // encoding is mentioned explicitly in the name. Likewise, the default 225 // representation is considered sequential. It is not mentioned in the 226 // name. The other representations (e.g. CONS, EXTERNAL) are explicitly 227 // mentioned. Finally, the string is either a SYMBOL_TYPE (if it is a 228 // symbol) or a STRING_TYPE (if it is not a symbol). 229 // 230 // NOTE: The following things are some that depend on the string types having 231 // instance_types that are less than those of all other types: 232 // HeapObject::Size, HeapObject::IterateBody, the typeof operator, and 233 // Object::IsString. 234 // 235 // NOTE: Everything following JS_VALUE_TYPE is considered a 236 // JSObject for GC purposes. The first four entries here have typeof 237 // 'object', whereas JS_FUNCTION_TYPE has typeof 'function'. 238 #define INSTANCE_TYPE_LIST_ALL(V) \ 239 V(SYMBOL_TYPE) \ 240 V(ASCII_SYMBOL_TYPE) \ 241 V(CONS_SYMBOL_TYPE) \ 242 V(CONS_ASCII_SYMBOL_TYPE) \ 243 V(EXTERNAL_SYMBOL_TYPE) \ 244 V(EXTERNAL_SYMBOL_WITH_ASCII_DATA_TYPE) \ 245 V(EXTERNAL_ASCII_SYMBOL_TYPE) \ 246 V(SHORT_EXTERNAL_SYMBOL_TYPE) \ 247 V(SHORT_EXTERNAL_SYMBOL_WITH_ASCII_DATA_TYPE) \ 248 V(SHORT_EXTERNAL_ASCII_SYMBOL_TYPE) \ 249 V(STRING_TYPE) \ 250 V(ASCII_STRING_TYPE) \ 251 V(CONS_STRING_TYPE) \ 252 V(CONS_ASCII_STRING_TYPE) \ 253 V(SLICED_STRING_TYPE) \ 254 V(EXTERNAL_STRING_TYPE) \ 255 V(EXTERNAL_STRING_WITH_ASCII_DATA_TYPE) \ 256 V(EXTERNAL_ASCII_STRING_TYPE) \ 257 V(SHORT_EXTERNAL_STRING_TYPE) \ 258 V(SHORT_EXTERNAL_STRING_WITH_ASCII_DATA_TYPE) \ 259 V(SHORT_EXTERNAL_ASCII_STRING_TYPE) \ 260 V(PRIVATE_EXTERNAL_ASCII_STRING_TYPE) \ 261 \ 262 V(MAP_TYPE) \ 263 V(CODE_TYPE) \ 264 V(ODDBALL_TYPE) \ 265 V(JS_GLOBAL_PROPERTY_CELL_TYPE) \ 266 \ 267 V(HEAP_NUMBER_TYPE) \ 268 V(FOREIGN_TYPE) \ 269 V(BYTE_ARRAY_TYPE) \ 270 V(FREE_SPACE_TYPE) \ 271 /* Note: the order of these external array */ \ 272 /* types is relied upon in */ \ 273 /* Object::IsExternalArray(). */ \ 274 V(EXTERNAL_BYTE_ARRAY_TYPE) \ 275 V(EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE) \ 276 V(EXTERNAL_SHORT_ARRAY_TYPE) \ 277 V(EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE) \ 278 V(EXTERNAL_INT_ARRAY_TYPE) \ 279 V(EXTERNAL_UNSIGNED_INT_ARRAY_TYPE) \ 280 V(EXTERNAL_FLOAT_ARRAY_TYPE) \ 281 V(EXTERNAL_PIXEL_ARRAY_TYPE) \ 282 V(FILLER_TYPE) \ 283 \ 284 V(ACCESSOR_INFO_TYPE) \ 285 V(ACCESSOR_PAIR_TYPE) \ 286 V(ACCESS_CHECK_INFO_TYPE) \ 287 V(INTERCEPTOR_INFO_TYPE) \ 288 V(CALL_HANDLER_INFO_TYPE) \ 289 V(FUNCTION_TEMPLATE_INFO_TYPE) \ 290 V(OBJECT_TEMPLATE_INFO_TYPE) \ 291 V(SIGNATURE_INFO_TYPE) \ 292 V(TYPE_SWITCH_INFO_TYPE) \ 293 V(SCRIPT_TYPE) \ 294 V(CODE_CACHE_TYPE) \ 295 V(POLYMORPHIC_CODE_CACHE_TYPE) \ 296 V(TYPE_FEEDBACK_INFO_TYPE) \ 297 V(ALIASED_ARGUMENTS_ENTRY_TYPE) \ 298 \ 299 V(FIXED_ARRAY_TYPE) \ 300 V(FIXED_DOUBLE_ARRAY_TYPE) \ 301 V(SHARED_FUNCTION_INFO_TYPE) \ 302 \ 303 V(JS_MESSAGE_OBJECT_TYPE) \ 304 \ 305 V(JS_VALUE_TYPE) \ 306 V(JS_DATE_TYPE) \ 307 V(JS_OBJECT_TYPE) \ 308 V(JS_CONTEXT_EXTENSION_OBJECT_TYPE) \ 309 V(JS_GLOBAL_OBJECT_TYPE) \ 310 V(JS_BUILTINS_OBJECT_TYPE) \ 311 V(JS_GLOBAL_PROXY_TYPE) \ 312 V(JS_ARRAY_TYPE) \ 313 V(JS_PROXY_TYPE) \ 314 V(JS_WEAK_MAP_TYPE) \ 315 V(JS_REGEXP_TYPE) \ 316 \ 317 V(JS_FUNCTION_TYPE) \ 318 V(JS_FUNCTION_PROXY_TYPE) \ 319 320 #ifdef ENABLE_DEBUGGER_SUPPORT 321 #define INSTANCE_TYPE_LIST_DEBUGGER(V) \ 322 V(DEBUG_INFO_TYPE) \ 323 V(BREAK_POINT_INFO_TYPE) 324 #else 325 #define INSTANCE_TYPE_LIST_DEBUGGER(V) 326 #endif 327 328 #define INSTANCE_TYPE_LIST(V) \ 329 INSTANCE_TYPE_LIST_ALL(V) \ 330 INSTANCE_TYPE_LIST_DEBUGGER(V) 331 332 333 // Since string types are not consecutive, this macro is used to 334 // iterate over them. 335 #define STRING_TYPE_LIST(V) \ 336 V(SYMBOL_TYPE, \ 337 kVariableSizeSentinel, \ 338 symbol, \ 339 Symbol) \ 340 V(ASCII_SYMBOL_TYPE, \ 341 kVariableSizeSentinel, \ 342 ascii_symbol, \ 343 AsciiSymbol) \ 344 V(CONS_SYMBOL_TYPE, \ 345 ConsString::kSize, \ 346 cons_symbol, \ 347 ConsSymbol) \ 348 V(CONS_ASCII_SYMBOL_TYPE, \ 349 ConsString::kSize, \ 350 cons_ascii_symbol, \ 351 ConsAsciiSymbol) \ 352 V(EXTERNAL_SYMBOL_TYPE, \ 353 ExternalTwoByteString::kSize, \ 354 external_symbol, \ 355 ExternalSymbol) \ 356 V(EXTERNAL_SYMBOL_WITH_ASCII_DATA_TYPE, \ 357 ExternalTwoByteString::kSize, \ 358 external_symbol_with_ascii_data, \ 359 ExternalSymbolWithAsciiData) \ 360 V(EXTERNAL_ASCII_SYMBOL_TYPE, \ 361 ExternalAsciiString::kSize, \ 362 external_ascii_symbol, \ 363 ExternalAsciiSymbol) \ 364 V(SHORT_EXTERNAL_SYMBOL_TYPE, \ 365 ExternalTwoByteString::kShortSize, \ 366 short_external_symbol, \ 367 ShortExternalSymbol) \ 368 V(SHORT_EXTERNAL_SYMBOL_WITH_ASCII_DATA_TYPE, \ 369 ExternalTwoByteString::kShortSize, \ 370 short_external_symbol_with_ascii_data, \ 371 ShortExternalSymbolWithAsciiData) \ 372 V(SHORT_EXTERNAL_ASCII_SYMBOL_TYPE, \ 373 ExternalAsciiString::kShortSize, \ 374 short_external_ascii_symbol, \ 375 ShortExternalAsciiSymbol) \ 376 V(STRING_TYPE, \ 377 kVariableSizeSentinel, \ 378 string, \ 379 String) \ 380 V(ASCII_STRING_TYPE, \ 381 kVariableSizeSentinel, \ 382 ascii_string, \ 383 AsciiString) \ 384 V(CONS_STRING_TYPE, \ 385 ConsString::kSize, \ 386 cons_string, \ 387 ConsString) \ 388 V(CONS_ASCII_STRING_TYPE, \ 389 ConsString::kSize, \ 390 cons_ascii_string, \ 391 ConsAsciiString) \ 392 V(SLICED_STRING_TYPE, \ 393 SlicedString::kSize, \ 394 sliced_string, \ 395 SlicedString) \ 396 V(SLICED_ASCII_STRING_TYPE, \ 397 SlicedString::kSize, \ 398 sliced_ascii_string, \ 399 SlicedAsciiString) \ 400 V(EXTERNAL_STRING_TYPE, \ 401 ExternalTwoByteString::kSize, \ 402 external_string, \ 403 ExternalString) \ 404 V(EXTERNAL_STRING_WITH_ASCII_DATA_TYPE, \ 405 ExternalTwoByteString::kSize, \ 406 external_string_with_ascii_data, \ 407 ExternalStringWithAsciiData) \ 408 V(EXTERNAL_ASCII_STRING_TYPE, \ 409 ExternalAsciiString::kSize, \ 410 external_ascii_string, \ 411 ExternalAsciiString) \ 412 V(SHORT_EXTERNAL_STRING_TYPE, \ 413 ExternalTwoByteString::kShortSize, \ 414 short_external_string, \ 415 ShortExternalString) \ 416 V(SHORT_EXTERNAL_STRING_WITH_ASCII_DATA_TYPE, \ 417 ExternalTwoByteString::kShortSize, \ 418 short_external_string_with_ascii_data, \ 419 ShortExternalStringWithAsciiData) \ 420 V(SHORT_EXTERNAL_ASCII_STRING_TYPE, \ 421 ExternalAsciiString::kShortSize, \ 422 short_external_ascii_string, \ 423 ShortExternalAsciiString) 424 425 // A struct is a simple object a set of object-valued fields. Including an 426 // object type in this causes the compiler to generate most of the boilerplate 427 // code for the class including allocation and garbage collection routines, 428 // casts and predicates. All you need to define is the class, methods and 429 // object verification routines. Easy, no? 430 // 431 // Note that for subtle reasons related to the ordering or numerical values of 432 // type tags, elements in this list have to be added to the INSTANCE_TYPE_LIST 433 // manually. 434 #define STRUCT_LIST_ALL(V) \ 435 V(ACCESSOR_INFO, AccessorInfo, accessor_info) \ 436 V(ACCESSOR_PAIR, AccessorPair, accessor_pair) \ 437 V(ACCESS_CHECK_INFO, AccessCheckInfo, access_check_info) \ 438 V(INTERCEPTOR_INFO, InterceptorInfo, interceptor_info) \ 439 V(CALL_HANDLER_INFO, CallHandlerInfo, call_handler_info) \ 440 V(FUNCTION_TEMPLATE_INFO, FunctionTemplateInfo, function_template_info) \ 441 V(OBJECT_TEMPLATE_INFO, ObjectTemplateInfo, object_template_info) \ 442 V(SIGNATURE_INFO, SignatureInfo, signature_info) \ 443 V(TYPE_SWITCH_INFO, TypeSwitchInfo, type_switch_info) \ 444 V(SCRIPT, Script, script) \ 445 V(CODE_CACHE, CodeCache, code_cache) \ 446 V(POLYMORPHIC_CODE_CACHE, PolymorphicCodeCache, polymorphic_code_cache) \ 447 V(TYPE_FEEDBACK_INFO, TypeFeedbackInfo, type_feedback_info) \ 448 V(ALIASED_ARGUMENTS_ENTRY, AliasedArgumentsEntry, aliased_arguments_entry) 449 450 #ifdef ENABLE_DEBUGGER_SUPPORT 451 #define STRUCT_LIST_DEBUGGER(V) \ 452 V(DEBUG_INFO, DebugInfo, debug_info) \ 453 V(BREAK_POINT_INFO, BreakPointInfo, break_point_info) 454 #else 455 #define STRUCT_LIST_DEBUGGER(V) 456 #endif 457 458 #define STRUCT_LIST(V) \ 459 STRUCT_LIST_ALL(V) \ 460 STRUCT_LIST_DEBUGGER(V) 461 462 // We use the full 8 bits of the instance_type field to encode heap object 463 // instance types. The high-order bit (bit 7) is set if the object is not a 464 // string, and cleared if it is a string. 465 const uint32_t kIsNotStringMask = 0x80; 466 const uint32_t kStringTag = 0x0; 467 const uint32_t kNotStringTag = 0x80; 468 469 // Bit 6 indicates that the object is a symbol (if set) or not (if cleared). 470 // There are not enough types that the non-string types (with bit 7 set) can 471 // have bit 6 set too. 472 const uint32_t kIsSymbolMask = 0x40; 473 const uint32_t kNotSymbolTag = 0x0; 474 const uint32_t kSymbolTag = 0x40; 475 476 // If bit 7 is clear then bit 2 indicates whether the string consists of 477 // two-byte characters or one-byte characters. 478 const uint32_t kStringEncodingMask = 0x4; 479 const uint32_t kTwoByteStringTag = 0x0; 480 const uint32_t kAsciiStringTag = 0x4; 481 482 // If bit 7 is clear, the low-order 2 bits indicate the representation 483 // of the string. 484 const uint32_t kStringRepresentationMask = 0x03; 485 enum StringRepresentationTag { 486 kSeqStringTag = 0x0, 487 kConsStringTag = 0x1, 488 kExternalStringTag = 0x2, 489 kSlicedStringTag = 0x3 490 }; 491 const uint32_t kIsIndirectStringMask = 0x1; 492 const uint32_t kIsIndirectStringTag = 0x1; 493 STATIC_ASSERT((kSeqStringTag & kIsIndirectStringMask) == 0); 494 STATIC_ASSERT((kExternalStringTag & kIsIndirectStringMask) == 0); 495 STATIC_ASSERT( 496 (kConsStringTag & kIsIndirectStringMask) == kIsIndirectStringTag); 497 STATIC_ASSERT( 498 (kSlicedStringTag & kIsIndirectStringMask) == kIsIndirectStringTag); 499 500 // Use this mask to distinguish between cons and slice only after making 501 // sure that the string is one of the two (an indirect string). 502 const uint32_t kSlicedNotConsMask = kSlicedStringTag & ~kConsStringTag; 503 STATIC_ASSERT(IS_POWER_OF_TWO(kSlicedNotConsMask) && kSlicedNotConsMask != 0); 504 505 // If bit 7 is clear, then bit 3 indicates whether this two-byte 506 // string actually contains ASCII data. 507 const uint32_t kAsciiDataHintMask = 0x08; 508 const uint32_t kAsciiDataHintTag = 0x08; 509 510 // If bit 7 is clear and string representation indicates an external string, 511 // then bit 4 indicates whether the data pointer is cached. 512 const uint32_t kShortExternalStringMask = 0x10; 513 const uint32_t kShortExternalStringTag = 0x10; 514 515 516 // A ConsString with an empty string as the right side is a candidate 517 // for being shortcut by the garbage collector unless it is a 518 // symbol. It's not common to have non-flat symbols, so we do not 519 // shortcut them thereby avoiding turning symbols into strings. See 520 // heap.cc and mark-compact.cc. 521 const uint32_t kShortcutTypeMask = 522 kIsNotStringMask | 523 kIsSymbolMask | 524 kStringRepresentationMask; 525 const uint32_t kShortcutTypeTag = kConsStringTag; 526 527 528 enum InstanceType { 529 // String types. 530 SYMBOL_TYPE = kTwoByteStringTag | kSymbolTag | kSeqStringTag, 531 ASCII_SYMBOL_TYPE = kAsciiStringTag | kSymbolTag | kSeqStringTag, 532 CONS_SYMBOL_TYPE = kTwoByteStringTag | kSymbolTag | kConsStringTag, 533 CONS_ASCII_SYMBOL_TYPE = kAsciiStringTag | kSymbolTag | kConsStringTag, 534 SHORT_EXTERNAL_SYMBOL_TYPE = kTwoByteStringTag | kSymbolTag | 535 kExternalStringTag | kShortExternalStringTag, 536 SHORT_EXTERNAL_SYMBOL_WITH_ASCII_DATA_TYPE = 537 kTwoByteStringTag | kSymbolTag | kExternalStringTag | 538 kAsciiDataHintTag | kShortExternalStringTag, 539 SHORT_EXTERNAL_ASCII_SYMBOL_TYPE = kAsciiStringTag | kExternalStringTag | 540 kSymbolTag | kShortExternalStringTag, 541 EXTERNAL_SYMBOL_TYPE = kTwoByteStringTag | kSymbolTag | kExternalStringTag, 542 EXTERNAL_SYMBOL_WITH_ASCII_DATA_TYPE = 543 kTwoByteStringTag | kSymbolTag | kExternalStringTag | kAsciiDataHintTag, 544 EXTERNAL_ASCII_SYMBOL_TYPE = 545 kAsciiStringTag | kSymbolTag | kExternalStringTag, 546 STRING_TYPE = kTwoByteStringTag | kSeqStringTag, 547 ASCII_STRING_TYPE = kAsciiStringTag | kSeqStringTag, 548 CONS_STRING_TYPE = kTwoByteStringTag | kConsStringTag, 549 CONS_ASCII_STRING_TYPE = kAsciiStringTag | kConsStringTag, 550 SLICED_STRING_TYPE = kTwoByteStringTag | kSlicedStringTag, 551 SLICED_ASCII_STRING_TYPE = kAsciiStringTag | kSlicedStringTag, 552 SHORT_EXTERNAL_STRING_TYPE = 553 kTwoByteStringTag | kExternalStringTag | kShortExternalStringTag, 554 SHORT_EXTERNAL_STRING_WITH_ASCII_DATA_TYPE = 555 kTwoByteStringTag | kExternalStringTag | 556 kAsciiDataHintTag | kShortExternalStringTag, 557 SHORT_EXTERNAL_ASCII_STRING_TYPE = 558 kAsciiStringTag | kExternalStringTag | kShortExternalStringTag, 559 EXTERNAL_STRING_TYPE = kTwoByteStringTag | kExternalStringTag, 560 EXTERNAL_STRING_WITH_ASCII_DATA_TYPE = 561 kTwoByteStringTag | kExternalStringTag | kAsciiDataHintTag, 562 // LAST_STRING_TYPE 563 EXTERNAL_ASCII_STRING_TYPE = kAsciiStringTag | kExternalStringTag, 564 PRIVATE_EXTERNAL_ASCII_STRING_TYPE = EXTERNAL_ASCII_STRING_TYPE, 565 566 // Objects allocated in their own spaces (never in new space). 567 MAP_TYPE = kNotStringTag, // FIRST_NONSTRING_TYPE 568 CODE_TYPE, 569 ODDBALL_TYPE, 570 JS_GLOBAL_PROPERTY_CELL_TYPE, 571 572 // "Data", objects that cannot contain non-map-word pointers to heap 573 // objects. 574 HEAP_NUMBER_TYPE, 575 FOREIGN_TYPE, 576 BYTE_ARRAY_TYPE, 577 FREE_SPACE_TYPE, 578 EXTERNAL_BYTE_ARRAY_TYPE, // FIRST_EXTERNAL_ARRAY_TYPE 579 EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE, 580 EXTERNAL_SHORT_ARRAY_TYPE, 581 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE, 582 EXTERNAL_INT_ARRAY_TYPE, 583 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE, 584 EXTERNAL_FLOAT_ARRAY_TYPE, 585 EXTERNAL_DOUBLE_ARRAY_TYPE, 586 EXTERNAL_PIXEL_ARRAY_TYPE, // LAST_EXTERNAL_ARRAY_TYPE 587 FIXED_DOUBLE_ARRAY_TYPE, 588 FILLER_TYPE, // LAST_DATA_TYPE 589 590 // Structs. 591 ACCESSOR_INFO_TYPE, 592 ACCESSOR_PAIR_TYPE, 593 ACCESS_CHECK_INFO_TYPE, 594 INTERCEPTOR_INFO_TYPE, 595 CALL_HANDLER_INFO_TYPE, 596 FUNCTION_TEMPLATE_INFO_TYPE, 597 OBJECT_TEMPLATE_INFO_TYPE, 598 SIGNATURE_INFO_TYPE, 599 TYPE_SWITCH_INFO_TYPE, 600 SCRIPT_TYPE, 601 CODE_CACHE_TYPE, 602 POLYMORPHIC_CODE_CACHE_TYPE, 603 TYPE_FEEDBACK_INFO_TYPE, 604 ALIASED_ARGUMENTS_ENTRY_TYPE, 605 // The following two instance types are only used when ENABLE_DEBUGGER_SUPPORT 606 // is defined. However as include/v8.h contain some of the instance type 607 // constants always having them avoids them getting different numbers 608 // depending on whether ENABLE_DEBUGGER_SUPPORT is defined or not. 609 DEBUG_INFO_TYPE, 610 BREAK_POINT_INFO_TYPE, 611 612 FIXED_ARRAY_TYPE, 613 SHARED_FUNCTION_INFO_TYPE, 614 615 JS_MESSAGE_OBJECT_TYPE, 616 617 // All the following types are subtypes of JSReceiver, which corresponds to 618 // objects in the JS sense. The first and the last type in this range are 619 // the two forms of function. This organization enables using the same 620 // compares for checking the JS_RECEIVER/SPEC_OBJECT range and the 621 // NONCALLABLE_JS_OBJECT range. 622 JS_FUNCTION_PROXY_TYPE, // FIRST_JS_RECEIVER_TYPE, FIRST_JS_PROXY_TYPE 623 JS_PROXY_TYPE, // LAST_JS_PROXY_TYPE 624 625 JS_VALUE_TYPE, // FIRST_JS_OBJECT_TYPE 626 JS_DATE_TYPE, 627 JS_OBJECT_TYPE, 628 JS_CONTEXT_EXTENSION_OBJECT_TYPE, 629 JS_GLOBAL_OBJECT_TYPE, 630 JS_BUILTINS_OBJECT_TYPE, 631 JS_GLOBAL_PROXY_TYPE, 632 JS_ARRAY_TYPE, 633 JS_SET_TYPE, 634 JS_MAP_TYPE, 635 JS_WEAK_MAP_TYPE, 636 637 JS_REGEXP_TYPE, 638 639 JS_FUNCTION_TYPE, // LAST_JS_OBJECT_TYPE, LAST_JS_RECEIVER_TYPE 640 641 // Pseudo-types 642 FIRST_TYPE = 0x0, 643 LAST_TYPE = JS_FUNCTION_TYPE, 644 INVALID_TYPE = FIRST_TYPE - 1, 645 FIRST_NONSTRING_TYPE = MAP_TYPE, 646 // Boundaries for testing for an external array. 647 FIRST_EXTERNAL_ARRAY_TYPE = EXTERNAL_BYTE_ARRAY_TYPE, 648 LAST_EXTERNAL_ARRAY_TYPE = EXTERNAL_PIXEL_ARRAY_TYPE, 649 // Boundary for promotion to old data space/old pointer space. 650 LAST_DATA_TYPE = FILLER_TYPE, 651 // Boundary for objects represented as JSReceiver (i.e. JSObject or JSProxy). 652 // Note that there is no range for JSObject or JSProxy, since their subtypes 653 // are not continuous in this enum! The enum ranges instead reflect the 654 // external class names, where proxies are treated as either ordinary objects, 655 // or functions. 656 FIRST_JS_RECEIVER_TYPE = JS_FUNCTION_PROXY_TYPE, 657 LAST_JS_RECEIVER_TYPE = LAST_TYPE, 658 // Boundaries for testing the types represented as JSObject 659 FIRST_JS_OBJECT_TYPE = JS_VALUE_TYPE, 660 LAST_JS_OBJECT_TYPE = LAST_TYPE, 661 // Boundaries for testing the types represented as JSProxy 662 FIRST_JS_PROXY_TYPE = JS_FUNCTION_PROXY_TYPE, 663 LAST_JS_PROXY_TYPE = JS_PROXY_TYPE, 664 // Boundaries for testing whether the type is a JavaScript object. 665 FIRST_SPEC_OBJECT_TYPE = FIRST_JS_RECEIVER_TYPE, 666 LAST_SPEC_OBJECT_TYPE = LAST_JS_RECEIVER_TYPE, 667 // Boundaries for testing the types for which typeof is "object". 668 FIRST_NONCALLABLE_SPEC_OBJECT_TYPE = JS_PROXY_TYPE, 669 LAST_NONCALLABLE_SPEC_OBJECT_TYPE = JS_REGEXP_TYPE, 670 // Note that the types for which typeof is "function" are not continuous. 671 // Define this so that we can put assertions on discrete checks. 672 NUM_OF_CALLABLE_SPEC_OBJECT_TYPES = 2 673 }; 674 675 const int kExternalArrayTypeCount = 676 LAST_EXTERNAL_ARRAY_TYPE - FIRST_EXTERNAL_ARRAY_TYPE + 1; 677 678 STATIC_CHECK(JS_OBJECT_TYPE == Internals::kJSObjectType); 679 STATIC_CHECK(FIRST_NONSTRING_TYPE == Internals::kFirstNonstringType); 680 STATIC_CHECK(FOREIGN_TYPE == Internals::kForeignType); 681 682 683 enum CompareResult { 684 LESS = -1, 685 EQUAL = 0, 686 GREATER = 1, 687 688 NOT_EQUAL = GREATER 689 }; 690 691 692 #define DECL_BOOLEAN_ACCESSORS(name) \ 693 inline bool name(); \ 694 inline void set_##name(bool value); \ 695 696 697 #define DECL_ACCESSORS(name, type) \ 698 inline type* name(); \ 699 inline void set_##name(type* value, \ 700 WriteBarrierMode mode = UPDATE_WRITE_BARRIER); \ 701 702 703 class DictionaryElementsAccessor; 704 class ElementsAccessor; 705 class FixedArrayBase; 706 class ObjectVisitor; 707 class StringStream; 708 class Failure; 709 710 struct ValueInfo : public Malloced { ValueInfoValueInfo711 ValueInfo() : type(FIRST_TYPE), ptr(NULL), str(NULL), number(0) { } 712 InstanceType type; 713 Object* ptr; 714 const char* str; 715 double number; 716 }; 717 718 719 // A template-ized version of the IsXXX functions. 720 template <class C> static inline bool Is(Object* obj); 721 722 723 class MaybeObject BASE_EMBEDDED { 724 public: 725 inline bool IsFailure(); 726 inline bool IsRetryAfterGC(); 727 inline bool IsOutOfMemory(); 728 inline bool IsException(); 729 INLINE(bool IsTheHole()); ToObject(Object ** obj)730 inline bool ToObject(Object** obj) { 731 if (IsFailure()) return false; 732 *obj = reinterpret_cast<Object*>(this); 733 return true; 734 } ToFailureUnchecked()735 inline Failure* ToFailureUnchecked() { 736 ASSERT(IsFailure()); 737 return reinterpret_cast<Failure*>(this); 738 } ToObjectUnchecked()739 inline Object* ToObjectUnchecked() { 740 ASSERT(!IsFailure()); 741 return reinterpret_cast<Object*>(this); 742 } ToObjectChecked()743 inline Object* ToObjectChecked() { 744 CHECK(!IsFailure()); 745 return reinterpret_cast<Object*>(this); 746 } 747 748 template<typename T> To(T ** obj)749 inline bool To(T** obj) { 750 if (IsFailure()) return false; 751 *obj = T::cast(reinterpret_cast<Object*>(this)); 752 return true; 753 } 754 755 #ifdef OBJECT_PRINT 756 // Prints this object with details. Print()757 inline void Print() { 758 Print(stdout); 759 } PrintLn()760 inline void PrintLn() { 761 PrintLn(stdout); 762 } 763 void Print(FILE* out); 764 void PrintLn(FILE* out); 765 #endif 766 #ifdef DEBUG 767 // Verifies the object. 768 void Verify(); 769 #endif 770 }; 771 772 773 #define OBJECT_TYPE_LIST(V) \ 774 V(Smi) \ 775 V(HeapObject) \ 776 V(Number) \ 777 778 #define HEAP_OBJECT_TYPE_LIST(V) \ 779 V(HeapNumber) \ 780 V(String) \ 781 V(Symbol) \ 782 V(SeqString) \ 783 V(ExternalString) \ 784 V(ConsString) \ 785 V(SlicedString) \ 786 V(ExternalTwoByteString) \ 787 V(ExternalAsciiString) \ 788 V(SeqTwoByteString) \ 789 V(SeqAsciiString) \ 790 \ 791 V(ExternalArray) \ 792 V(ExternalByteArray) \ 793 V(ExternalUnsignedByteArray) \ 794 V(ExternalShortArray) \ 795 V(ExternalUnsignedShortArray) \ 796 V(ExternalIntArray) \ 797 V(ExternalUnsignedIntArray) \ 798 V(ExternalFloatArray) \ 799 V(ExternalDoubleArray) \ 800 V(ExternalPixelArray) \ 801 V(ByteArray) \ 802 V(FreeSpace) \ 803 V(JSReceiver) \ 804 V(JSObject) \ 805 V(JSContextExtensionObject) \ 806 V(Map) \ 807 V(DescriptorArray) \ 808 V(DeoptimizationInputData) \ 809 V(DeoptimizationOutputData) \ 810 V(TypeFeedbackCells) \ 811 V(FixedArray) \ 812 V(FixedDoubleArray) \ 813 V(Context) \ 814 V(GlobalContext) \ 815 V(ScopeInfo) \ 816 V(JSFunction) \ 817 V(Code) \ 818 V(Oddball) \ 819 V(SharedFunctionInfo) \ 820 V(JSValue) \ 821 V(JSDate) \ 822 V(JSMessageObject) \ 823 V(StringWrapper) \ 824 V(Foreign) \ 825 V(Boolean) \ 826 V(JSArray) \ 827 V(JSProxy) \ 828 V(JSFunctionProxy) \ 829 V(JSSet) \ 830 V(JSMap) \ 831 V(JSWeakMap) \ 832 V(JSRegExp) \ 833 V(HashTable) \ 834 V(Dictionary) \ 835 V(SymbolTable) \ 836 V(JSFunctionResultCache) \ 837 V(NormalizedMapCache) \ 838 V(CompilationCacheTable) \ 839 V(CodeCacheHashTable) \ 840 V(PolymorphicCodeCacheHashTable) \ 841 V(MapCache) \ 842 V(Primitive) \ 843 V(GlobalObject) \ 844 V(JSGlobalObject) \ 845 V(JSBuiltinsObject) \ 846 V(JSGlobalProxy) \ 847 V(UndetectableObject) \ 848 V(AccessCheckNeeded) \ 849 V(JSGlobalPropertyCell) \ 850 851 852 class JSReceiver; 853 854 // Object is the abstract superclass for all classes in the 855 // object hierarchy. 856 // Object does not use any virtual functions to avoid the 857 // allocation of the C++ vtable. 858 // Since Smi and Failure are subclasses of Object no 859 // data members can be present in Object. 860 class Object : public MaybeObject { 861 public: 862 // Type testing. IsObject()863 bool IsObject() { return true; } 864 865 #define IS_TYPE_FUNCTION_DECL(type_) inline bool Is##type_(); 866 OBJECT_TYPE_LIST(IS_TYPE_FUNCTION_DECL) 867 HEAP_OBJECT_TYPE_LIST(IS_TYPE_FUNCTION_DECL) 868 #undef IS_TYPE_FUNCTION_DECL 869 870 inline bool IsFixedArrayBase(); 871 872 // Returns true if this object is an instance of the specified 873 // function template. 874 inline bool IsInstanceOf(FunctionTemplateInfo* type); 875 876 inline bool IsStruct(); 877 #define DECLARE_STRUCT_PREDICATE(NAME, Name, name) inline bool Is##Name(); 878 STRUCT_LIST(DECLARE_STRUCT_PREDICATE) 879 #undef DECLARE_STRUCT_PREDICATE 880 881 INLINE(bool IsSpecObject()); 882 INLINE(bool IsSpecFunction()); 883 884 // Oddball testing. 885 INLINE(bool IsUndefined()); 886 INLINE(bool IsNull()); 887 INLINE(bool IsTheHole()); // Shadows MaybeObject's implementation. 888 INLINE(bool IsTrue()); 889 INLINE(bool IsFalse()); 890 inline bool IsArgumentsMarker(); 891 inline bool NonFailureIsHeapObject(); 892 893 // Filler objects (fillers and free space objects). 894 inline bool IsFiller(); 895 896 // Extract the number. 897 inline double Number(); 898 inline bool IsNaN(); 899 900 // Returns true if the object is of the correct type to be used as a 901 // implementation of a JSObject's elements. 902 inline bool HasValidElements(); 903 904 inline bool HasSpecificClassOf(String* name); 905 906 MUST_USE_RESULT MaybeObject* ToObject(); // ECMA-262 9.9. 907 Object* ToBoolean(); // ECMA-262 9.2. 908 909 // Convert to a JSObject if needed. 910 // global_context is used when creating wrapper object. 911 MUST_USE_RESULT MaybeObject* ToObject(Context* global_context); 912 913 // Converts this to a Smi if possible. 914 // Failure is returned otherwise. 915 MUST_USE_RESULT inline MaybeObject* ToSmi(); 916 917 void Lookup(String* name, LookupResult* result); 918 919 // Property access. 920 MUST_USE_RESULT inline MaybeObject* GetProperty(String* key); 921 MUST_USE_RESULT inline MaybeObject* GetProperty( 922 String* key, 923 PropertyAttributes* attributes); 924 MUST_USE_RESULT MaybeObject* GetPropertyWithReceiver( 925 Object* receiver, 926 String* key, 927 PropertyAttributes* attributes); 928 929 static Handle<Object> GetProperty(Handle<Object> object, 930 Handle<Object> receiver, 931 LookupResult* result, 932 Handle<String> key, 933 PropertyAttributes* attributes); 934 935 MUST_USE_RESULT MaybeObject* GetProperty(Object* receiver, 936 LookupResult* result, 937 String* key, 938 PropertyAttributes* attributes); 939 940 MUST_USE_RESULT MaybeObject* GetPropertyWithDefinedGetter(Object* receiver, 941 JSReceiver* getter); 942 943 static Handle<Object> GetElement(Handle<Object> object, uint32_t index); 944 MUST_USE_RESULT inline MaybeObject* GetElement(uint32_t index); 945 // For use when we know that no exception can be thrown. 946 inline Object* GetElementNoExceptionThrown(uint32_t index); 947 MUST_USE_RESULT MaybeObject* GetElementWithReceiver(Object* receiver, 948 uint32_t index); 949 950 // Return the object's prototype (might be Heap::null_value()). 951 Object* GetPrototype(); 952 953 // Returns the permanent hash code associated with this object depending on 954 // the actual object type. Might return a failure in case no hash was 955 // created yet or GC was caused by creation. 956 MUST_USE_RESULT MaybeObject* GetHash(CreationFlag flag); 957 958 // Checks whether this object has the same value as the given one. This 959 // function is implemented according to ES5, section 9.12 and can be used 960 // to implement the Harmony "egal" function. 961 bool SameValue(Object* other); 962 963 // Tries to convert an object to an array index. Returns true and sets 964 // the output parameter if it succeeds. 965 inline bool ToArrayIndex(uint32_t* index); 966 967 // Returns true if this is a JSValue containing a string and the index is 968 // < the length of the string. Used to implement [] on strings. 969 inline bool IsStringObjectWithCharacterAt(uint32_t index); 970 971 #ifdef DEBUG 972 // Verify a pointer is a valid object pointer. 973 static void VerifyPointer(Object* p); 974 #endif 975 976 // Prints this object without details. ShortPrint()977 inline void ShortPrint() { 978 ShortPrint(stdout); 979 } 980 void ShortPrint(FILE* out); 981 982 // Prints this object without details to a message accumulator. 983 void ShortPrint(StringStream* accumulator); 984 985 // Casting: This cast is only needed to satisfy macros in objects-inl.h. cast(Object * value)986 static Object* cast(Object* value) { return value; } 987 988 // Layout description. 989 static const int kHeaderSize = 0; // Object does not take up any space. 990 991 private: 992 DISALLOW_IMPLICIT_CONSTRUCTORS(Object); 993 }; 994 995 996 // Smi represents integer Numbers that can be stored in 31 bits. 997 // Smis are immediate which means they are NOT allocated in the heap. 998 // The this pointer has the following format: [31 bit signed int] 0 999 // For long smis it has the following format: 1000 // [32 bit signed int] [31 bits zero padding] 0 1001 // Smi stands for small integer. 1002 class Smi: public Object { 1003 public: 1004 // Returns the integer value. 1005 inline int value(); 1006 1007 // Convert a value to a Smi object. 1008 static inline Smi* FromInt(int value); 1009 1010 static inline Smi* FromIntptr(intptr_t value); 1011 1012 // Returns whether value can be represented in a Smi. 1013 static inline bool IsValid(intptr_t value); 1014 1015 // Casting. 1016 static inline Smi* cast(Object* object); 1017 1018 // Dispatched behavior. SmiPrint()1019 inline void SmiPrint() { 1020 SmiPrint(stdout); 1021 } 1022 void SmiPrint(FILE* out); 1023 void SmiPrint(StringStream* accumulator); 1024 #ifdef DEBUG 1025 void SmiVerify(); 1026 #endif 1027 1028 static const int kMinValue = 1029 (static_cast<unsigned int>(-1)) << (kSmiValueSize - 1); 1030 static const int kMaxValue = -(kMinValue + 1); 1031 1032 private: 1033 DISALLOW_IMPLICIT_CONSTRUCTORS(Smi); 1034 }; 1035 1036 1037 // Failure is used for reporting out of memory situations and 1038 // propagating exceptions through the runtime system. Failure objects 1039 // are transient and cannot occur as part of the object graph. 1040 // 1041 // Failures are a single word, encoded as follows: 1042 // +-------------------------+---+--+--+ 1043 // |.........unused..........|sss|tt|11| 1044 // +-------------------------+---+--+--+ 1045 // 7 6 4 32 10 1046 // 1047 // 1048 // The low two bits, 0-1, are the failure tag, 11. The next two bits, 1049 // 2-3, are a failure type tag 'tt' with possible values: 1050 // 00 RETRY_AFTER_GC 1051 // 01 EXCEPTION 1052 // 10 INTERNAL_ERROR 1053 // 11 OUT_OF_MEMORY_EXCEPTION 1054 // 1055 // The next three bits, 4-6, are an allocation space tag 'sss'. The 1056 // allocation space tag is 000 for all failure types except 1057 // RETRY_AFTER_GC. For RETRY_AFTER_GC, the possible values are the 1058 // allocation spaces (the encoding is found in globals.h). 1059 1060 // Failure type tag info. 1061 const int kFailureTypeTagSize = 2; 1062 const int kFailureTypeTagMask = (1 << kFailureTypeTagSize) - 1; 1063 1064 class Failure: public MaybeObject { 1065 public: 1066 // RuntimeStubs assumes EXCEPTION = 1 in the compiler-generated code. 1067 enum Type { 1068 RETRY_AFTER_GC = 0, 1069 EXCEPTION = 1, // Returning this marker tells the real exception 1070 // is in Isolate::pending_exception. 1071 INTERNAL_ERROR = 2, 1072 OUT_OF_MEMORY_EXCEPTION = 3 1073 }; 1074 1075 inline Type type() const; 1076 1077 // Returns the space that needs to be collected for RetryAfterGC failures. 1078 inline AllocationSpace allocation_space() const; 1079 1080 inline bool IsInternalError() const; 1081 inline bool IsOutOfMemoryException() const; 1082 1083 static inline Failure* RetryAfterGC(AllocationSpace space); 1084 static inline Failure* RetryAfterGC(); // NEW_SPACE 1085 static inline Failure* Exception(); 1086 static inline Failure* InternalError(); 1087 static inline Failure* OutOfMemoryException(); 1088 // Casting. 1089 static inline Failure* cast(MaybeObject* object); 1090 1091 // Dispatched behavior. FailurePrint()1092 inline void FailurePrint() { 1093 FailurePrint(stdout); 1094 } 1095 void FailurePrint(FILE* out); 1096 void FailurePrint(StringStream* accumulator); 1097 #ifdef DEBUG 1098 void FailureVerify(); 1099 #endif 1100 1101 private: 1102 inline intptr_t value() const; 1103 static inline Failure* Construct(Type type, intptr_t value = 0); 1104 1105 DISALLOW_IMPLICIT_CONSTRUCTORS(Failure); 1106 }; 1107 1108 1109 // Heap objects typically have a map pointer in their first word. However, 1110 // during GC other data (e.g. mark bits, forwarding addresses) is sometimes 1111 // encoded in the first word. The class MapWord is an abstraction of the 1112 // value in a heap object's first word. 1113 class MapWord BASE_EMBEDDED { 1114 public: 1115 // Normal state: the map word contains a map pointer. 1116 1117 // Create a map word from a map pointer. 1118 static inline MapWord FromMap(Map* map); 1119 1120 // View this map word as a map pointer. 1121 inline Map* ToMap(); 1122 1123 1124 // Scavenge collection: the map word of live objects in the from space 1125 // contains a forwarding address (a heap object pointer in the to space). 1126 1127 // True if this map word is a forwarding address for a scavenge 1128 // collection. Only valid during a scavenge collection (specifically, 1129 // when all map words are heap object pointers, i.e. not during a full GC). 1130 inline bool IsForwardingAddress(); 1131 1132 // Create a map word from a forwarding address. 1133 static inline MapWord FromForwardingAddress(HeapObject* object); 1134 1135 // View this map word as a forwarding address. 1136 inline HeapObject* ToForwardingAddress(); 1137 FromRawValue(uintptr_t value)1138 static inline MapWord FromRawValue(uintptr_t value) { 1139 return MapWord(value); 1140 } 1141 ToRawValue()1142 inline uintptr_t ToRawValue() { 1143 return value_; 1144 } 1145 1146 private: 1147 // HeapObject calls the private constructor and directly reads the value. 1148 friend class HeapObject; 1149 MapWord(uintptr_t value)1150 explicit MapWord(uintptr_t value) : value_(value) {} 1151 1152 uintptr_t value_; 1153 }; 1154 1155 1156 // HeapObject is the superclass for all classes describing heap allocated 1157 // objects. 1158 class HeapObject: public Object { 1159 public: 1160 // [map]: Contains a map which contains the object's reflective 1161 // information. 1162 inline Map* map(); 1163 inline void set_map(Map* value); 1164 // The no-write-barrier version. This is OK if the object is white and in 1165 // new space, or if the value is an immortal immutable object, like the maps 1166 // of primitive (non-JS) objects like strings, heap numbers etc. 1167 inline void set_map_no_write_barrier(Map* value); 1168 1169 // During garbage collection, the map word of a heap object does not 1170 // necessarily contain a map pointer. 1171 inline MapWord map_word(); 1172 inline void set_map_word(MapWord map_word); 1173 1174 // The Heap the object was allocated in. Used also to access Isolate. 1175 inline Heap* GetHeap(); 1176 1177 // Convenience method to get current isolate. This method can be 1178 // accessed only when its result is the same as 1179 // Isolate::Current(), it ASSERTs this. See also comment for GetHeap. 1180 inline Isolate* GetIsolate(); 1181 1182 // Converts an address to a HeapObject pointer. 1183 static inline HeapObject* FromAddress(Address address); 1184 1185 // Returns the address of this HeapObject. 1186 inline Address address(); 1187 1188 // Iterates over pointers contained in the object (including the Map) 1189 void Iterate(ObjectVisitor* v); 1190 1191 // Iterates over all pointers contained in the object except the 1192 // first map pointer. The object type is given in the first 1193 // parameter. This function does not access the map pointer in the 1194 // object, and so is safe to call while the map pointer is modified. 1195 void IterateBody(InstanceType type, int object_size, ObjectVisitor* v); 1196 1197 // Returns the heap object's size in bytes 1198 inline int Size(); 1199 1200 // Given a heap object's map pointer, returns the heap size in bytes 1201 // Useful when the map pointer field is used for other purposes. 1202 // GC internal. 1203 inline int SizeFromMap(Map* map); 1204 1205 // Returns the field at offset in obj, as a read/write Object* reference. 1206 // Does no checking, and is safe to use during GC, while maps are invalid. 1207 // Does not invoke write barrier, so should only be assigned to 1208 // during marking GC. 1209 static inline Object** RawField(HeapObject* obj, int offset); 1210 1211 // Casting. 1212 static inline HeapObject* cast(Object* obj); 1213 1214 // Return the write barrier mode for this. Callers of this function 1215 // must be able to present a reference to an AssertNoAllocation 1216 // object as a sign that they are not going to use this function 1217 // from code that allocates and thus invalidates the returned write 1218 // barrier mode. 1219 inline WriteBarrierMode GetWriteBarrierMode(const AssertNoAllocation&); 1220 1221 // Dispatched behavior. 1222 void HeapObjectShortPrint(StringStream* accumulator); 1223 #ifdef OBJECT_PRINT HeapObjectPrint()1224 inline void HeapObjectPrint() { 1225 HeapObjectPrint(stdout); 1226 } 1227 void HeapObjectPrint(FILE* out); 1228 void PrintHeader(FILE* out, const char* id); 1229 #endif 1230 1231 #ifdef DEBUG 1232 void HeapObjectVerify(); 1233 inline void VerifyObjectField(int offset); 1234 inline void VerifySmiField(int offset); 1235 1236 // Verify a pointer is a valid HeapObject pointer that points to object 1237 // areas in the heap. 1238 static void VerifyHeapPointer(Object* p); 1239 #endif 1240 1241 // Layout description. 1242 // First field in a heap object is map. 1243 static const int kMapOffset = Object::kHeaderSize; 1244 static const int kHeaderSize = kMapOffset + kPointerSize; 1245 1246 STATIC_CHECK(kMapOffset == Internals::kHeapObjectMapOffset); 1247 1248 protected: 1249 // helpers for calling an ObjectVisitor to iterate over pointers in the 1250 // half-open range [start, end) specified as integer offsets 1251 inline void IteratePointers(ObjectVisitor* v, int start, int end); 1252 // as above, for the single element at "offset" 1253 inline void IteratePointer(ObjectVisitor* v, int offset); 1254 1255 private: 1256 DISALLOW_IMPLICIT_CONSTRUCTORS(HeapObject); 1257 }; 1258 1259 1260 #define SLOT_ADDR(obj, offset) \ 1261 reinterpret_cast<Object**>((obj)->address() + offset) 1262 1263 // This class describes a body of an object of a fixed size 1264 // in which all pointer fields are located in the [start_offset, end_offset) 1265 // interval. 1266 template<int start_offset, int end_offset, int size> 1267 class FixedBodyDescriptor { 1268 public: 1269 static const int kStartOffset = start_offset; 1270 static const int kEndOffset = end_offset; 1271 static const int kSize = size; 1272 1273 static inline void IterateBody(HeapObject* obj, ObjectVisitor* v); 1274 1275 template<typename StaticVisitor> IterateBody(HeapObject * obj)1276 static inline void IterateBody(HeapObject* obj) { 1277 StaticVisitor::VisitPointers(SLOT_ADDR(obj, start_offset), 1278 SLOT_ADDR(obj, end_offset)); 1279 } 1280 }; 1281 1282 1283 // This class describes a body of an object of a variable size 1284 // in which all pointer fields are located in the [start_offset, object_size) 1285 // interval. 1286 template<int start_offset> 1287 class FlexibleBodyDescriptor { 1288 public: 1289 static const int kStartOffset = start_offset; 1290 1291 static inline void IterateBody(HeapObject* obj, 1292 int object_size, 1293 ObjectVisitor* v); 1294 1295 template<typename StaticVisitor> IterateBody(HeapObject * obj,int object_size)1296 static inline void IterateBody(HeapObject* obj, int object_size) { 1297 StaticVisitor::VisitPointers(SLOT_ADDR(obj, start_offset), 1298 SLOT_ADDR(obj, object_size)); 1299 } 1300 }; 1301 1302 #undef SLOT_ADDR 1303 1304 1305 // The HeapNumber class describes heap allocated numbers that cannot be 1306 // represented in a Smi (small integer) 1307 class HeapNumber: public HeapObject { 1308 public: 1309 // [value]: number value. 1310 inline double value(); 1311 inline void set_value(double value); 1312 1313 // Casting. 1314 static inline HeapNumber* cast(Object* obj); 1315 1316 // Dispatched behavior. 1317 Object* HeapNumberToBoolean(); HeapNumberPrint()1318 inline void HeapNumberPrint() { 1319 HeapNumberPrint(stdout); 1320 } 1321 void HeapNumberPrint(FILE* out); 1322 void HeapNumberPrint(StringStream* accumulator); 1323 #ifdef DEBUG 1324 void HeapNumberVerify(); 1325 #endif 1326 1327 inline int get_exponent(); 1328 inline int get_sign(); 1329 1330 // Layout description. 1331 static const int kValueOffset = HeapObject::kHeaderSize; 1332 // IEEE doubles are two 32 bit words. The first is just mantissa, the second 1333 // is a mixture of sign, exponent and mantissa. Our current platforms are all 1334 // little endian apart from non-EABI arm which is little endian with big 1335 // endian floating point word ordering! 1336 static const int kMantissaOffset = kValueOffset; 1337 static const int kExponentOffset = kValueOffset + 4; 1338 1339 static const int kSize = kValueOffset + kDoubleSize; 1340 static const uint32_t kSignMask = 0x80000000u; 1341 static const uint32_t kExponentMask = 0x7ff00000u; 1342 static const uint32_t kMantissaMask = 0xfffffu; 1343 static const int kMantissaBits = 52; 1344 static const int kExponentBits = 11; 1345 static const int kExponentBias = 1023; 1346 static const int kExponentShift = 20; 1347 static const int kMantissaBitsInTopWord = 20; 1348 static const int kNonMantissaBitsInTopWord = 12; 1349 1350 private: 1351 DISALLOW_IMPLICIT_CONSTRUCTORS(HeapNumber); 1352 }; 1353 1354 1355 enum EnsureElementsMode { 1356 DONT_ALLOW_DOUBLE_ELEMENTS, 1357 ALLOW_COPIED_DOUBLE_ELEMENTS, 1358 ALLOW_CONVERTED_DOUBLE_ELEMENTS 1359 }; 1360 1361 1362 // Indicates whether a property should be set or (re)defined. Setting of a 1363 // property causes attributes to remain unchanged, writability to be checked 1364 // and callbacks to be called. Defining of a property causes attributes to 1365 // be updated and callbacks to be overridden. 1366 enum SetPropertyMode { 1367 SET_PROPERTY, 1368 DEFINE_PROPERTY 1369 }; 1370 1371 1372 // Indicator for one component of an AccessorPair. 1373 enum AccessorComponent { 1374 ACCESSOR_GETTER, 1375 ACCESSOR_SETTER 1376 }; 1377 1378 1379 // JSReceiver includes types on which properties can be defined, i.e., 1380 // JSObject and JSProxy. 1381 class JSReceiver: public HeapObject { 1382 public: 1383 enum DeleteMode { 1384 NORMAL_DELETION, 1385 STRICT_DELETION, 1386 FORCE_DELETION 1387 }; 1388 1389 // Casting. 1390 static inline JSReceiver* cast(Object* obj); 1391 1392 static Handle<Object> SetProperty(Handle<JSReceiver> object, 1393 Handle<String> key, 1394 Handle<Object> value, 1395 PropertyAttributes attributes, 1396 StrictModeFlag strict_mode); 1397 // Can cause GC. 1398 MUST_USE_RESULT MaybeObject* SetProperty(String* key, 1399 Object* value, 1400 PropertyAttributes attributes, 1401 StrictModeFlag strict_mode); 1402 MUST_USE_RESULT MaybeObject* SetProperty(LookupResult* result, 1403 String* key, 1404 Object* value, 1405 PropertyAttributes attributes, 1406 StrictModeFlag strict_mode); 1407 MUST_USE_RESULT MaybeObject* SetPropertyWithDefinedSetter(JSReceiver* setter, 1408 Object* value); 1409 1410 MUST_USE_RESULT MaybeObject* DeleteProperty(String* name, DeleteMode mode); 1411 MUST_USE_RESULT MaybeObject* DeleteElement(uint32_t index, DeleteMode mode); 1412 1413 // Set the index'th array element. 1414 // Can cause GC, or return failure if GC is required. 1415 MUST_USE_RESULT MaybeObject* SetElement(uint32_t index, 1416 Object* value, 1417 PropertyAttributes attributes, 1418 StrictModeFlag strict_mode, 1419 bool check_prototype); 1420 1421 // Tests for the fast common case for property enumeration. 1422 bool IsSimpleEnum(); 1423 1424 // Returns the class name ([[Class]] property in the specification). 1425 String* class_name(); 1426 1427 // Returns the constructor name (the name (possibly, inferred name) of the 1428 // function that was used to instantiate the object). 1429 String* constructor_name(); 1430 1431 inline PropertyAttributes GetPropertyAttribute(String* name); 1432 PropertyAttributes GetPropertyAttributeWithReceiver(JSReceiver* receiver, 1433 String* name); 1434 PropertyAttributes GetLocalPropertyAttribute(String* name); 1435 1436 // Can cause a GC. 1437 inline bool HasProperty(String* name); 1438 inline bool HasLocalProperty(String* name); 1439 inline bool HasElement(uint32_t index); 1440 1441 // Return the object's prototype (might be Heap::null_value()). 1442 inline Object* GetPrototype(); 1443 1444 // Set the object's prototype (only JSReceiver and null are allowed). 1445 MUST_USE_RESULT MaybeObject* SetPrototype(Object* value, 1446 bool skip_hidden_prototypes); 1447 1448 // Retrieves a permanent object identity hash code. The undefined value might 1449 // be returned in case no hash was created yet and OMIT_CREATION was used. 1450 inline MUST_USE_RESULT MaybeObject* GetIdentityHash(CreationFlag flag); 1451 1452 // Lookup a property. If found, the result is valid and has 1453 // detailed information. 1454 void LocalLookup(String* name, LookupResult* result); 1455 void Lookup(String* name, LookupResult* result); 1456 1457 protected: 1458 Smi* GenerateIdentityHash(); 1459 1460 private: 1461 PropertyAttributes GetPropertyAttribute(JSReceiver* receiver, 1462 LookupResult* result, 1463 String* name, 1464 bool continue_search); 1465 1466 DISALLOW_IMPLICIT_CONSTRUCTORS(JSReceiver); 1467 }; 1468 1469 // The JSObject describes real heap allocated JavaScript objects with 1470 // properties. 1471 // Note that the map of JSObject changes during execution to enable inline 1472 // caching. 1473 class JSObject: public JSReceiver { 1474 public: 1475 // [properties]: Backing storage for properties. 1476 // properties is a FixedArray in the fast case and a Dictionary in the 1477 // slow case. 1478 DECL_ACCESSORS(properties, FixedArray) // Get and set fast properties. 1479 inline void initialize_properties(); 1480 inline bool HasFastProperties(); 1481 inline StringDictionary* property_dictionary(); // Gets slow properties. 1482 1483 // [elements]: The elements (properties with names that are integers). 1484 // 1485 // Elements can be in two general modes: fast and slow. Each mode 1486 // corrensponds to a set of object representations of elements that 1487 // have something in common. 1488 // 1489 // In the fast mode elements is a FixedArray and so each element can 1490 // be quickly accessed. This fact is used in the generated code. The 1491 // elements array can have one of three maps in this mode: 1492 // fixed_array_map, non_strict_arguments_elements_map or 1493 // fixed_cow_array_map (for copy-on-write arrays). In the latter case 1494 // the elements array may be shared by a few objects and so before 1495 // writing to any element the array must be copied. Use 1496 // EnsureWritableFastElements in this case. 1497 // 1498 // In the slow mode the elements is either a NumberDictionary, an 1499 // ExternalArray, or a FixedArray parameter map for a (non-strict) 1500 // arguments object. 1501 DECL_ACCESSORS(elements, FixedArrayBase) 1502 inline void initialize_elements(); 1503 MUST_USE_RESULT inline MaybeObject* ResetElements(); 1504 inline ElementsKind GetElementsKind(); 1505 inline ElementsAccessor* GetElementsAccessor(); 1506 inline bool HasFastSmiOnlyElements(); 1507 inline bool HasFastElements(); 1508 // Returns if an object has either FAST_ELEMENT or FAST_SMI_ONLY_ELEMENT 1509 // elements. TODO(danno): Rename HasFastTypeElements to HasFastElements() and 1510 // HasFastElements to HasFastObjectElements. 1511 inline bool HasFastTypeElements(); 1512 inline bool HasFastDoubleElements(); 1513 inline bool HasNonStrictArgumentsElements(); 1514 inline bool HasDictionaryElements(); 1515 inline bool HasExternalPixelElements(); 1516 inline bool HasExternalArrayElements(); 1517 inline bool HasExternalByteElements(); 1518 inline bool HasExternalUnsignedByteElements(); 1519 inline bool HasExternalShortElements(); 1520 inline bool HasExternalUnsignedShortElements(); 1521 inline bool HasExternalIntElements(); 1522 inline bool HasExternalUnsignedIntElements(); 1523 inline bool HasExternalFloatElements(); 1524 inline bool HasExternalDoubleElements(); 1525 bool HasFastArgumentsElements(); 1526 bool HasDictionaryArgumentsElements(); 1527 inline SeededNumberDictionary* element_dictionary(); // Gets slow elements. 1528 1529 inline void set_map_and_elements( 1530 Map* map, 1531 FixedArrayBase* value, 1532 WriteBarrierMode mode = UPDATE_WRITE_BARRIER); 1533 1534 // Requires: HasFastElements(). 1535 MUST_USE_RESULT inline MaybeObject* EnsureWritableFastElements(); 1536 1537 // Collects elements starting at index 0. 1538 // Undefined values are placed after non-undefined values. 1539 // Returns the number of non-undefined values. 1540 MUST_USE_RESULT MaybeObject* PrepareElementsForSort(uint32_t limit); 1541 // As PrepareElementsForSort, but only on objects where elements is 1542 // a dictionary, and it will stay a dictionary. 1543 MUST_USE_RESULT MaybeObject* PrepareSlowElementsForSort(uint32_t limit); 1544 1545 MUST_USE_RESULT MaybeObject* GetPropertyWithCallback(Object* receiver, 1546 Object* structure, 1547 String* name); 1548 1549 // Can cause GC. 1550 MUST_USE_RESULT MaybeObject* SetPropertyForResult(LookupResult* result, 1551 String* key, 1552 Object* value, 1553 PropertyAttributes attributes, 1554 StrictModeFlag strict_mode); 1555 MUST_USE_RESULT MaybeObject* SetPropertyWithFailedAccessCheck( 1556 LookupResult* result, 1557 String* name, 1558 Object* value, 1559 bool check_prototype, 1560 StrictModeFlag strict_mode); 1561 MUST_USE_RESULT MaybeObject* SetPropertyWithCallback( 1562 Object* structure, 1563 String* name, 1564 Object* value, 1565 JSObject* holder, 1566 StrictModeFlag strict_mode); 1567 MUST_USE_RESULT MaybeObject* SetPropertyWithInterceptor( 1568 String* name, 1569 Object* value, 1570 PropertyAttributes attributes, 1571 StrictModeFlag strict_mode); 1572 MUST_USE_RESULT MaybeObject* SetPropertyPostInterceptor( 1573 String* name, 1574 Object* value, 1575 PropertyAttributes attributes, 1576 StrictModeFlag strict_mode); 1577 1578 static Handle<Object> SetLocalPropertyIgnoreAttributes( 1579 Handle<JSObject> object, 1580 Handle<String> key, 1581 Handle<Object> value, 1582 PropertyAttributes attributes); 1583 1584 // Can cause GC. 1585 MUST_USE_RESULT MaybeObject* SetLocalPropertyIgnoreAttributes( 1586 String* key, 1587 Object* value, 1588 PropertyAttributes attributes); 1589 1590 // Retrieve a value in a normalized object given a lookup result. 1591 // Handles the special representation of JS global objects. 1592 Object* GetNormalizedProperty(LookupResult* result); 1593 1594 // Sets the property value in a normalized object given a lookup result. 1595 // Handles the special representation of JS global objects. 1596 Object* SetNormalizedProperty(LookupResult* result, Object* value); 1597 1598 // Sets the property value in a normalized object given (key, value, details). 1599 // Handles the special representation of JS global objects. 1600 static Handle<Object> SetNormalizedProperty(Handle<JSObject> object, 1601 Handle<String> key, 1602 Handle<Object> value, 1603 PropertyDetails details); 1604 1605 MUST_USE_RESULT MaybeObject* SetNormalizedProperty(String* name, 1606 Object* value, 1607 PropertyDetails details); 1608 1609 // Deletes the named property in a normalized object. 1610 MUST_USE_RESULT MaybeObject* DeleteNormalizedProperty(String* name, 1611 DeleteMode mode); 1612 1613 // Retrieve interceptors. 1614 InterceptorInfo* GetNamedInterceptor(); 1615 InterceptorInfo* GetIndexedInterceptor(); 1616 1617 // Used from JSReceiver. 1618 PropertyAttributes GetPropertyAttributePostInterceptor(JSObject* receiver, 1619 String* name, 1620 bool continue_search); 1621 PropertyAttributes GetPropertyAttributeWithInterceptor(JSObject* receiver, 1622 String* name, 1623 bool continue_search); 1624 PropertyAttributes GetPropertyAttributeWithFailedAccessCheck( 1625 Object* receiver, 1626 LookupResult* result, 1627 String* name, 1628 bool continue_search); 1629 1630 static void DefineAccessor(Handle<JSObject> object, 1631 Handle<String> name, 1632 Handle<Object> getter, 1633 Handle<Object> setter, 1634 PropertyAttributes attributes); 1635 MUST_USE_RESULT MaybeObject* DefineAccessor(String* name, 1636 Object* getter, 1637 Object* setter, 1638 PropertyAttributes attributes); 1639 Object* LookupAccessor(String* name, AccessorComponent component); 1640 1641 MUST_USE_RESULT MaybeObject* DefineAccessor(AccessorInfo* info); 1642 1643 // Used from Object::GetProperty(). 1644 MUST_USE_RESULT MaybeObject* GetPropertyWithFailedAccessCheck( 1645 Object* receiver, 1646 LookupResult* result, 1647 String* name, 1648 PropertyAttributes* attributes); 1649 MUST_USE_RESULT MaybeObject* GetPropertyWithInterceptor( 1650 JSReceiver* receiver, 1651 String* name, 1652 PropertyAttributes* attributes); 1653 MUST_USE_RESULT MaybeObject* GetPropertyPostInterceptor( 1654 JSReceiver* receiver, 1655 String* name, 1656 PropertyAttributes* attributes); 1657 MUST_USE_RESULT MaybeObject* GetLocalPropertyPostInterceptor( 1658 JSReceiver* receiver, 1659 String* name, 1660 PropertyAttributes* attributes); 1661 1662 // Returns true if this is an instance of an api function and has 1663 // been modified since it was created. May give false positives. 1664 bool IsDirty(); 1665 1666 // If the receiver is a JSGlobalProxy this method will return its prototype, 1667 // otherwise the result is the receiver itself. 1668 inline Object* BypassGlobalProxy(); 1669 1670 // Accessors for hidden properties object. 1671 // 1672 // Hidden properties are not local properties of the object itself. 1673 // Instead they are stored in an auxiliary structure kept as a local 1674 // property with a special name Heap::hidden_symbol(). But if the 1675 // receiver is a JSGlobalProxy then the auxiliary object is a property 1676 // of its prototype, and if it's a detached proxy, then you can't have 1677 // hidden properties. 1678 1679 // Sets a hidden property on this object. Returns this object if successful, 1680 // undefined if called on a detached proxy. 1681 static Handle<Object> SetHiddenProperty(Handle<JSObject> obj, 1682 Handle<String> key, 1683 Handle<Object> value); 1684 // Returns a failure if a GC is required. 1685 MUST_USE_RESULT MaybeObject* SetHiddenProperty(String* key, Object* value); 1686 // Gets the value of a hidden property with the given key. Returns undefined 1687 // if the property doesn't exist (or if called on a detached proxy), 1688 // otherwise returns the value set for the key. 1689 Object* GetHiddenProperty(String* key); 1690 // Deletes a hidden property. Deleting a non-existing property is 1691 // considered successful. 1692 void DeleteHiddenProperty(String* key); 1693 // Returns true if the object has a property with the hidden symbol as name. 1694 bool HasHiddenProperties(); 1695 1696 static int GetIdentityHash(Handle<JSObject> obj); 1697 MUST_USE_RESULT MaybeObject* GetIdentityHash(CreationFlag flag); 1698 MUST_USE_RESULT MaybeObject* SetIdentityHash(Object* hash, CreationFlag flag); 1699 1700 static Handle<Object> DeleteProperty(Handle<JSObject> obj, 1701 Handle<String> name); 1702 MUST_USE_RESULT MaybeObject* DeleteProperty(String* name, DeleteMode mode); 1703 1704 static Handle<Object> DeleteElement(Handle<JSObject> obj, uint32_t index); 1705 MUST_USE_RESULT MaybeObject* DeleteElement(uint32_t index, DeleteMode mode); 1706 1707 inline void ValidateSmiOnlyElements(); 1708 1709 // Makes sure that this object can contain HeapObject as elements. 1710 MUST_USE_RESULT inline MaybeObject* EnsureCanContainHeapObjectElements(); 1711 1712 // Makes sure that this object can contain the specified elements. 1713 MUST_USE_RESULT inline MaybeObject* EnsureCanContainElements( 1714 Object** elements, 1715 uint32_t count, 1716 EnsureElementsMode mode); 1717 MUST_USE_RESULT inline MaybeObject* EnsureCanContainElements( 1718 FixedArrayBase* elements, 1719 EnsureElementsMode mode); 1720 MUST_USE_RESULT MaybeObject* EnsureCanContainElements( 1721 Arguments* arguments, 1722 uint32_t first_arg, 1723 uint32_t arg_count, 1724 EnsureElementsMode mode); 1725 1726 // Do we want to keep the elements in fast case when increasing the 1727 // capacity? 1728 bool ShouldConvertToSlowElements(int new_capacity); 1729 // Returns true if the backing storage for the slow-case elements of 1730 // this object takes up nearly as much space as a fast-case backing 1731 // storage would. In that case the JSObject should have fast 1732 // elements. 1733 bool ShouldConvertToFastElements(); 1734 // Returns true if the elements of JSObject contains only values that can be 1735 // represented in a FixedDoubleArray and has at least one value that can only 1736 // be represented as a double and not a Smi. 1737 bool ShouldConvertToFastDoubleElements(bool* has_smi_only_elements); 1738 1739 // Tells whether the index'th element is present. 1740 bool HasElementWithReceiver(JSReceiver* receiver, uint32_t index); 1741 1742 // Computes the new capacity when expanding the elements of a JSObject. NewElementsCapacity(int old_capacity)1743 static int NewElementsCapacity(int old_capacity) { 1744 // (old_capacity + 50%) + 16 1745 return old_capacity + (old_capacity >> 1) + 16; 1746 } 1747 1748 // Tells whether the index'th element is present and how it is stored. 1749 enum LocalElementType { 1750 // There is no element with given index. 1751 UNDEFINED_ELEMENT, 1752 1753 // Element with given index is handled by interceptor. 1754 INTERCEPTED_ELEMENT, 1755 1756 // Element with given index is character in string. 1757 STRING_CHARACTER_ELEMENT, 1758 1759 // Element with given index is stored in fast backing store. 1760 FAST_ELEMENT, 1761 1762 // Element with given index is stored in slow backing store. 1763 DICTIONARY_ELEMENT 1764 }; 1765 1766 LocalElementType HasLocalElement(uint32_t index); 1767 1768 bool HasElementWithInterceptor(JSReceiver* receiver, uint32_t index); 1769 1770 MUST_USE_RESULT MaybeObject* SetFastElement(uint32_t index, 1771 Object* value, 1772 StrictModeFlag strict_mode, 1773 bool check_prototype); 1774 1775 MUST_USE_RESULT MaybeObject* SetDictionaryElement( 1776 uint32_t index, 1777 Object* value, 1778 PropertyAttributes attributes, 1779 StrictModeFlag strict_mode, 1780 bool check_prototype, 1781 SetPropertyMode set_mode = SET_PROPERTY); 1782 1783 MUST_USE_RESULT MaybeObject* SetFastDoubleElement( 1784 uint32_t index, 1785 Object* value, 1786 StrictModeFlag strict_mode, 1787 bool check_prototype = true); 1788 1789 static Handle<Object> SetOwnElement(Handle<JSObject> object, 1790 uint32_t index, 1791 Handle<Object> value, 1792 StrictModeFlag strict_mode); 1793 1794 // Empty handle is returned if the element cannot be set to the given value. 1795 static MUST_USE_RESULT Handle<Object> SetElement( 1796 Handle<JSObject> object, 1797 uint32_t index, 1798 Handle<Object> value, 1799 PropertyAttributes attr, 1800 StrictModeFlag strict_mode, 1801 SetPropertyMode set_mode = SET_PROPERTY); 1802 1803 // A Failure object is returned if GC is needed. 1804 MUST_USE_RESULT MaybeObject* SetElement( 1805 uint32_t index, 1806 Object* value, 1807 PropertyAttributes attributes, 1808 StrictModeFlag strict_mode, 1809 bool check_prototype = true, 1810 SetPropertyMode set_mode = SET_PROPERTY); 1811 1812 // Returns the index'th element. 1813 // The undefined object if index is out of bounds. 1814 MUST_USE_RESULT MaybeObject* GetElementWithInterceptor(Object* receiver, 1815 uint32_t index); 1816 1817 enum SetFastElementsCapacityMode { 1818 kAllowSmiOnlyElements, 1819 kForceSmiOnlyElements, 1820 kDontAllowSmiOnlyElements 1821 }; 1822 1823 // Replace the elements' backing store with fast elements of the given 1824 // capacity. Update the length for JSArrays. Returns the new backing 1825 // store. 1826 MUST_USE_RESULT MaybeObject* SetFastElementsCapacityAndLength( 1827 int capacity, 1828 int length, 1829 SetFastElementsCapacityMode set_capacity_mode); 1830 MUST_USE_RESULT MaybeObject* SetFastDoubleElementsCapacityAndLength( 1831 int capacity, 1832 int length); 1833 1834 // Lookup interceptors are used for handling properties controlled by host 1835 // objects. 1836 inline bool HasNamedInterceptor(); 1837 inline bool HasIndexedInterceptor(); 1838 1839 // Support functions for v8 api (needed for correct interceptor behavior). 1840 bool HasRealNamedProperty(String* key); 1841 bool HasRealElementProperty(uint32_t index); 1842 bool HasRealNamedCallbackProperty(String* key); 1843 1844 // Get the header size for a JSObject. Used to compute the index of 1845 // internal fields as well as the number of internal fields. 1846 inline int GetHeaderSize(); 1847 1848 inline int GetInternalFieldCount(); 1849 inline int GetInternalFieldOffset(int index); 1850 inline Object* GetInternalField(int index); 1851 inline void SetInternalField(int index, Object* value); 1852 inline void SetInternalField(int index, Smi* value); 1853 1854 // The following lookup functions skip interceptors. 1855 void LocalLookupRealNamedProperty(String* name, LookupResult* result); 1856 void LookupRealNamedProperty(String* name, LookupResult* result); 1857 void LookupRealNamedPropertyInPrototypes(String* name, LookupResult* result); 1858 void LookupCallbackSetterInPrototypes(String* name, LookupResult* result); 1859 MUST_USE_RESULT MaybeObject* SetElementWithCallbackSetterInPrototypes( 1860 uint32_t index, Object* value, bool* found, StrictModeFlag strict_mode); 1861 void LookupCallback(String* name, LookupResult* result); 1862 1863 // Returns the number of properties on this object filtering out properties 1864 // with the specified attributes (ignoring interceptors). 1865 int NumberOfLocalProperties(PropertyAttributes filter = NONE); 1866 // Fill in details for properties into storage starting at the specified 1867 // index. 1868 void GetLocalPropertyNames(FixedArray* storage, int index); 1869 1870 // Returns the number of properties on this object filtering out properties 1871 // with the specified attributes (ignoring interceptors). 1872 int NumberOfLocalElements(PropertyAttributes filter); 1873 // Returns the number of enumerable elements (ignoring interceptors). 1874 int NumberOfEnumElements(); 1875 // Returns the number of elements on this object filtering out elements 1876 // with the specified attributes (ignoring interceptors). 1877 int GetLocalElementKeys(FixedArray* storage, PropertyAttributes filter); 1878 // Count and fill in the enumerable elements into storage. 1879 // (storage->length() == NumberOfEnumElements()). 1880 // If storage is NULL, will count the elements without adding 1881 // them to any storage. 1882 // Returns the number of enumerable elements. 1883 int GetEnumElementKeys(FixedArray* storage); 1884 1885 // Add a property to a fast-case object using a map transition to 1886 // new_map. 1887 MUST_USE_RESULT MaybeObject* AddFastPropertyUsingMap(Map* new_map, 1888 String* name, 1889 Object* value); 1890 1891 // Add a constant function property to a fast-case object. 1892 // This leaves a CONSTANT_TRANSITION in the old map, and 1893 // if it is called on a second object with this map, a 1894 // normal property is added instead, with a map transition. 1895 // This avoids the creation of many maps with the same constant 1896 // function, all orphaned. 1897 MUST_USE_RESULT MaybeObject* AddConstantFunctionProperty( 1898 String* name, 1899 JSFunction* function, 1900 PropertyAttributes attributes); 1901 1902 MUST_USE_RESULT MaybeObject* ReplaceSlowProperty( 1903 String* name, 1904 Object* value, 1905 PropertyAttributes attributes); 1906 1907 // Returns a new map with all transitions dropped from the object's current 1908 // map and the ElementsKind set. 1909 static Handle<Map> GetElementsTransitionMap(Handle<JSObject> object, 1910 ElementsKind to_kind); 1911 inline MUST_USE_RESULT MaybeObject* GetElementsTransitionMap( 1912 Isolate* isolate, 1913 ElementsKind elements_kind); 1914 MUST_USE_RESULT MaybeObject* GetElementsTransitionMapSlow( 1915 ElementsKind elements_kind); 1916 1917 static Handle<Object> TransitionElementsKind(Handle<JSObject> object, 1918 ElementsKind to_kind); 1919 1920 MUST_USE_RESULT MaybeObject* TransitionElementsKind(ElementsKind to_kind); 1921 1922 // Converts a descriptor of any other type to a real field, 1923 // backed by the properties array. Descriptors of visible 1924 // types, such as CONSTANT_FUNCTION, keep their enumeration order. 1925 // Converts the descriptor on the original object's map to a 1926 // map transition, and the the new field is on the object's new map. 1927 MUST_USE_RESULT MaybeObject* ConvertDescriptorToFieldAndMapTransition( 1928 String* name, 1929 Object* new_value, 1930 PropertyAttributes attributes); 1931 1932 // Converts a descriptor of any other type to a real field, 1933 // backed by the properties array. Descriptors of visible 1934 // types, such as CONSTANT_FUNCTION, keep their enumeration order. 1935 MUST_USE_RESULT MaybeObject* ConvertDescriptorToField( 1936 String* name, 1937 Object* new_value, 1938 PropertyAttributes attributes); 1939 1940 // Add a property to a fast-case object. 1941 MUST_USE_RESULT MaybeObject* AddFastProperty(String* name, 1942 Object* value, 1943 PropertyAttributes attributes); 1944 1945 // Add a property to a slow-case object. 1946 MUST_USE_RESULT MaybeObject* AddSlowProperty(String* name, 1947 Object* value, 1948 PropertyAttributes attributes); 1949 1950 // Add a property to an object. 1951 MUST_USE_RESULT MaybeObject* AddProperty(String* name, 1952 Object* value, 1953 PropertyAttributes attributes, 1954 StrictModeFlag strict_mode); 1955 1956 // Convert the object to use the canonical dictionary 1957 // representation. If the object is expected to have additional properties 1958 // added this number can be indicated to have the backing store allocated to 1959 // an initial capacity for holding these properties. 1960 static void NormalizeProperties(Handle<JSObject> object, 1961 PropertyNormalizationMode mode, 1962 int expected_additional_properties); 1963 1964 MUST_USE_RESULT MaybeObject* NormalizeProperties( 1965 PropertyNormalizationMode mode, 1966 int expected_additional_properties); 1967 1968 // Convert and update the elements backing store to be a 1969 // SeededNumberDictionary dictionary. Returns the backing after conversion. 1970 static Handle<SeededNumberDictionary> NormalizeElements( 1971 Handle<JSObject> object); 1972 1973 MUST_USE_RESULT MaybeObject* NormalizeElements(); 1974 1975 static void UpdateMapCodeCache(Handle<JSObject> object, 1976 Handle<String> name, 1977 Handle<Code> code); 1978 1979 MUST_USE_RESULT MaybeObject* UpdateMapCodeCache(String* name, Code* code); 1980 1981 // Transform slow named properties to fast variants. 1982 // Returns failure if allocation failed. 1983 static void TransformToFastProperties(Handle<JSObject> object, 1984 int unused_property_fields); 1985 1986 MUST_USE_RESULT MaybeObject* TransformToFastProperties( 1987 int unused_property_fields); 1988 1989 // Access fast-case object properties at index. 1990 inline Object* FastPropertyAt(int index); 1991 inline Object* FastPropertyAtPut(int index, Object* value); 1992 1993 // Access to in object properties. 1994 inline int GetInObjectPropertyOffset(int index); 1995 inline Object* InObjectPropertyAt(int index); 1996 inline Object* InObjectPropertyAtPut(int index, 1997 Object* value, 1998 WriteBarrierMode mode 1999 = UPDATE_WRITE_BARRIER); 2000 2001 // Initializes the body after properties slot, properties slot is 2002 // initialized by set_properties. Fill the pre-allocated fields with 2003 // pre_allocated_value and the rest with filler_value. 2004 // Note: this call does not update write barrier, the caller is responsible 2005 // to ensure that |filler_value| can be collected without WB here. 2006 inline void InitializeBody(Map* map, 2007 Object* pre_allocated_value, 2008 Object* filler_value); 2009 2010 // Check whether this object references another object 2011 bool ReferencesObject(Object* obj); 2012 2013 // Casting. 2014 static inline JSObject* cast(Object* obj); 2015 2016 // Disalow further properties to be added to the object. 2017 static Handle<Object> PreventExtensions(Handle<JSObject> object); 2018 MUST_USE_RESULT MaybeObject* PreventExtensions(); 2019 2020 2021 // Dispatched behavior. 2022 void JSObjectShortPrint(StringStream* accumulator); 2023 #ifdef OBJECT_PRINT JSObjectPrint()2024 inline void JSObjectPrint() { 2025 JSObjectPrint(stdout); 2026 } 2027 void JSObjectPrint(FILE* out); 2028 #endif 2029 #ifdef DEBUG 2030 void JSObjectVerify(); 2031 #endif 2032 #ifdef OBJECT_PRINT PrintProperties()2033 inline void PrintProperties() { 2034 PrintProperties(stdout); 2035 } 2036 void PrintProperties(FILE* out); 2037 PrintElements()2038 inline void PrintElements() { 2039 PrintElements(stdout); 2040 } 2041 void PrintElements(FILE* out); 2042 #endif 2043 2044 void PrintElementsTransition( 2045 FILE* file, ElementsKind from_kind, FixedArrayBase* from_elements, 2046 ElementsKind to_kind, FixedArrayBase* to_elements); 2047 2048 #ifdef DEBUG 2049 // Structure for collecting spill information about JSObjects. 2050 class SpillInformation { 2051 public: 2052 void Clear(); 2053 void Print(); 2054 int number_of_objects_; 2055 int number_of_objects_with_fast_properties_; 2056 int number_of_objects_with_fast_elements_; 2057 int number_of_fast_used_fields_; 2058 int number_of_fast_unused_fields_; 2059 int number_of_slow_used_properties_; 2060 int number_of_slow_unused_properties_; 2061 int number_of_fast_used_elements_; 2062 int number_of_fast_unused_elements_; 2063 int number_of_slow_used_elements_; 2064 int number_of_slow_unused_elements_; 2065 }; 2066 2067 void IncrementSpillStatistics(SpillInformation* info); 2068 #endif 2069 Object* SlowReverseLookup(Object* value); 2070 2071 // Maximal number of fast properties for the JSObject. Used to 2072 // restrict the number of map transitions to avoid an explosion in 2073 // the number of maps for objects used as dictionaries. 2074 inline int MaxFastProperties(); 2075 2076 // Maximal number of elements (numbered 0 .. kMaxElementCount - 1). 2077 // Also maximal value of JSArray's length property. 2078 static const uint32_t kMaxElementCount = 0xffffffffu; 2079 2080 // Constants for heuristics controlling conversion of fast elements 2081 // to slow elements. 2082 2083 // Maximal gap that can be introduced by adding an element beyond 2084 // the current elements length. 2085 static const uint32_t kMaxGap = 1024; 2086 2087 // Maximal length of fast elements array that won't be checked for 2088 // being dense enough on expansion. 2089 static const int kMaxUncheckedFastElementsLength = 5000; 2090 2091 // Same as above but for old arrays. This limit is more strict. We 2092 // don't want to be wasteful with long lived objects. 2093 static const int kMaxUncheckedOldFastElementsLength = 500; 2094 2095 static const int kInitialMaxFastElementArray = 100000; 2096 static const int kMaxFastProperties = 12; 2097 static const int kMaxInstanceSize = 255 * kPointerSize; 2098 // When extending the backing storage for property values, we increase 2099 // its size by more than the 1 entry necessary, so sequentially adding fields 2100 // to the same object requires fewer allocations and copies. 2101 static const int kFieldsAdded = 3; 2102 2103 // Layout description. 2104 static const int kPropertiesOffset = HeapObject::kHeaderSize; 2105 static const int kElementsOffset = kPropertiesOffset + kPointerSize; 2106 static const int kHeaderSize = kElementsOffset + kPointerSize; 2107 2108 STATIC_CHECK(kHeaderSize == Internals::kJSObjectHeaderSize); 2109 2110 class BodyDescriptor : public FlexibleBodyDescriptor<kPropertiesOffset> { 2111 public: 2112 static inline int SizeOf(Map* map, HeapObject* object); 2113 }; 2114 2115 private: 2116 friend class DictionaryElementsAccessor; 2117 2118 MUST_USE_RESULT MaybeObject* GetElementWithCallback(Object* receiver, 2119 Object* structure, 2120 uint32_t index, 2121 Object* holder); 2122 MUST_USE_RESULT MaybeObject* SetElementWithCallback( 2123 Object* structure, 2124 uint32_t index, 2125 Object* value, 2126 JSObject* holder, 2127 StrictModeFlag strict_mode); 2128 MUST_USE_RESULT MaybeObject* SetElementWithInterceptor( 2129 uint32_t index, 2130 Object* value, 2131 PropertyAttributes attributes, 2132 StrictModeFlag strict_mode, 2133 bool check_prototype, 2134 SetPropertyMode set_mode); 2135 MUST_USE_RESULT MaybeObject* SetElementWithoutInterceptor( 2136 uint32_t index, 2137 Object* value, 2138 PropertyAttributes attributes, 2139 StrictModeFlag strict_mode, 2140 bool check_prototype, 2141 SetPropertyMode set_mode); 2142 2143 // Searches the prototype chain for a callback setter and sets the property 2144 // with the setter if it finds one. The '*found' flag indicates whether 2145 // a setter was found or not. 2146 // This function can cause GC and can return a failure result with 2147 // '*found==true'. 2148 MUST_USE_RESULT MaybeObject* SetPropertyWithCallbackSetterInPrototypes( 2149 String* name, 2150 Object* value, 2151 PropertyAttributes attributes, 2152 bool* found, 2153 StrictModeFlag strict_mode); 2154 2155 MUST_USE_RESULT MaybeObject* DeletePropertyPostInterceptor(String* name, 2156 DeleteMode mode); 2157 MUST_USE_RESULT MaybeObject* DeletePropertyWithInterceptor(String* name); 2158 2159 MUST_USE_RESULT MaybeObject* DeleteElementWithInterceptor(uint32_t index); 2160 2161 MUST_USE_RESULT MaybeObject* DeleteFastElement(uint32_t index); 2162 MUST_USE_RESULT MaybeObject* DeleteDictionaryElement(uint32_t index, 2163 DeleteMode mode); 2164 2165 bool ReferencesObjectFromElements(FixedArray* elements, 2166 ElementsKind kind, 2167 Object* object); 2168 2169 // Returns true if most of the elements backing storage is used. 2170 bool HasDenseElements(); 2171 2172 // Gets the current elements capacity and the number of used elements. 2173 void GetElementsCapacityAndUsage(int* capacity, int* used); 2174 2175 bool CanSetCallback(String* name); 2176 MUST_USE_RESULT MaybeObject* SetElementCallback( 2177 uint32_t index, 2178 Object* structure, 2179 PropertyAttributes attributes); 2180 MUST_USE_RESULT MaybeObject* SetPropertyCallback( 2181 String* name, 2182 Object* structure, 2183 PropertyAttributes attributes); 2184 MUST_USE_RESULT MaybeObject* DefineElementAccessor( 2185 uint32_t index, 2186 Object* getter, 2187 Object* setter, 2188 PropertyAttributes attributes); 2189 MUST_USE_RESULT MaybeObject* DefinePropertyAccessor( 2190 String* name, 2191 Object* getter, 2192 Object* setter, 2193 PropertyAttributes attributes); 2194 void LookupInDescriptor(String* name, LookupResult* result); 2195 2196 // Returns the hidden properties backing store object, currently 2197 // a StringDictionary, stored on this object. 2198 // If no hidden properties object has been put on this object, 2199 // return undefined, unless create_if_absent is true, in which case 2200 // a new dictionary is created, added to this object, and returned. 2201 MUST_USE_RESULT MaybeObject* GetHiddenPropertiesDictionary( 2202 bool create_if_absent); 2203 // Updates the existing hidden properties dictionary. 2204 MUST_USE_RESULT MaybeObject* SetHiddenPropertiesDictionary( 2205 StringDictionary* dictionary); 2206 2207 DISALLOW_IMPLICIT_CONSTRUCTORS(JSObject); 2208 }; 2209 2210 2211 // Common superclass for FixedArrays that allow implementations to share 2212 // common accessors and some code paths. 2213 class FixedArrayBase: public HeapObject { 2214 public: 2215 // [length]: length of the array. 2216 inline int length(); 2217 inline void set_length(int value); 2218 2219 inline static FixedArrayBase* cast(Object* object); 2220 2221 // Layout description. 2222 // Length is smi tagged when it is stored. 2223 static const int kLengthOffset = HeapObject::kHeaderSize; 2224 static const int kHeaderSize = kLengthOffset + kPointerSize; 2225 }; 2226 2227 2228 class FixedDoubleArray; 2229 2230 // FixedArray describes fixed-sized arrays with element type Object*. 2231 class FixedArray: public FixedArrayBase { 2232 public: 2233 // Setter and getter for elements. 2234 inline Object* get(int index); 2235 // Setter that uses write barrier. 2236 inline void set(int index, Object* value); 2237 inline bool is_the_hole(int index); 2238 2239 // Setter that doesn't need write barrier). 2240 inline void set(int index, Smi* value); 2241 // Setter with explicit barrier mode. 2242 inline void set(int index, Object* value, WriteBarrierMode mode); 2243 2244 // Setters for frequently used oddballs located in old space. 2245 inline void set_undefined(int index); 2246 // TODO(isolates): duplicate. 2247 inline void set_undefined(Heap* heap, int index); 2248 inline void set_null(int index); 2249 // TODO(isolates): duplicate. 2250 inline void set_null(Heap* heap, int index); 2251 inline void set_the_hole(int index); 2252 2253 // Setters with less debug checks for the GC to use. 2254 inline void set_unchecked(int index, Smi* value); 2255 inline void set_null_unchecked(Heap* heap, int index); 2256 inline void set_unchecked(Heap* heap, int index, Object* value, 2257 WriteBarrierMode mode); 2258 2259 // Gives access to raw memory which stores the array's data. 2260 inline Object** data_start(); 2261 2262 inline Object** GetFirstElementAddress(); 2263 inline bool ContainsOnlySmisOrHoles(); 2264 2265 // Copy operations. 2266 MUST_USE_RESULT inline MaybeObject* Copy(); 2267 MUST_USE_RESULT MaybeObject* CopySize(int new_length); 2268 2269 // Add the elements of a JSArray to this FixedArray. 2270 MUST_USE_RESULT MaybeObject* AddKeysFromJSArray(JSArray* array); 2271 2272 // Compute the union of this and other. 2273 MUST_USE_RESULT MaybeObject* UnionOfKeys(FixedArray* other); 2274 2275 // Copy a sub array from the receiver to dest. 2276 void CopyTo(int pos, FixedArray* dest, int dest_pos, int len); 2277 2278 // Garbage collection support. SizeFor(int length)2279 static int SizeFor(int length) { return kHeaderSize + length * kPointerSize; } 2280 2281 // Code Generation support. OffsetOfElementAt(int index)2282 static int OffsetOfElementAt(int index) { return SizeFor(index); } 2283 2284 // Casting. 2285 static inline FixedArray* cast(Object* obj); 2286 2287 // Maximal allowed size, in bytes, of a single FixedArray. 2288 // Prevents overflowing size computations, as well as extreme memory 2289 // consumption. 2290 static const int kMaxSize = 128 * MB * kPointerSize; 2291 // Maximally allowed length of a FixedArray. 2292 static const int kMaxLength = (kMaxSize - kHeaderSize) / kPointerSize; 2293 2294 // Dispatched behavior. 2295 #ifdef OBJECT_PRINT FixedArrayPrint()2296 inline void FixedArrayPrint() { 2297 FixedArrayPrint(stdout); 2298 } 2299 void FixedArrayPrint(FILE* out); 2300 #endif 2301 #ifdef DEBUG 2302 void FixedArrayVerify(); 2303 // Checks if two FixedArrays have identical contents. 2304 bool IsEqualTo(FixedArray* other); 2305 #endif 2306 2307 // Swap two elements in a pair of arrays. If this array and the 2308 // numbers array are the same object, the elements are only swapped 2309 // once. 2310 void SwapPairs(FixedArray* numbers, int i, int j); 2311 2312 // Sort prefix of this array and the numbers array as pairs wrt. the 2313 // numbers. If the numbers array and the this array are the same 2314 // object, the prefix of this array is sorted. 2315 void SortPairs(FixedArray* numbers, uint32_t len); 2316 2317 class BodyDescriptor : public FlexibleBodyDescriptor<kHeaderSize> { 2318 public: SizeOf(Map * map,HeapObject * object)2319 static inline int SizeOf(Map* map, HeapObject* object) { 2320 return SizeFor(reinterpret_cast<FixedArray*>(object)->length()); 2321 } 2322 }; 2323 2324 protected: 2325 // Set operation on FixedArray without using write barriers. Can 2326 // only be used for storing old space objects or smis. 2327 static inline void NoWriteBarrierSet(FixedArray* array, 2328 int index, 2329 Object* value); 2330 2331 // Set operation on FixedArray without incremental write barrier. Can 2332 // only be used if the object is guaranteed to be white (whiteness witness 2333 // is present). 2334 static inline void NoIncrementalWriteBarrierSet(FixedArray* array, 2335 int index, 2336 Object* value); 2337 2338 private: 2339 DISALLOW_IMPLICIT_CONSTRUCTORS(FixedArray); 2340 }; 2341 2342 2343 // FixedDoubleArray describes fixed-sized arrays with element type double. 2344 class FixedDoubleArray: public FixedArrayBase { 2345 public: 2346 // Setter and getter for elements. 2347 inline double get_scalar(int index); 2348 inline int64_t get_representation(int index); 2349 MUST_USE_RESULT inline MaybeObject* get(int index); 2350 inline void set(int index, double value); 2351 inline void set_the_hole(int index); 2352 2353 // Checking for the hole. 2354 inline bool is_the_hole(int index); 2355 2356 // Copy operations 2357 MUST_USE_RESULT inline MaybeObject* Copy(); 2358 2359 // Garbage collection support. SizeFor(int length)2360 inline static int SizeFor(int length) { 2361 return kHeaderSize + length * kDoubleSize; 2362 } 2363 2364 // Code Generation support. OffsetOfElementAt(int index)2365 static int OffsetOfElementAt(int index) { return SizeFor(index); } 2366 2367 inline static bool is_the_hole_nan(double value); 2368 inline static double hole_nan_as_double(); 2369 inline static double canonical_not_the_hole_nan_as_double(); 2370 2371 // Casting. 2372 static inline FixedDoubleArray* cast(Object* obj); 2373 2374 // Maximal allowed size, in bytes, of a single FixedDoubleArray. 2375 // Prevents overflowing size computations, as well as extreme memory 2376 // consumption. 2377 static const int kMaxSize = 512 * MB; 2378 // Maximally allowed length of a FixedArray. 2379 static const int kMaxLength = (kMaxSize - kHeaderSize) / kDoubleSize; 2380 2381 // Dispatched behavior. 2382 #ifdef OBJECT_PRINT FixedDoubleArrayPrint()2383 inline void FixedDoubleArrayPrint() { 2384 FixedDoubleArrayPrint(stdout); 2385 } 2386 void FixedDoubleArrayPrint(FILE* out); 2387 #endif 2388 2389 #ifdef DEBUG 2390 void FixedDoubleArrayVerify(); 2391 #endif 2392 2393 private: 2394 DISALLOW_IMPLICIT_CONSTRUCTORS(FixedDoubleArray); 2395 }; 2396 2397 2398 class IncrementalMarking; 2399 2400 2401 // DescriptorArrays are fixed arrays used to hold instance descriptors. 2402 // The format of the these objects is: 2403 // TODO(1399): It should be possible to make room for bit_field3 in the map 2404 // without overloading the instance descriptors field in the map 2405 // (and storing it in the DescriptorArray when the map has one). 2406 // [0]: storage for bit_field3 for Map owning this object (Smi) 2407 // [1]: point to a fixed array with (value, detail) pairs. 2408 // [2]: next enumeration index (Smi), or pointer to small fixed array: 2409 // [0]: next enumeration index (Smi) 2410 // [1]: pointer to fixed array with enum cache 2411 // [3]: first key 2412 // [length() - 1]: last key 2413 // 2414 class DescriptorArray: public FixedArray { 2415 public: 2416 // Returns true for both shared empty_descriptor_array and for smis, which the 2417 // map uses to encode additional bit fields when the descriptor array is not 2418 // yet used. 2419 inline bool IsEmpty(); 2420 2421 // Returns the number of descriptors in the array. number_of_descriptors()2422 int number_of_descriptors() { 2423 ASSERT(length() > kFirstIndex || IsEmpty()); 2424 int len = length(); 2425 return len <= kFirstIndex ? 0 : len - kFirstIndex; 2426 } 2427 NextEnumerationIndex()2428 int NextEnumerationIndex() { 2429 if (IsEmpty()) return PropertyDetails::kInitialIndex; 2430 Object* obj = get(kEnumerationIndexIndex); 2431 if (obj->IsSmi()) { 2432 return Smi::cast(obj)->value(); 2433 } else { 2434 Object* index = FixedArray::cast(obj)->get(kEnumCacheBridgeEnumIndex); 2435 return Smi::cast(index)->value(); 2436 } 2437 } 2438 2439 // Set next enumeration index and flush any enum cache. SetNextEnumerationIndex(int value)2440 void SetNextEnumerationIndex(int value) { 2441 if (!IsEmpty()) { 2442 set(kEnumerationIndexIndex, Smi::FromInt(value)); 2443 } 2444 } HasEnumCache()2445 bool HasEnumCache() { 2446 return !IsEmpty() && !get(kEnumerationIndexIndex)->IsSmi(); 2447 } 2448 GetEnumCache()2449 Object* GetEnumCache() { 2450 ASSERT(HasEnumCache()); 2451 FixedArray* bridge = FixedArray::cast(get(kEnumerationIndexIndex)); 2452 return bridge->get(kEnumCacheBridgeCacheIndex); 2453 } 2454 2455 // TODO(1399): It should be possible to make room for bit_field3 in the map 2456 // without overloading the instance descriptors field in the map 2457 // (and storing it in the DescriptorArray when the map has one). 2458 inline int bit_field3_storage(); 2459 inline void set_bit_field3_storage(int value); 2460 2461 // Initialize or change the enum cache, 2462 // using the supplied storage for the small "bridge". 2463 void SetEnumCache(FixedArray* bridge_storage, 2464 FixedArray* new_cache, 2465 Object* new_index_cache); 2466 2467 // Accessors for fetching instance descriptor at descriptor number. 2468 inline String* GetKey(int descriptor_number); 2469 inline Object* GetValue(int descriptor_number); 2470 inline Smi* GetDetails(int descriptor_number); 2471 inline PropertyType GetType(int descriptor_number); 2472 inline int GetFieldIndex(int descriptor_number); 2473 inline JSFunction* GetConstantFunction(int descriptor_number); 2474 inline Object* GetCallbacksObject(int descriptor_number); 2475 inline AccessorDescriptor* GetCallbacks(int descriptor_number); 2476 inline bool IsProperty(int descriptor_number); 2477 inline bool IsTransitionOnly(int descriptor_number); 2478 inline bool IsNullDescriptor(int descriptor_number); 2479 inline bool IsDontEnum(int descriptor_number); 2480 2481 class WhitenessWitness { 2482 public: 2483 inline explicit WhitenessWitness(DescriptorArray* array); 2484 inline ~WhitenessWitness(); 2485 2486 private: 2487 IncrementalMarking* marking_; 2488 }; 2489 2490 // Accessor for complete descriptor. 2491 inline void Get(int descriptor_number, Descriptor* desc); 2492 inline void Set(int descriptor_number, 2493 Descriptor* desc, 2494 const WhitenessWitness&); 2495 2496 // Transfer a complete descriptor from the src descriptor array to the dst 2497 // one, dropping map transitions in CALLBACKS. 2498 static void CopyFrom(Handle<DescriptorArray> dst, 2499 int dst_index, 2500 Handle<DescriptorArray> src, 2501 int src_index, 2502 const WhitenessWitness& witness); 2503 2504 // Transfer a complete descriptor from the src descriptor array to this 2505 // descriptor array, dropping map transitions in CALLBACKS. 2506 MUST_USE_RESULT MaybeObject* CopyFrom(int dst_index, 2507 DescriptorArray* src, 2508 int src_index, 2509 const WhitenessWitness&); 2510 2511 // Copy the descriptor array, insert a new descriptor and optionally 2512 // remove map transitions. If the descriptor is already present, it is 2513 // replaced. If a replaced descriptor is a real property (not a transition 2514 // or null), its enumeration index is kept as is. 2515 // If adding a real property, map transitions must be removed. If adding 2516 // a transition, they must not be removed. All null descriptors are removed. 2517 MUST_USE_RESULT MaybeObject* CopyInsert(Descriptor* descriptor, 2518 TransitionFlag transition_flag); 2519 2520 // Return a copy of the array with all transitions and null descriptors 2521 // removed. Return a Failure object in case of an allocation failure. 2522 MUST_USE_RESULT MaybeObject* RemoveTransitions(); 2523 2524 // Sort the instance descriptors by the hash codes of their keys. 2525 // Does not check for duplicates. 2526 void SortUnchecked(const WhitenessWitness&); 2527 2528 // Sort the instance descriptors by the hash codes of their keys. 2529 // Checks the result for duplicates. 2530 void Sort(const WhitenessWitness&); 2531 2532 // Search the instance descriptors for given name. 2533 inline int Search(String* name); 2534 2535 // As the above, but uses DescriptorLookupCache and updates it when 2536 // necessary. 2537 inline int SearchWithCache(String* name); 2538 2539 // Tells whether the name is present int the array. Contains(String * name)2540 bool Contains(String* name) { return kNotFound != Search(name); } 2541 2542 // Perform a binary search in the instance descriptors represented 2543 // by this fixed array. low and high are descriptor indices. If there 2544 // are three instance descriptors in this array it should be called 2545 // with low=0 and high=2. 2546 int BinarySearch(String* name, int low, int high); 2547 2548 // Perform a linear search in the instance descriptors represented 2549 // by this fixed array. len is the number of descriptor indices that are 2550 // valid. Does not require the descriptors to be sorted. 2551 int LinearSearch(String* name, int len); 2552 2553 // Allocates a DescriptorArray, but returns the singleton 2554 // empty descriptor array object if number_of_descriptors is 0. 2555 MUST_USE_RESULT static MaybeObject* Allocate(int number_of_descriptors); 2556 2557 // Casting. 2558 static inline DescriptorArray* cast(Object* obj); 2559 2560 // Constant for denoting key was not found. 2561 static const int kNotFound = -1; 2562 2563 static const int kBitField3StorageIndex = 0; 2564 static const int kContentArrayIndex = 1; 2565 static const int kEnumerationIndexIndex = 2; 2566 static const int kFirstIndex = 3; 2567 2568 // The length of the "bridge" to the enum cache. 2569 static const int kEnumCacheBridgeLength = 3; 2570 static const int kEnumCacheBridgeEnumIndex = 0; 2571 static const int kEnumCacheBridgeCacheIndex = 1; 2572 static const int kEnumCacheBridgeIndicesCacheIndex = 2; 2573 2574 // Layout description. 2575 static const int kBitField3StorageOffset = FixedArray::kHeaderSize; 2576 static const int kContentArrayOffset = kBitField3StorageOffset + kPointerSize; 2577 static const int kEnumerationIndexOffset = kContentArrayOffset + kPointerSize; 2578 static const int kFirstOffset = kEnumerationIndexOffset + kPointerSize; 2579 2580 // Layout description for the bridge array. 2581 static const int kEnumCacheBridgeEnumOffset = FixedArray::kHeaderSize; 2582 static const int kEnumCacheBridgeCacheOffset = 2583 kEnumCacheBridgeEnumOffset + kPointerSize; 2584 2585 #ifdef OBJECT_PRINT 2586 // Print all the descriptors. PrintDescriptors()2587 inline void PrintDescriptors() { 2588 PrintDescriptors(stdout); 2589 } 2590 void PrintDescriptors(FILE* out); 2591 #endif 2592 2593 #ifdef DEBUG 2594 // Is the descriptor array sorted and without duplicates? 2595 bool IsSortedNoDuplicates(); 2596 2597 // Are two DescriptorArrays equal? 2598 bool IsEqualTo(DescriptorArray* other); 2599 #endif 2600 2601 // The maximum number of descriptors we want in a descriptor array (should 2602 // fit in a page). 2603 static const int kMaxNumberOfDescriptors = 1024 + 512; 2604 2605 private: 2606 // An entry in a DescriptorArray, represented as an (array, index) pair. 2607 class Entry { 2608 public: Entry(DescriptorArray * descs,int index)2609 inline explicit Entry(DescriptorArray* descs, int index) : 2610 descs_(descs), index_(index) { } 2611 type()2612 inline PropertyType type() { return descs_->GetType(index_); } GetCallbackObject()2613 inline Object* GetCallbackObject() { return descs_->GetValue(index_); } 2614 2615 private: 2616 DescriptorArray* descs_; 2617 int index_; 2618 }; 2619 2620 // Conversion from descriptor number to array indices. ToKeyIndex(int descriptor_number)2621 static int ToKeyIndex(int descriptor_number) { 2622 return descriptor_number+kFirstIndex; 2623 } 2624 ToDetailsIndex(int descriptor_number)2625 static int ToDetailsIndex(int descriptor_number) { 2626 return (descriptor_number << 1) + 1; 2627 } 2628 ToValueIndex(int descriptor_number)2629 static int ToValueIndex(int descriptor_number) { 2630 return descriptor_number << 1; 2631 } 2632 is_null_descriptor(int descriptor_number)2633 bool is_null_descriptor(int descriptor_number) { 2634 return PropertyDetails(GetDetails(descriptor_number)).type() == 2635 NULL_DESCRIPTOR; 2636 } 2637 // Swap operation on FixedArray without using write barriers. 2638 static inline void NoIncrementalWriteBarrierSwap( 2639 FixedArray* array, int first, int second); 2640 2641 // Swap descriptor first and second. 2642 inline void NoIncrementalWriteBarrierSwapDescriptors( 2643 int first, int second); 2644 GetContentArray()2645 FixedArray* GetContentArray() { 2646 return FixedArray::cast(get(kContentArrayIndex)); 2647 } 2648 DISALLOW_IMPLICIT_CONSTRUCTORS(DescriptorArray); 2649 }; 2650 2651 2652 // HashTable is a subclass of FixedArray that implements a hash table 2653 // that uses open addressing and quadratic probing. 2654 // 2655 // In order for the quadratic probing to work, elements that have not 2656 // yet been used and elements that have been deleted are 2657 // distinguished. Probing continues when deleted elements are 2658 // encountered and stops when unused elements are encountered. 2659 // 2660 // - Elements with key == undefined have not been used yet. 2661 // - Elements with key == the_hole have been deleted. 2662 // 2663 // The hash table class is parameterized with a Shape and a Key. 2664 // Shape must be a class with the following interface: 2665 // class ExampleShape { 2666 // public: 2667 // // Tells whether key matches other. 2668 // static bool IsMatch(Key key, Object* other); 2669 // // Returns the hash value for key. 2670 // static uint32_t Hash(Key key); 2671 // // Returns the hash value for object. 2672 // static uint32_t HashForObject(Key key, Object* object); 2673 // // Convert key to an object. 2674 // static inline Object* AsObject(Key key); 2675 // // The prefix size indicates number of elements in the beginning 2676 // // of the backing storage. 2677 // static const int kPrefixSize = ..; 2678 // // The Element size indicates number of elements per entry. 2679 // static const int kEntrySize = ..; 2680 // }; 2681 // The prefix size indicates an amount of memory in the 2682 // beginning of the backing storage that can be used for non-element 2683 // information by subclasses. 2684 2685 template<typename Key> 2686 class BaseShape { 2687 public: 2688 static const bool UsesSeed = false; Hash(Key key)2689 static uint32_t Hash(Key key) { return 0; } SeededHash(Key key,uint32_t seed)2690 static uint32_t SeededHash(Key key, uint32_t seed) { 2691 ASSERT(UsesSeed); 2692 return Hash(key); 2693 } HashForObject(Key key,Object * object)2694 static uint32_t HashForObject(Key key, Object* object) { return 0; } SeededHashForObject(Key key,uint32_t seed,Object * object)2695 static uint32_t SeededHashForObject(Key key, uint32_t seed, Object* object) { 2696 ASSERT(UsesSeed); 2697 return HashForObject(key, object); 2698 } 2699 }; 2700 2701 template<typename Shape, typename Key> 2702 class HashTable: public FixedArray { 2703 public: 2704 // Wrapper methods Hash(Key key)2705 inline uint32_t Hash(Key key) { 2706 if (Shape::UsesSeed) { 2707 return Shape::SeededHash(key, 2708 GetHeap()->HashSeed()); 2709 } else { 2710 return Shape::Hash(key); 2711 } 2712 } 2713 HashForObject(Key key,Object * object)2714 inline uint32_t HashForObject(Key key, Object* object) { 2715 if (Shape::UsesSeed) { 2716 return Shape::SeededHashForObject(key, 2717 GetHeap()->HashSeed(), object); 2718 } else { 2719 return Shape::HashForObject(key, object); 2720 } 2721 } 2722 2723 // Returns the number of elements in the hash table. NumberOfElements()2724 int NumberOfElements() { 2725 return Smi::cast(get(kNumberOfElementsIndex))->value(); 2726 } 2727 2728 // Returns the number of deleted elements in the hash table. NumberOfDeletedElements()2729 int NumberOfDeletedElements() { 2730 return Smi::cast(get(kNumberOfDeletedElementsIndex))->value(); 2731 } 2732 2733 // Returns the capacity of the hash table. Capacity()2734 int Capacity() { 2735 return Smi::cast(get(kCapacityIndex))->value(); 2736 } 2737 2738 // ElementAdded should be called whenever an element is added to a 2739 // hash table. ElementAdded()2740 void ElementAdded() { SetNumberOfElements(NumberOfElements() + 1); } 2741 2742 // ElementRemoved should be called whenever an element is removed from 2743 // a hash table. ElementRemoved()2744 void ElementRemoved() { 2745 SetNumberOfElements(NumberOfElements() - 1); 2746 SetNumberOfDeletedElements(NumberOfDeletedElements() + 1); 2747 } ElementsRemoved(int n)2748 void ElementsRemoved(int n) { 2749 SetNumberOfElements(NumberOfElements() - n); 2750 SetNumberOfDeletedElements(NumberOfDeletedElements() + n); 2751 } 2752 2753 // Returns a new HashTable object. Might return Failure. 2754 MUST_USE_RESULT static MaybeObject* Allocate( 2755 int at_least_space_for, 2756 PretenureFlag pretenure = NOT_TENURED); 2757 2758 // Computes the required capacity for a table holding the given 2759 // number of elements. May be more than HashTable::kMaxCapacity. 2760 static int ComputeCapacity(int at_least_space_for); 2761 2762 // Returns the key at entry. KeyAt(int entry)2763 Object* KeyAt(int entry) { return get(EntryToIndex(entry)); } 2764 2765 // Tells whether k is a real key. The hole and undefined are not allowed 2766 // as keys and can be used to indicate missing or deleted elements. IsKey(Object * k)2767 bool IsKey(Object* k) { 2768 return !k->IsTheHole() && !k->IsUndefined(); 2769 } 2770 2771 // Garbage collection support. 2772 void IteratePrefix(ObjectVisitor* visitor); 2773 void IterateElements(ObjectVisitor* visitor); 2774 2775 // Casting. 2776 static inline HashTable* cast(Object* obj); 2777 2778 // Compute the probe offset (quadratic probing). INLINE(static uint32_t GetProbeOffset (uint32_t n))2779 INLINE(static uint32_t GetProbeOffset(uint32_t n)) { 2780 return (n + n * n) >> 1; 2781 } 2782 2783 static const int kNumberOfElementsIndex = 0; 2784 static const int kNumberOfDeletedElementsIndex = 1; 2785 static const int kCapacityIndex = 2; 2786 static const int kPrefixStartIndex = 3; 2787 static const int kElementsStartIndex = 2788 kPrefixStartIndex + Shape::kPrefixSize; 2789 static const int kEntrySize = Shape::kEntrySize; 2790 static const int kElementsStartOffset = 2791 kHeaderSize + kElementsStartIndex * kPointerSize; 2792 static const int kCapacityOffset = 2793 kHeaderSize + kCapacityIndex * kPointerSize; 2794 2795 // Constant used for denoting a absent entry. 2796 static const int kNotFound = -1; 2797 2798 // Maximal capacity of HashTable. Based on maximal length of underlying 2799 // FixedArray. Staying below kMaxCapacity also ensures that EntryToIndex 2800 // cannot overflow. 2801 static const int kMaxCapacity = 2802 (FixedArray::kMaxLength - kElementsStartOffset) / kEntrySize; 2803 2804 // Find entry for key otherwise return kNotFound. 2805 inline int FindEntry(Key key); 2806 int FindEntry(Isolate* isolate, Key key); 2807 2808 protected: 2809 // Find the entry at which to insert element with the given key that 2810 // has the given hash value. 2811 uint32_t FindInsertionEntry(uint32_t hash); 2812 2813 // Returns the index for an entry (of the key) EntryToIndex(int entry)2814 static inline int EntryToIndex(int entry) { 2815 return (entry * kEntrySize) + kElementsStartIndex; 2816 } 2817 2818 // Update the number of elements in the hash table. SetNumberOfElements(int nof)2819 void SetNumberOfElements(int nof) { 2820 set(kNumberOfElementsIndex, Smi::FromInt(nof)); 2821 } 2822 2823 // Update the number of deleted elements in the hash table. SetNumberOfDeletedElements(int nod)2824 void SetNumberOfDeletedElements(int nod) { 2825 set(kNumberOfDeletedElementsIndex, Smi::FromInt(nod)); 2826 } 2827 2828 // Sets the capacity of the hash table. SetCapacity(int capacity)2829 void SetCapacity(int capacity) { 2830 // To scale a computed hash code to fit within the hash table, we 2831 // use bit-wise AND with a mask, so the capacity must be positive 2832 // and non-zero. 2833 ASSERT(capacity > 0); 2834 ASSERT(capacity <= kMaxCapacity); 2835 set(kCapacityIndex, Smi::FromInt(capacity)); 2836 } 2837 2838 2839 // Returns probe entry. GetProbe(uint32_t hash,uint32_t number,uint32_t size)2840 static uint32_t GetProbe(uint32_t hash, uint32_t number, uint32_t size) { 2841 ASSERT(IsPowerOf2(size)); 2842 return (hash + GetProbeOffset(number)) & (size - 1); 2843 } 2844 FirstProbe(uint32_t hash,uint32_t size)2845 static uint32_t FirstProbe(uint32_t hash, uint32_t size) { 2846 return hash & (size - 1); 2847 } 2848 NextProbe(uint32_t last,uint32_t number,uint32_t size)2849 static uint32_t NextProbe(uint32_t last, uint32_t number, uint32_t size) { 2850 return (last + number) & (size - 1); 2851 } 2852 2853 // Rehashes this hash-table into the new table. 2854 MUST_USE_RESULT MaybeObject* Rehash(HashTable* new_table, Key key); 2855 2856 // Attempt to shrink hash table after removal of key. 2857 MUST_USE_RESULT MaybeObject* Shrink(Key key); 2858 2859 // Ensure enough space for n additional elements. 2860 MUST_USE_RESULT MaybeObject* EnsureCapacity(int n, Key key); 2861 }; 2862 2863 2864 // HashTableKey is an abstract superclass for virtual key behavior. 2865 class HashTableKey { 2866 public: 2867 // Returns whether the other object matches this key. 2868 virtual bool IsMatch(Object* other) = 0; 2869 // Returns the hash value for this key. 2870 virtual uint32_t Hash() = 0; 2871 // Returns the hash value for object. 2872 virtual uint32_t HashForObject(Object* key) = 0; 2873 // Returns the key object for storing into the hash table. 2874 // If allocations fails a failure object is returned. 2875 MUST_USE_RESULT virtual MaybeObject* AsObject() = 0; 2876 // Required. ~HashTableKey()2877 virtual ~HashTableKey() {} 2878 }; 2879 2880 2881 class SymbolTableShape : public BaseShape<HashTableKey*> { 2882 public: IsMatch(HashTableKey * key,Object * value)2883 static inline bool IsMatch(HashTableKey* key, Object* value) { 2884 return key->IsMatch(value); 2885 } Hash(HashTableKey * key)2886 static inline uint32_t Hash(HashTableKey* key) { 2887 return key->Hash(); 2888 } HashForObject(HashTableKey * key,Object * object)2889 static inline uint32_t HashForObject(HashTableKey* key, Object* object) { 2890 return key->HashForObject(object); 2891 } AsObject(HashTableKey * key)2892 MUST_USE_RESULT static inline MaybeObject* AsObject(HashTableKey* key) { 2893 return key->AsObject(); 2894 } 2895 2896 static const int kPrefixSize = 0; 2897 static const int kEntrySize = 1; 2898 }; 2899 2900 class SeqAsciiString; 2901 2902 // SymbolTable. 2903 // 2904 // No special elements in the prefix and the element size is 1 2905 // because only the symbol itself (the key) needs to be stored. 2906 class SymbolTable: public HashTable<SymbolTableShape, HashTableKey*> { 2907 public: 2908 // Find symbol in the symbol table. If it is not there yet, it is 2909 // added. The return value is the symbol table which might have 2910 // been enlarged. If the return value is not a failure, the symbol 2911 // pointer *s is set to the symbol found. 2912 MUST_USE_RESULT MaybeObject* LookupSymbol(Vector<const char> str, Object** s); 2913 MUST_USE_RESULT MaybeObject* LookupAsciiSymbol(Vector<const char> str, 2914 Object** s); 2915 MUST_USE_RESULT MaybeObject* LookupSubStringAsciiSymbol( 2916 Handle<SeqAsciiString> str, 2917 int from, 2918 int length, 2919 Object** s); 2920 MUST_USE_RESULT MaybeObject* LookupTwoByteSymbol(Vector<const uc16> str, 2921 Object** s); 2922 MUST_USE_RESULT MaybeObject* LookupString(String* key, Object** s); 2923 2924 // Looks up a symbol that is equal to the given string and returns 2925 // true if it is found, assigning the symbol to the given output 2926 // parameter. 2927 bool LookupSymbolIfExists(String* str, String** symbol); 2928 bool LookupTwoCharsSymbolIfExists(uint32_t c1, uint32_t c2, String** symbol); 2929 2930 // Casting. 2931 static inline SymbolTable* cast(Object* obj); 2932 2933 private: 2934 MUST_USE_RESULT MaybeObject* LookupKey(HashTableKey* key, Object** s); 2935 2936 DISALLOW_IMPLICIT_CONSTRUCTORS(SymbolTable); 2937 }; 2938 2939 2940 class MapCacheShape : public BaseShape<HashTableKey*> { 2941 public: IsMatch(HashTableKey * key,Object * value)2942 static inline bool IsMatch(HashTableKey* key, Object* value) { 2943 return key->IsMatch(value); 2944 } Hash(HashTableKey * key)2945 static inline uint32_t Hash(HashTableKey* key) { 2946 return key->Hash(); 2947 } 2948 HashForObject(HashTableKey * key,Object * object)2949 static inline uint32_t HashForObject(HashTableKey* key, Object* object) { 2950 return key->HashForObject(object); 2951 } 2952 AsObject(HashTableKey * key)2953 MUST_USE_RESULT static inline MaybeObject* AsObject(HashTableKey* key) { 2954 return key->AsObject(); 2955 } 2956 2957 static const int kPrefixSize = 0; 2958 static const int kEntrySize = 2; 2959 }; 2960 2961 2962 // MapCache. 2963 // 2964 // Maps keys that are a fixed array of symbols to a map. 2965 // Used for canonicalize maps for object literals. 2966 class MapCache: public HashTable<MapCacheShape, HashTableKey*> { 2967 public: 2968 // Find cached value for a string key, otherwise return null. 2969 Object* Lookup(FixedArray* key); 2970 MUST_USE_RESULT MaybeObject* Put(FixedArray* key, Map* value); 2971 static inline MapCache* cast(Object* obj); 2972 2973 private: 2974 DISALLOW_IMPLICIT_CONSTRUCTORS(MapCache); 2975 }; 2976 2977 2978 template <typename Shape, typename Key> 2979 class Dictionary: public HashTable<Shape, Key> { 2980 public: cast(Object * obj)2981 static inline Dictionary<Shape, Key>* cast(Object* obj) { 2982 return reinterpret_cast<Dictionary<Shape, Key>*>(obj); 2983 } 2984 2985 // Returns the value at entry. ValueAt(int entry)2986 Object* ValueAt(int entry) { 2987 return this->get(HashTable<Shape, Key>::EntryToIndex(entry) + 1); 2988 } 2989 2990 // Set the value for entry. ValueAtPut(int entry,Object * value)2991 void ValueAtPut(int entry, Object* value) { 2992 this->set(HashTable<Shape, Key>::EntryToIndex(entry) + 1, value); 2993 } 2994 2995 // Returns the property details for the property at entry. DetailsAt(int entry)2996 PropertyDetails DetailsAt(int entry) { 2997 ASSERT(entry >= 0); // Not found is -1, which is not caught by get(). 2998 return PropertyDetails( 2999 Smi::cast(this->get(HashTable<Shape, Key>::EntryToIndex(entry) + 2))); 3000 } 3001 3002 // Set the details for entry. DetailsAtPut(int entry,PropertyDetails value)3003 void DetailsAtPut(int entry, PropertyDetails value) { 3004 this->set(HashTable<Shape, Key>::EntryToIndex(entry) + 2, value.AsSmi()); 3005 } 3006 3007 // Sorting support 3008 void CopyValuesTo(FixedArray* elements); 3009 3010 // Delete a property from the dictionary. 3011 Object* DeleteProperty(int entry, JSObject::DeleteMode mode); 3012 3013 // Attempt to shrink the dictionary after deletion of key. 3014 MUST_USE_RESULT MaybeObject* Shrink(Key key); 3015 3016 // Returns the number of elements in the dictionary filtering out properties 3017 // with the specified attributes. 3018 int NumberOfElementsFilterAttributes(PropertyAttributes filter); 3019 3020 // Returns the number of enumerable elements in the dictionary. 3021 int NumberOfEnumElements(); 3022 3023 enum SortMode { UNSORTED, SORTED }; 3024 // Copies keys to preallocated fixed array. 3025 void CopyKeysTo(FixedArray* storage, 3026 PropertyAttributes filter, 3027 SortMode sort_mode); 3028 // Fill in details for properties into storage. 3029 void CopyKeysTo(FixedArray* storage, int index, SortMode sort_mode); 3030 3031 // Accessors for next enumeration index. SetNextEnumerationIndex(int index)3032 void SetNextEnumerationIndex(int index) { 3033 this->set(kNextEnumerationIndexIndex, Smi::FromInt(index)); 3034 } 3035 NextEnumerationIndex()3036 int NextEnumerationIndex() { 3037 return Smi::cast(FixedArray::get(kNextEnumerationIndexIndex))->value(); 3038 } 3039 3040 // Returns a new array for dictionary usage. Might return Failure. 3041 MUST_USE_RESULT static MaybeObject* Allocate(int at_least_space_for); 3042 3043 // Ensure enough space for n additional elements. 3044 MUST_USE_RESULT MaybeObject* EnsureCapacity(int n, Key key); 3045 3046 #ifdef OBJECT_PRINT Print()3047 inline void Print() { 3048 Print(stdout); 3049 } 3050 void Print(FILE* out); 3051 #endif 3052 // Returns the key (slow). 3053 Object* SlowReverseLookup(Object* value); 3054 3055 // Sets the entry to (key, value) pair. 3056 inline void SetEntry(int entry, 3057 Object* key, 3058 Object* value); 3059 inline void SetEntry(int entry, 3060 Object* key, 3061 Object* value, 3062 PropertyDetails details); 3063 3064 MUST_USE_RESULT MaybeObject* Add(Key key, 3065 Object* value, 3066 PropertyDetails details); 3067 3068 protected: 3069 // Generic at put operation. 3070 MUST_USE_RESULT MaybeObject* AtPut(Key key, Object* value); 3071 3072 // Add entry to dictionary. 3073 MUST_USE_RESULT MaybeObject* AddEntry(Key key, 3074 Object* value, 3075 PropertyDetails details, 3076 uint32_t hash); 3077 3078 // Generate new enumeration indices to avoid enumeration index overflow. 3079 MUST_USE_RESULT MaybeObject* GenerateNewEnumerationIndices(); 3080 static const int kMaxNumberKeyIndex = 3081 HashTable<Shape, Key>::kPrefixStartIndex; 3082 static const int kNextEnumerationIndexIndex = kMaxNumberKeyIndex + 1; 3083 }; 3084 3085 3086 class StringDictionaryShape : public BaseShape<String*> { 3087 public: 3088 static inline bool IsMatch(String* key, Object* other); 3089 static inline uint32_t Hash(String* key); 3090 static inline uint32_t HashForObject(String* key, Object* object); 3091 MUST_USE_RESULT static inline MaybeObject* AsObject(String* key); 3092 static const int kPrefixSize = 2; 3093 static const int kEntrySize = 3; 3094 static const bool kIsEnumerable = true; 3095 }; 3096 3097 3098 class StringDictionary: public Dictionary<StringDictionaryShape, String*> { 3099 public: cast(Object * obj)3100 static inline StringDictionary* cast(Object* obj) { 3101 ASSERT(obj->IsDictionary()); 3102 return reinterpret_cast<StringDictionary*>(obj); 3103 } 3104 3105 // Copies enumerable keys to preallocated fixed array. 3106 void CopyEnumKeysTo(FixedArray* storage, FixedArray* sort_array); 3107 3108 // For transforming properties of a JSObject. 3109 MUST_USE_RESULT MaybeObject* TransformPropertiesToFastFor( 3110 JSObject* obj, 3111 int unused_property_fields); 3112 3113 // Find entry for key, otherwise return kNotFound. Optimized version of 3114 // HashTable::FindEntry. 3115 int FindEntry(String* key); 3116 3117 bool ContainsTransition(int entry); 3118 }; 3119 3120 3121 class NumberDictionaryShape : public BaseShape<uint32_t> { 3122 public: 3123 static inline bool IsMatch(uint32_t key, Object* other); 3124 MUST_USE_RESULT static inline MaybeObject* AsObject(uint32_t key); 3125 static const int kEntrySize = 3; 3126 static const bool kIsEnumerable = false; 3127 }; 3128 3129 3130 class SeededNumberDictionaryShape : public NumberDictionaryShape { 3131 public: 3132 static const bool UsesSeed = true; 3133 static const int kPrefixSize = 2; 3134 3135 static inline uint32_t SeededHash(uint32_t key, uint32_t seed); 3136 static inline uint32_t SeededHashForObject(uint32_t key, 3137 uint32_t seed, 3138 Object* object); 3139 }; 3140 3141 3142 class UnseededNumberDictionaryShape : public NumberDictionaryShape { 3143 public: 3144 static const int kPrefixSize = 0; 3145 3146 static inline uint32_t Hash(uint32_t key); 3147 static inline uint32_t HashForObject(uint32_t key, Object* object); 3148 }; 3149 3150 3151 class SeededNumberDictionary 3152 : public Dictionary<SeededNumberDictionaryShape, uint32_t> { 3153 public: cast(Object * obj)3154 static SeededNumberDictionary* cast(Object* obj) { 3155 ASSERT(obj->IsDictionary()); 3156 return reinterpret_cast<SeededNumberDictionary*>(obj); 3157 } 3158 3159 // Type specific at put (default NONE attributes is used when adding). 3160 MUST_USE_RESULT MaybeObject* AtNumberPut(uint32_t key, Object* value); 3161 MUST_USE_RESULT MaybeObject* AddNumberEntry(uint32_t key, 3162 Object* value, 3163 PropertyDetails details); 3164 3165 // Set an existing entry or add a new one if needed. 3166 // Return the updated dictionary. 3167 MUST_USE_RESULT static Handle<SeededNumberDictionary> Set( 3168 Handle<SeededNumberDictionary> dictionary, 3169 uint32_t index, 3170 Handle<Object> value, 3171 PropertyDetails details); 3172 3173 MUST_USE_RESULT MaybeObject* Set(uint32_t key, 3174 Object* value, 3175 PropertyDetails details); 3176 3177 void UpdateMaxNumberKey(uint32_t key); 3178 3179 // If slow elements are required we will never go back to fast-case 3180 // for the elements kept in this dictionary. We require slow 3181 // elements if an element has been added at an index larger than 3182 // kRequiresSlowElementsLimit or set_requires_slow_elements() has been called 3183 // when defining a getter or setter with a number key. 3184 inline bool requires_slow_elements(); 3185 inline void set_requires_slow_elements(); 3186 3187 // Get the value of the max number key that has been added to this 3188 // dictionary. max_number_key can only be called if 3189 // requires_slow_elements returns false. 3190 inline uint32_t max_number_key(); 3191 3192 // Bit masks. 3193 static const int kRequiresSlowElementsMask = 1; 3194 static const int kRequiresSlowElementsTagSize = 1; 3195 static const uint32_t kRequiresSlowElementsLimit = (1 << 29) - 1; 3196 }; 3197 3198 3199 class UnseededNumberDictionary 3200 : public Dictionary<UnseededNumberDictionaryShape, uint32_t> { 3201 public: cast(Object * obj)3202 static UnseededNumberDictionary* cast(Object* obj) { 3203 ASSERT(obj->IsDictionary()); 3204 return reinterpret_cast<UnseededNumberDictionary*>(obj); 3205 } 3206 3207 // Type specific at put (default NONE attributes is used when adding). 3208 MUST_USE_RESULT MaybeObject* AtNumberPut(uint32_t key, Object* value); 3209 MUST_USE_RESULT MaybeObject* AddNumberEntry(uint32_t key, Object* value); 3210 3211 // Set an existing entry or add a new one if needed. 3212 // Return the updated dictionary. 3213 MUST_USE_RESULT static Handle<UnseededNumberDictionary> Set( 3214 Handle<UnseededNumberDictionary> dictionary, 3215 uint32_t index, 3216 Handle<Object> value); 3217 3218 MUST_USE_RESULT MaybeObject* Set(uint32_t key, Object* value); 3219 }; 3220 3221 3222 template <int entrysize> 3223 class ObjectHashTableShape : public BaseShape<Object*> { 3224 public: 3225 static inline bool IsMatch(Object* key, Object* other); 3226 static inline uint32_t Hash(Object* key); 3227 static inline uint32_t HashForObject(Object* key, Object* object); 3228 MUST_USE_RESULT static inline MaybeObject* AsObject(Object* key); 3229 static const int kPrefixSize = 0; 3230 static const int kEntrySize = entrysize; 3231 }; 3232 3233 3234 // ObjectHashSet holds keys that are arbitrary objects by using the identity 3235 // hash of the key for hashing purposes. 3236 class ObjectHashSet: public HashTable<ObjectHashTableShape<1>, Object*> { 3237 public: cast(Object * obj)3238 static inline ObjectHashSet* cast(Object* obj) { 3239 ASSERT(obj->IsHashTable()); 3240 return reinterpret_cast<ObjectHashSet*>(obj); 3241 } 3242 3243 // Looks up whether the given key is part of this hash set. 3244 bool Contains(Object* key); 3245 3246 // Adds the given key to this hash set. 3247 MUST_USE_RESULT MaybeObject* Add(Object* key); 3248 3249 // Removes the given key from this hash set. 3250 MUST_USE_RESULT MaybeObject* Remove(Object* key); 3251 }; 3252 3253 3254 // ObjectHashTable maps keys that are arbitrary objects to object values by 3255 // using the identity hash of the key for hashing purposes. 3256 class ObjectHashTable: public HashTable<ObjectHashTableShape<2>, Object*> { 3257 public: cast(Object * obj)3258 static inline ObjectHashTable* cast(Object* obj) { 3259 ASSERT(obj->IsHashTable()); 3260 return reinterpret_cast<ObjectHashTable*>(obj); 3261 } 3262 3263 // Looks up the value associated with the given key. The undefined value is 3264 // returned in case the key is not present. 3265 Object* Lookup(Object* key); 3266 3267 // Adds (or overwrites) the value associated with the given key. Mapping a 3268 // key to the undefined value causes removal of the whole entry. 3269 MUST_USE_RESULT MaybeObject* Put(Object* key, Object* value); 3270 3271 private: 3272 friend class MarkCompactCollector; 3273 3274 void AddEntry(int entry, Object* key, Object* value); 3275 void RemoveEntry(int entry); 3276 3277 // Returns the index to the value of an entry. EntryToValueIndex(int entry)3278 static inline int EntryToValueIndex(int entry) { 3279 return EntryToIndex(entry) + 1; 3280 } 3281 }; 3282 3283 3284 // JSFunctionResultCache caches results of some JSFunction invocation. 3285 // It is a fixed array with fixed structure: 3286 // [0]: factory function 3287 // [1]: finger index 3288 // [2]: current cache size 3289 // [3]: dummy field. 3290 // The rest of array are key/value pairs. 3291 class JSFunctionResultCache: public FixedArray { 3292 public: 3293 static const int kFactoryIndex = 0; 3294 static const int kFingerIndex = kFactoryIndex + 1; 3295 static const int kCacheSizeIndex = kFingerIndex + 1; 3296 static const int kDummyIndex = kCacheSizeIndex + 1; 3297 static const int kEntriesIndex = kDummyIndex + 1; 3298 3299 static const int kEntrySize = 2; // key + value 3300 3301 static const int kFactoryOffset = kHeaderSize; 3302 static const int kFingerOffset = kFactoryOffset + kPointerSize; 3303 static const int kCacheSizeOffset = kFingerOffset + kPointerSize; 3304 3305 inline void MakeZeroSize(); 3306 inline void Clear(); 3307 3308 inline int size(); 3309 inline void set_size(int size); 3310 inline int finger_index(); 3311 inline void set_finger_index(int finger_index); 3312 3313 // Casting 3314 static inline JSFunctionResultCache* cast(Object* obj); 3315 3316 #ifdef DEBUG 3317 void JSFunctionResultCacheVerify(); 3318 #endif 3319 }; 3320 3321 3322 // ScopeInfo represents information about different scopes of a source 3323 // program and the allocation of the scope's variables. Scope information 3324 // is stored in a compressed form in ScopeInfo objects and is used 3325 // at runtime (stack dumps, deoptimization, etc.). 3326 3327 // This object provides quick access to scope info details for runtime 3328 // routines. 3329 class ScopeInfo : public FixedArray { 3330 public: 3331 static inline ScopeInfo* cast(Object* object); 3332 3333 // Return the type of this scope. 3334 ScopeType Type(); 3335 3336 // Does this scope call eval? 3337 bool CallsEval(); 3338 3339 // Return the language mode of this scope. 3340 LanguageMode language_mode(); 3341 3342 // Does this scope make a non-strict eval call? CallsNonStrictEval()3343 bool CallsNonStrictEval() { 3344 return CallsEval() && (language_mode() == CLASSIC_MODE); 3345 } 3346 3347 // Return the total number of locals allocated on the stack and in the 3348 // context. This includes the parameters that are allocated in the context. 3349 int LocalCount(); 3350 3351 // Return the number of stack slots for code. This number consists of two 3352 // parts: 3353 // 1. One stack slot per stack allocated local. 3354 // 2. One stack slot for the function name if it is stack allocated. 3355 int StackSlotCount(); 3356 3357 // Return the number of context slots for code if a context is allocated. This 3358 // number consists of three parts: 3359 // 1. Size of fixed header for every context: Context::MIN_CONTEXT_SLOTS 3360 // 2. One context slot per context allocated local. 3361 // 3. One context slot for the function name if it is context allocated. 3362 // Parameters allocated in the context count as context allocated locals. If 3363 // no contexts are allocated for this scope ContextLength returns 0. 3364 int ContextLength(); 3365 3366 // Is this scope the scope of a named function expression? 3367 bool HasFunctionName(); 3368 3369 // Return if this has context allocated locals. 3370 bool HasHeapAllocatedLocals(); 3371 3372 // Return if contexts are allocated for this scope. 3373 bool HasContext(); 3374 3375 // Return the function_name if present. 3376 String* FunctionName(); 3377 3378 // Return the name of the given parameter. 3379 String* ParameterName(int var); 3380 3381 // Return the name of the given local. 3382 String* LocalName(int var); 3383 3384 // Return the name of the given stack local. 3385 String* StackLocalName(int var); 3386 3387 // Return the name of the given context local. 3388 String* ContextLocalName(int var); 3389 3390 // Return the mode of the given context local. 3391 VariableMode ContextLocalMode(int var); 3392 3393 // Return the initialization flag of the given context local. 3394 InitializationFlag ContextLocalInitFlag(int var); 3395 3396 // Lookup support for serialized scope info. Returns the 3397 // the stack slot index for a given slot name if the slot is 3398 // present; otherwise returns a value < 0. The name must be a symbol 3399 // (canonicalized). 3400 int StackSlotIndex(String* name); 3401 3402 // Lookup support for serialized scope info. Returns the 3403 // context slot index for a given slot name if the slot is present; otherwise 3404 // returns a value < 0. The name must be a symbol (canonicalized). 3405 // If the slot is present and mode != NULL, sets *mode to the corresponding 3406 // mode for that variable. 3407 int ContextSlotIndex(String* name, 3408 VariableMode* mode, 3409 InitializationFlag* init_flag); 3410 3411 // Lookup support for serialized scope info. Returns the 3412 // parameter index for a given parameter name if the parameter is present; 3413 // otherwise returns a value < 0. The name must be a symbol (canonicalized). 3414 int ParameterIndex(String* name); 3415 3416 // Lookup support for serialized scope info. Returns the 3417 // function context slot index if the function name is present (named 3418 // function expressions, only), otherwise returns a value < 0. The name 3419 // must be a symbol (canonicalized). 3420 int FunctionContextSlotIndex(String* name, VariableMode* mode); 3421 3422 static Handle<ScopeInfo> Create(Scope* scope); 3423 3424 // Serializes empty scope info. 3425 static ScopeInfo* Empty(); 3426 3427 #ifdef DEBUG 3428 void Print(); 3429 #endif 3430 3431 // The layout of the static part of a ScopeInfo is as follows. Each entry is 3432 // numeric and occupies one array slot. 3433 // 1. A set of properties of the scope 3434 // 2. The number of parameters. This only applies to function scopes. For 3435 // non-function scopes this is 0. 3436 // 3. The number of non-parameter variables allocated on the stack. 3437 // 4. The number of non-parameter and parameter variables allocated in the 3438 // context. 3439 #define FOR_EACH_NUMERIC_FIELD(V) \ 3440 V(Flags) \ 3441 V(ParameterCount) \ 3442 V(StackLocalCount) \ 3443 V(ContextLocalCount) 3444 3445 #define FIELD_ACCESSORS(name) \ 3446 void Set##name(int value) { \ 3447 set(k##name, Smi::FromInt(value)); \ 3448 } \ 3449 int name() { \ 3450 if (length() > 0) { \ 3451 return Smi::cast(get(k##name))->value(); \ 3452 } else { \ 3453 return 0; \ 3454 } \ 3455 } 3456 FOR_EACH_NUMERIC_FIELD(FIELD_ACCESSORS) 3457 #undef FIELD_ACCESSORS 3458 3459 private: 3460 enum { 3461 #define DECL_INDEX(name) k##name, 3462 FOR_EACH_NUMERIC_FIELD(DECL_INDEX) 3463 #undef DECL_INDEX 3464 #undef FOR_EACH_NUMERIC_FIELD 3465 kVariablePartIndex 3466 }; 3467 3468 // The layout of the variable part of a ScopeInfo is as follows: 3469 // 1. ParameterEntries: 3470 // This part stores the names of the parameters for function scopes. One 3471 // slot is used per parameter, so in total this part occupies 3472 // ParameterCount() slots in the array. For other scopes than function 3473 // scopes ParameterCount() is 0. 3474 // 2. StackLocalEntries: 3475 // Contains the names of local variables that are allocated on the stack, 3476 // in increasing order of the stack slot index. One slot is used per stack 3477 // local, so in total this part occupies StackLocalCount() slots in the 3478 // array. 3479 // 3. ContextLocalNameEntries: 3480 // Contains the names of local variables and parameters that are allocated 3481 // in the context. They are stored in increasing order of the context slot 3482 // index starting with Context::MIN_CONTEXT_SLOTS. One slot is used per 3483 // context local, so in total this part occupies ContextLocalCount() slots 3484 // in the array. 3485 // 4. ContextLocalInfoEntries: 3486 // Contains the variable modes and initialization flags corresponding to 3487 // the context locals in ContextLocalNameEntries. One slot is used per 3488 // context local, so in total this part occupies ContextLocalCount() 3489 // slots in the array. 3490 // 5. FunctionNameEntryIndex: 3491 // If the scope belongs to a named function expression this part contains 3492 // information about the function variable. It always occupies two array 3493 // slots: a. The name of the function variable. 3494 // b. The context or stack slot index for the variable. 3495 int ParameterEntriesIndex(); 3496 int StackLocalEntriesIndex(); 3497 int ContextLocalNameEntriesIndex(); 3498 int ContextLocalInfoEntriesIndex(); 3499 int FunctionNameEntryIndex(); 3500 3501 // Location of the function variable for named function expressions. 3502 enum FunctionVariableInfo { 3503 NONE, // No function name present. 3504 STACK, // Function 3505 CONTEXT, 3506 UNUSED 3507 }; 3508 3509 // Properties of scopes. 3510 class TypeField: public BitField<ScopeType, 0, 3> {}; 3511 class CallsEvalField: public BitField<bool, 3, 1> {}; 3512 class LanguageModeField: public BitField<LanguageMode, 4, 2> {}; 3513 class FunctionVariableField: public BitField<FunctionVariableInfo, 6, 2> {}; 3514 class FunctionVariableMode: public BitField<VariableMode, 8, 3> {}; 3515 3516 // BitFields representing the encoded information for context locals in the 3517 // ContextLocalInfoEntries part. 3518 class ContextLocalMode: public BitField<VariableMode, 0, 3> {}; 3519 class ContextLocalInitFlag: public BitField<InitializationFlag, 3, 1> {}; 3520 }; 3521 3522 3523 // The cache for maps used by normalized (dictionary mode) objects. 3524 // Such maps do not have property descriptors, so a typical program 3525 // needs very limited number of distinct normalized maps. 3526 class NormalizedMapCache: public FixedArray { 3527 public: 3528 static const int kEntries = 64; 3529 3530 MUST_USE_RESULT MaybeObject* Get(JSObject* object, 3531 PropertyNormalizationMode mode); 3532 3533 void Clear(); 3534 3535 // Casting 3536 static inline NormalizedMapCache* cast(Object* obj); 3537 3538 #ifdef DEBUG 3539 void NormalizedMapCacheVerify(); 3540 #endif 3541 }; 3542 3543 3544 // ByteArray represents fixed sized byte arrays. Used for the relocation info 3545 // that is attached to code objects. 3546 class ByteArray: public FixedArrayBase { 3547 public: Size()3548 inline int Size() { return RoundUp(length() + kHeaderSize, kPointerSize); } 3549 3550 // Setter and getter. 3551 inline byte get(int index); 3552 inline void set(int index, byte value); 3553 3554 // Treat contents as an int array. 3555 inline int get_int(int index); 3556 SizeFor(int length)3557 static int SizeFor(int length) { 3558 return OBJECT_POINTER_ALIGN(kHeaderSize + length); 3559 } 3560 // We use byte arrays for free blocks in the heap. Given a desired size in 3561 // bytes that is a multiple of the word size and big enough to hold a byte 3562 // array, this function returns the number of elements a byte array should 3563 // have. LengthFor(int size_in_bytes)3564 static int LengthFor(int size_in_bytes) { 3565 ASSERT(IsAligned(size_in_bytes, kPointerSize)); 3566 ASSERT(size_in_bytes >= kHeaderSize); 3567 return size_in_bytes - kHeaderSize; 3568 } 3569 3570 // Returns data start address. 3571 inline Address GetDataStartAddress(); 3572 3573 // Returns a pointer to the ByteArray object for a given data start address. 3574 static inline ByteArray* FromDataStartAddress(Address address); 3575 3576 // Casting. 3577 static inline ByteArray* cast(Object* obj); 3578 3579 // Dispatched behavior. ByteArraySize()3580 inline int ByteArraySize() { 3581 return SizeFor(this->length()); 3582 } 3583 #ifdef OBJECT_PRINT ByteArrayPrint()3584 inline void ByteArrayPrint() { 3585 ByteArrayPrint(stdout); 3586 } 3587 void ByteArrayPrint(FILE* out); 3588 #endif 3589 #ifdef DEBUG 3590 void ByteArrayVerify(); 3591 #endif 3592 3593 // Layout description. 3594 static const int kAlignedSize = OBJECT_POINTER_ALIGN(kHeaderSize); 3595 3596 // Maximal memory consumption for a single ByteArray. 3597 static const int kMaxSize = 512 * MB; 3598 // Maximal length of a single ByteArray. 3599 static const int kMaxLength = kMaxSize - kHeaderSize; 3600 3601 private: 3602 DISALLOW_IMPLICIT_CONSTRUCTORS(ByteArray); 3603 }; 3604 3605 3606 // FreeSpace represents fixed sized areas of the heap that are not currently in 3607 // use. Used by the heap and GC. 3608 class FreeSpace: public HeapObject { 3609 public: 3610 // [size]: size of the free space including the header. 3611 inline int size(); 3612 inline void set_size(int value); 3613 Size()3614 inline int Size() { return size(); } 3615 3616 // Casting. 3617 static inline FreeSpace* cast(Object* obj); 3618 3619 #ifdef OBJECT_PRINT FreeSpacePrint()3620 inline void FreeSpacePrint() { 3621 FreeSpacePrint(stdout); 3622 } 3623 void FreeSpacePrint(FILE* out); 3624 #endif 3625 #ifdef DEBUG 3626 void FreeSpaceVerify(); 3627 #endif 3628 3629 // Layout description. 3630 // Size is smi tagged when it is stored. 3631 static const int kSizeOffset = HeapObject::kHeaderSize; 3632 static const int kHeaderSize = kSizeOffset + kPointerSize; 3633 3634 static const int kAlignedSize = OBJECT_POINTER_ALIGN(kHeaderSize); 3635 3636 private: 3637 DISALLOW_IMPLICIT_CONSTRUCTORS(FreeSpace); 3638 }; 3639 3640 3641 // An ExternalArray represents a fixed-size array of primitive values 3642 // which live outside the JavaScript heap. Its subclasses are used to 3643 // implement the CanvasArray types being defined in the WebGL 3644 // specification. As of this writing the first public draft is not yet 3645 // available, but Khronos members can access the draft at: 3646 // https://cvs.khronos.org/svn/repos/3dweb/trunk/doc/spec/WebGL-spec.html 3647 // 3648 // The semantics of these arrays differ from CanvasPixelArray. 3649 // Out-of-range values passed to the setter are converted via a C 3650 // cast, not clamping. Out-of-range indices cause exceptions to be 3651 // raised rather than being silently ignored. 3652 class ExternalArray: public FixedArrayBase { 3653 public: is_the_hole(int index)3654 inline bool is_the_hole(int index) { return false; } 3655 3656 // [external_pointer]: The pointer to the external memory area backing this 3657 // external array. 3658 DECL_ACCESSORS(external_pointer, void) // Pointer to the data store. 3659 3660 // Casting. 3661 static inline ExternalArray* cast(Object* obj); 3662 3663 // Maximal acceptable length for an external array. 3664 static const int kMaxLength = 0x3fffffff; 3665 3666 // ExternalArray headers are not quadword aligned. 3667 static const int kExternalPointerOffset = 3668 POINTER_SIZE_ALIGN(FixedArrayBase::kLengthOffset + kPointerSize); 3669 static const int kHeaderSize = kExternalPointerOffset + kPointerSize; 3670 static const int kAlignedSize = OBJECT_POINTER_ALIGN(kHeaderSize); 3671 3672 private: 3673 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalArray); 3674 }; 3675 3676 3677 // A ExternalPixelArray represents a fixed-size byte array with special 3678 // semantics used for implementing the CanvasPixelArray object. Please see the 3679 // specification at: 3680 3681 // http://www.whatwg.org/specs/web-apps/current-work/ 3682 // multipage/the-canvas-element.html#canvaspixelarray 3683 // In particular, write access clamps the value written to 0 or 255 if the 3684 // value written is outside this range. 3685 class ExternalPixelArray: public ExternalArray { 3686 public: 3687 inline uint8_t* external_pixel_pointer(); 3688 3689 // Setter and getter. 3690 inline uint8_t get_scalar(int index); 3691 MUST_USE_RESULT inline MaybeObject* get(int index); 3692 inline void set(int index, uint8_t value); 3693 3694 // This accessor applies the correct conversion from Smi, HeapNumber and 3695 // undefined and clamps the converted value between 0 and 255. 3696 Object* SetValue(uint32_t index, Object* value); 3697 3698 // Casting. 3699 static inline ExternalPixelArray* cast(Object* obj); 3700 3701 #ifdef OBJECT_PRINT ExternalPixelArrayPrint()3702 inline void ExternalPixelArrayPrint() { 3703 ExternalPixelArrayPrint(stdout); 3704 } 3705 void ExternalPixelArrayPrint(FILE* out); 3706 #endif 3707 #ifdef DEBUG 3708 void ExternalPixelArrayVerify(); 3709 #endif // DEBUG 3710 3711 private: 3712 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalPixelArray); 3713 }; 3714 3715 3716 class ExternalByteArray: public ExternalArray { 3717 public: 3718 // Setter and getter. 3719 inline int8_t get_scalar(int index); 3720 MUST_USE_RESULT inline MaybeObject* get(int index); 3721 inline void set(int index, int8_t value); 3722 3723 // This accessor applies the correct conversion from Smi, HeapNumber 3724 // and undefined. 3725 MUST_USE_RESULT MaybeObject* SetValue(uint32_t index, Object* value); 3726 3727 // Casting. 3728 static inline ExternalByteArray* cast(Object* obj); 3729 3730 #ifdef OBJECT_PRINT ExternalByteArrayPrint()3731 inline void ExternalByteArrayPrint() { 3732 ExternalByteArrayPrint(stdout); 3733 } 3734 void ExternalByteArrayPrint(FILE* out); 3735 #endif 3736 #ifdef DEBUG 3737 void ExternalByteArrayVerify(); 3738 #endif // DEBUG 3739 3740 private: 3741 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalByteArray); 3742 }; 3743 3744 3745 class ExternalUnsignedByteArray: public ExternalArray { 3746 public: 3747 // Setter and getter. 3748 inline uint8_t get_scalar(int index); 3749 MUST_USE_RESULT inline MaybeObject* get(int index); 3750 inline void set(int index, uint8_t value); 3751 3752 // This accessor applies the correct conversion from Smi, HeapNumber 3753 // and undefined. 3754 MUST_USE_RESULT MaybeObject* SetValue(uint32_t index, Object* value); 3755 3756 // Casting. 3757 static inline ExternalUnsignedByteArray* cast(Object* obj); 3758 3759 #ifdef OBJECT_PRINT ExternalUnsignedByteArrayPrint()3760 inline void ExternalUnsignedByteArrayPrint() { 3761 ExternalUnsignedByteArrayPrint(stdout); 3762 } 3763 void ExternalUnsignedByteArrayPrint(FILE* out); 3764 #endif 3765 #ifdef DEBUG 3766 void ExternalUnsignedByteArrayVerify(); 3767 #endif // DEBUG 3768 3769 private: 3770 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalUnsignedByteArray); 3771 }; 3772 3773 3774 class ExternalShortArray: public ExternalArray { 3775 public: 3776 // Setter and getter. 3777 inline int16_t get_scalar(int index); 3778 MUST_USE_RESULT inline MaybeObject* get(int index); 3779 inline void set(int index, int16_t value); 3780 3781 // This accessor applies the correct conversion from Smi, HeapNumber 3782 // and undefined. 3783 MUST_USE_RESULT MaybeObject* SetValue(uint32_t index, Object* value); 3784 3785 // Casting. 3786 static inline ExternalShortArray* cast(Object* obj); 3787 3788 #ifdef OBJECT_PRINT ExternalShortArrayPrint()3789 inline void ExternalShortArrayPrint() { 3790 ExternalShortArrayPrint(stdout); 3791 } 3792 void ExternalShortArrayPrint(FILE* out); 3793 #endif 3794 #ifdef DEBUG 3795 void ExternalShortArrayVerify(); 3796 #endif // DEBUG 3797 3798 private: 3799 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalShortArray); 3800 }; 3801 3802 3803 class ExternalUnsignedShortArray: public ExternalArray { 3804 public: 3805 // Setter and getter. 3806 inline uint16_t get_scalar(int index); 3807 MUST_USE_RESULT inline MaybeObject* get(int index); 3808 inline void set(int index, uint16_t value); 3809 3810 // This accessor applies the correct conversion from Smi, HeapNumber 3811 // and undefined. 3812 MUST_USE_RESULT MaybeObject* SetValue(uint32_t index, Object* value); 3813 3814 // Casting. 3815 static inline ExternalUnsignedShortArray* cast(Object* obj); 3816 3817 #ifdef OBJECT_PRINT ExternalUnsignedShortArrayPrint()3818 inline void ExternalUnsignedShortArrayPrint() { 3819 ExternalUnsignedShortArrayPrint(stdout); 3820 } 3821 void ExternalUnsignedShortArrayPrint(FILE* out); 3822 #endif 3823 #ifdef DEBUG 3824 void ExternalUnsignedShortArrayVerify(); 3825 #endif // DEBUG 3826 3827 private: 3828 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalUnsignedShortArray); 3829 }; 3830 3831 3832 class ExternalIntArray: public ExternalArray { 3833 public: 3834 // Setter and getter. 3835 inline int32_t get_scalar(int index); 3836 MUST_USE_RESULT inline MaybeObject* get(int index); 3837 inline void set(int index, int32_t value); 3838 3839 // This accessor applies the correct conversion from Smi, HeapNumber 3840 // and undefined. 3841 MUST_USE_RESULT MaybeObject* SetValue(uint32_t index, Object* value); 3842 3843 // Casting. 3844 static inline ExternalIntArray* cast(Object* obj); 3845 3846 #ifdef OBJECT_PRINT ExternalIntArrayPrint()3847 inline void ExternalIntArrayPrint() { 3848 ExternalIntArrayPrint(stdout); 3849 } 3850 void ExternalIntArrayPrint(FILE* out); 3851 #endif 3852 #ifdef DEBUG 3853 void ExternalIntArrayVerify(); 3854 #endif // DEBUG 3855 3856 private: 3857 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalIntArray); 3858 }; 3859 3860 3861 class ExternalUnsignedIntArray: public ExternalArray { 3862 public: 3863 // Setter and getter. 3864 inline uint32_t get_scalar(int index); 3865 MUST_USE_RESULT inline MaybeObject* get(int index); 3866 inline void set(int index, uint32_t value); 3867 3868 // This accessor applies the correct conversion from Smi, HeapNumber 3869 // and undefined. 3870 MUST_USE_RESULT MaybeObject* SetValue(uint32_t index, Object* value); 3871 3872 // Casting. 3873 static inline ExternalUnsignedIntArray* cast(Object* obj); 3874 3875 #ifdef OBJECT_PRINT ExternalUnsignedIntArrayPrint()3876 inline void ExternalUnsignedIntArrayPrint() { 3877 ExternalUnsignedIntArrayPrint(stdout); 3878 } 3879 void ExternalUnsignedIntArrayPrint(FILE* out); 3880 #endif 3881 #ifdef DEBUG 3882 void ExternalUnsignedIntArrayVerify(); 3883 #endif // DEBUG 3884 3885 private: 3886 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalUnsignedIntArray); 3887 }; 3888 3889 3890 class ExternalFloatArray: public ExternalArray { 3891 public: 3892 // Setter and getter. 3893 inline float get_scalar(int index); 3894 MUST_USE_RESULT inline MaybeObject* get(int index); 3895 inline void set(int index, float value); 3896 3897 // This accessor applies the correct conversion from Smi, HeapNumber 3898 // and undefined. 3899 MUST_USE_RESULT MaybeObject* SetValue(uint32_t index, Object* value); 3900 3901 // Casting. 3902 static inline ExternalFloatArray* cast(Object* obj); 3903 3904 #ifdef OBJECT_PRINT ExternalFloatArrayPrint()3905 inline void ExternalFloatArrayPrint() { 3906 ExternalFloatArrayPrint(stdout); 3907 } 3908 void ExternalFloatArrayPrint(FILE* out); 3909 #endif 3910 #ifdef DEBUG 3911 void ExternalFloatArrayVerify(); 3912 #endif // DEBUG 3913 3914 private: 3915 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalFloatArray); 3916 }; 3917 3918 3919 class ExternalDoubleArray: public ExternalArray { 3920 public: 3921 // Setter and getter. 3922 inline double get_scalar(int index); 3923 MUST_USE_RESULT inline MaybeObject* get(int index); 3924 inline void set(int index, double value); 3925 3926 // This accessor applies the correct conversion from Smi, HeapNumber 3927 // and undefined. 3928 MUST_USE_RESULT MaybeObject* SetValue(uint32_t index, Object* value); 3929 3930 // Casting. 3931 static inline ExternalDoubleArray* cast(Object* obj); 3932 3933 #ifdef OBJECT_PRINT ExternalDoubleArrayPrint()3934 inline void ExternalDoubleArrayPrint() { 3935 ExternalDoubleArrayPrint(stdout); 3936 } 3937 void ExternalDoubleArrayPrint(FILE* out); 3938 #endif // OBJECT_PRINT 3939 #ifdef DEBUG 3940 void ExternalDoubleArrayVerify(); 3941 #endif // DEBUG 3942 3943 private: 3944 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalDoubleArray); 3945 }; 3946 3947 3948 // DeoptimizationInputData is a fixed array used to hold the deoptimization 3949 // data for code generated by the Hydrogen/Lithium compiler. It also 3950 // contains information about functions that were inlined. If N different 3951 // functions were inlined then first N elements of the literal array will 3952 // contain these functions. 3953 // 3954 // It can be empty. 3955 class DeoptimizationInputData: public FixedArray { 3956 public: 3957 // Layout description. Indices in the array. 3958 static const int kTranslationByteArrayIndex = 0; 3959 static const int kInlinedFunctionCountIndex = 1; 3960 static const int kLiteralArrayIndex = 2; 3961 static const int kOsrAstIdIndex = 3; 3962 static const int kOsrPcOffsetIndex = 4; 3963 static const int kFirstDeoptEntryIndex = 5; 3964 3965 // Offsets of deopt entry elements relative to the start of the entry. 3966 static const int kAstIdOffset = 0; 3967 static const int kTranslationIndexOffset = 1; 3968 static const int kArgumentsStackHeightOffset = 2; 3969 static const int kPcOffset = 3; 3970 static const int kDeoptEntrySize = 4; 3971 3972 // Simple element accessors. 3973 #define DEFINE_ELEMENT_ACCESSORS(name, type) \ 3974 type* name() { \ 3975 return type::cast(get(k##name##Index)); \ 3976 } \ 3977 void Set##name(type* value) { \ 3978 set(k##name##Index, value); \ 3979 } 3980 DEFINE_ELEMENT_ACCESSORS(TranslationByteArray,ByteArray)3981 DEFINE_ELEMENT_ACCESSORS(TranslationByteArray, ByteArray) 3982 DEFINE_ELEMENT_ACCESSORS(InlinedFunctionCount, Smi) 3983 DEFINE_ELEMENT_ACCESSORS(LiteralArray, FixedArray) 3984 DEFINE_ELEMENT_ACCESSORS(OsrAstId, Smi) 3985 DEFINE_ELEMENT_ACCESSORS(OsrPcOffset, Smi) 3986 3987 #undef DEFINE_ELEMENT_ACCESSORS 3988 3989 // Accessors for elements of the ith deoptimization entry. 3990 #define DEFINE_ENTRY_ACCESSORS(name, type) \ 3991 type* name(int i) { \ 3992 return type::cast(get(IndexForEntry(i) + k##name##Offset)); \ 3993 } \ 3994 void Set##name(int i, type* value) { \ 3995 set(IndexForEntry(i) + k##name##Offset, value); \ 3996 } 3997 3998 DEFINE_ENTRY_ACCESSORS(AstId, Smi) 3999 DEFINE_ENTRY_ACCESSORS(TranslationIndex, Smi) 4000 DEFINE_ENTRY_ACCESSORS(ArgumentsStackHeight, Smi) 4001 DEFINE_ENTRY_ACCESSORS(Pc, Smi) 4002 4003 #undef DEFINE_ENTRY_ACCESSORS 4004 4005 int DeoptCount() { 4006 return (length() - kFirstDeoptEntryIndex) / kDeoptEntrySize; 4007 } 4008 4009 // Allocates a DeoptimizationInputData. 4010 MUST_USE_RESULT static MaybeObject* Allocate(int deopt_entry_count, 4011 PretenureFlag pretenure); 4012 4013 // Casting. 4014 static inline DeoptimizationInputData* cast(Object* obj); 4015 4016 #ifdef ENABLE_DISASSEMBLER 4017 void DeoptimizationInputDataPrint(FILE* out); 4018 #endif 4019 4020 private: IndexForEntry(int i)4021 static int IndexForEntry(int i) { 4022 return kFirstDeoptEntryIndex + (i * kDeoptEntrySize); 4023 } 4024 LengthFor(int entry_count)4025 static int LengthFor(int entry_count) { 4026 return IndexForEntry(entry_count); 4027 } 4028 }; 4029 4030 4031 // DeoptimizationOutputData is a fixed array used to hold the deoptimization 4032 // data for code generated by the full compiler. 4033 // The format of the these objects is 4034 // [i * 2]: Ast ID for ith deoptimization. 4035 // [i * 2 + 1]: PC and state of ith deoptimization 4036 class DeoptimizationOutputData: public FixedArray { 4037 public: DeoptPoints()4038 int DeoptPoints() { return length() / 2; } AstId(int index)4039 Smi* AstId(int index) { return Smi::cast(get(index * 2)); } SetAstId(int index,Smi * id)4040 void SetAstId(int index, Smi* id) { set(index * 2, id); } PcAndState(int index)4041 Smi* PcAndState(int index) { return Smi::cast(get(1 + index * 2)); } SetPcAndState(int index,Smi * offset)4042 void SetPcAndState(int index, Smi* offset) { set(1 + index * 2, offset); } 4043 LengthOfFixedArray(int deopt_points)4044 static int LengthOfFixedArray(int deopt_points) { 4045 return deopt_points * 2; 4046 } 4047 4048 // Allocates a DeoptimizationOutputData. 4049 MUST_USE_RESULT static MaybeObject* Allocate(int number_of_deopt_points, 4050 PretenureFlag pretenure); 4051 4052 // Casting. 4053 static inline DeoptimizationOutputData* cast(Object* obj); 4054 4055 #if defined(OBJECT_PRINT) || defined(ENABLE_DISASSEMBLER) 4056 void DeoptimizationOutputDataPrint(FILE* out); 4057 #endif 4058 }; 4059 4060 4061 // Forward declaration. 4062 class JSGlobalPropertyCell; 4063 4064 // TypeFeedbackCells is a fixed array used to hold the association between 4065 // cache cells and AST ids for code generated by the full compiler. 4066 // The format of the these objects is 4067 // [i * 2]: Global property cell of ith cache cell. 4068 // [i * 2 + 1]: Ast ID for ith cache cell. 4069 class TypeFeedbackCells: public FixedArray { 4070 public: CellCount()4071 int CellCount() { return length() / 2; } LengthOfFixedArray(int cell_count)4072 static int LengthOfFixedArray(int cell_count) { return cell_count * 2; } 4073 4074 // Accessors for AST ids associated with cache values. 4075 inline Smi* AstId(int index); 4076 inline void SetAstId(int index, Smi* id); 4077 4078 // Accessors for global property cells holding the cache values. 4079 inline JSGlobalPropertyCell* Cell(int index); 4080 inline void SetCell(int index, JSGlobalPropertyCell* cell); 4081 4082 // The object that indicates an uninitialized cache. 4083 static inline Handle<Object> UninitializedSentinel(Isolate* isolate); 4084 4085 // The object that indicates a megamorphic state. 4086 static inline Handle<Object> MegamorphicSentinel(Isolate* isolate); 4087 4088 // A raw version of the uninitialized sentinel that's safe to read during 4089 // garbage collection (e.g., for patching the cache). 4090 static inline Object* RawUninitializedSentinel(Heap* heap); 4091 4092 // Casting. 4093 static inline TypeFeedbackCells* cast(Object* obj); 4094 4095 static const int kForInFastCaseMarker = 0; 4096 static const int kForInSlowCaseMarker = 1; 4097 }; 4098 4099 4100 // Forward declaration. 4101 class SafepointEntry; 4102 class TypeFeedbackInfo; 4103 4104 // Code describes objects with on-the-fly generated machine code. 4105 class Code: public HeapObject { 4106 public: 4107 // Opaque data type for encapsulating code flags like kind, inline 4108 // cache state, and arguments count. 4109 // FLAGS_MIN_VALUE and FLAGS_MAX_VALUE are specified to ensure that 4110 // enumeration type has correct value range (see Issue 830 for more details). 4111 enum Flags { 4112 FLAGS_MIN_VALUE = kMinInt, 4113 FLAGS_MAX_VALUE = kMaxInt 4114 }; 4115 4116 enum Kind { 4117 FUNCTION, 4118 OPTIMIZED_FUNCTION, 4119 STUB, 4120 BUILTIN, 4121 LOAD_IC, 4122 KEYED_LOAD_IC, 4123 CALL_IC, 4124 KEYED_CALL_IC, 4125 STORE_IC, 4126 KEYED_STORE_IC, 4127 UNARY_OP_IC, 4128 BINARY_OP_IC, 4129 COMPARE_IC, 4130 TO_BOOLEAN_IC, 4131 // No more than 16 kinds. The value currently encoded in four bits in 4132 // Flags. 4133 4134 // Pseudo-kinds. 4135 REGEXP = BUILTIN, 4136 FIRST_IC_KIND = LOAD_IC, 4137 LAST_IC_KIND = TO_BOOLEAN_IC 4138 }; 4139 4140 enum { 4141 NUMBER_OF_KINDS = LAST_IC_KIND + 1 4142 }; 4143 4144 typedef int ExtraICState; 4145 4146 static const ExtraICState kNoExtraICState = 0; 4147 4148 #ifdef ENABLE_DISASSEMBLER 4149 // Printing 4150 static const char* Kind2String(Kind kind); 4151 static const char* ICState2String(InlineCacheState state); 4152 static const char* PropertyType2String(PropertyType type); 4153 static void PrintExtraICState(FILE* out, Kind kind, ExtraICState extra); Disassemble(const char * name)4154 inline void Disassemble(const char* name) { 4155 Disassemble(name, stdout); 4156 } 4157 void Disassemble(const char* name, FILE* out); 4158 #endif // ENABLE_DISASSEMBLER 4159 4160 // [instruction_size]: Size of the native instructions 4161 inline int instruction_size(); 4162 inline void set_instruction_size(int value); 4163 4164 // [relocation_info]: Code relocation information 4165 DECL_ACCESSORS(relocation_info, ByteArray) 4166 void InvalidateRelocation(); 4167 4168 // [handler_table]: Fixed array containing offsets of exception handlers. 4169 DECL_ACCESSORS(handler_table, FixedArray) 4170 4171 // [deoptimization_data]: Array containing data for deopt. 4172 DECL_ACCESSORS(deoptimization_data, FixedArray) 4173 4174 // [type_feedback_info]: Struct containing type feedback information. 4175 // Will contain either a TypeFeedbackInfo object, or undefined. 4176 DECL_ACCESSORS(type_feedback_info, Object) 4177 4178 // [gc_metadata]: Field used to hold GC related metadata. The contents of this 4179 // field does not have to be traced during garbage collection since 4180 // it is only used by the garbage collector itself. 4181 DECL_ACCESSORS(gc_metadata, Object) 4182 4183 // [ic_age]: Inline caching age: the value of the Heap::global_ic_age 4184 // at the moment when this object was created. 4185 inline void set_ic_age(int count); 4186 inline int ic_age(); 4187 4188 // Unchecked accessors to be used during GC. 4189 inline ByteArray* unchecked_relocation_info(); 4190 inline FixedArray* unchecked_deoptimization_data(); 4191 4192 inline int relocation_size(); 4193 4194 // [flags]: Various code flags. 4195 inline Flags flags(); 4196 inline void set_flags(Flags flags); 4197 4198 // [flags]: Access to specific code flags. 4199 inline Kind kind(); 4200 inline InlineCacheState ic_state(); // Only valid for IC stubs. 4201 inline ExtraICState extra_ic_state(); // Only valid for IC stubs. 4202 inline PropertyType type(); // Only valid for monomorphic IC stubs. 4203 inline int arguments_count(); // Only valid for call IC stubs. 4204 4205 // Testers for IC stub kinds. 4206 inline bool is_inline_cache_stub(); is_load_stub()4207 inline bool is_load_stub() { return kind() == LOAD_IC; } is_keyed_load_stub()4208 inline bool is_keyed_load_stub() { return kind() == KEYED_LOAD_IC; } is_store_stub()4209 inline bool is_store_stub() { return kind() == STORE_IC; } is_keyed_store_stub()4210 inline bool is_keyed_store_stub() { return kind() == KEYED_STORE_IC; } is_call_stub()4211 inline bool is_call_stub() { return kind() == CALL_IC; } is_keyed_call_stub()4212 inline bool is_keyed_call_stub() { return kind() == KEYED_CALL_IC; } is_unary_op_stub()4213 inline bool is_unary_op_stub() { return kind() == UNARY_OP_IC; } is_binary_op_stub()4214 inline bool is_binary_op_stub() { return kind() == BINARY_OP_IC; } is_compare_ic_stub()4215 inline bool is_compare_ic_stub() { return kind() == COMPARE_IC; } is_to_boolean_ic_stub()4216 inline bool is_to_boolean_ic_stub() { return kind() == TO_BOOLEAN_IC; } 4217 4218 // [major_key]: For kind STUB or BINARY_OP_IC, the major key. 4219 inline int major_key(); 4220 inline void set_major_key(int value); 4221 4222 // For stubs, tells whether they should always exist, so that they can be 4223 // called from other stubs. 4224 inline bool is_pregenerated(); 4225 inline void set_is_pregenerated(bool value); 4226 4227 // [optimizable]: For FUNCTION kind, tells if it is optimizable. 4228 inline bool optimizable(); 4229 inline void set_optimizable(bool value); 4230 4231 // [has_deoptimization_support]: For FUNCTION kind, tells if it has 4232 // deoptimization support. 4233 inline bool has_deoptimization_support(); 4234 inline void set_has_deoptimization_support(bool value); 4235 4236 // [has_debug_break_slots]: For FUNCTION kind, tells if it has 4237 // been compiled with debug break slots. 4238 inline bool has_debug_break_slots(); 4239 inline void set_has_debug_break_slots(bool value); 4240 4241 // [compiled_with_optimizing]: For FUNCTION kind, tells if it has 4242 // been compiled with IsOptimizing set to true. 4243 inline bool is_compiled_optimizable(); 4244 inline void set_compiled_optimizable(bool value); 4245 4246 // [has_self_optimization_header]: For FUNCTION kind, tells if it has 4247 // a self-optimization header. 4248 inline bool has_self_optimization_header(); 4249 inline void set_self_optimization_header(bool value); 4250 4251 // [allow_osr_at_loop_nesting_level]: For FUNCTION kind, tells for 4252 // how long the function has been marked for OSR and therefore which 4253 // level of loop nesting we are willing to do on-stack replacement 4254 // for. 4255 inline void set_allow_osr_at_loop_nesting_level(int level); 4256 inline int allow_osr_at_loop_nesting_level(); 4257 4258 // [profiler_ticks]: For FUNCTION kind, tells for how many profiler ticks 4259 // the code object was seen on the stack with no IC patching going on. 4260 inline int profiler_ticks(); 4261 inline void set_profiler_ticks(int ticks); 4262 4263 // [stack_slots]: For kind OPTIMIZED_FUNCTION, the number of stack slots 4264 // reserved in the code prologue. 4265 inline unsigned stack_slots(); 4266 inline void set_stack_slots(unsigned slots); 4267 4268 // [safepoint_table_start]: For kind OPTIMIZED_CODE, the offset in 4269 // the instruction stream where the safepoint table starts. 4270 inline unsigned safepoint_table_offset(); 4271 inline void set_safepoint_table_offset(unsigned offset); 4272 4273 // [stack_check_table_start]: For kind FUNCTION, the offset in the 4274 // instruction stream where the stack check table starts. 4275 inline unsigned stack_check_table_offset(); 4276 inline void set_stack_check_table_offset(unsigned offset); 4277 4278 // [check type]: For kind CALL_IC, tells how to check if the 4279 // receiver is valid for the given call. 4280 inline CheckType check_type(); 4281 inline void set_check_type(CheckType value); 4282 4283 // [type-recording unary op type]: For kind UNARY_OP_IC. 4284 inline byte unary_op_type(); 4285 inline void set_unary_op_type(byte value); 4286 4287 // [type-recording binary op type]: For kind BINARY_OP_IC. 4288 inline byte binary_op_type(); 4289 inline void set_binary_op_type(byte value); 4290 inline byte binary_op_result_type(); 4291 inline void set_binary_op_result_type(byte value); 4292 4293 // [compare state]: For kind COMPARE_IC, tells what state the stub is in. 4294 inline byte compare_state(); 4295 inline void set_compare_state(byte value); 4296 4297 // [to_boolean_foo]: For kind TO_BOOLEAN_IC tells what state the stub is in. 4298 inline byte to_boolean_state(); 4299 inline void set_to_boolean_state(byte value); 4300 4301 // [has_function_cache]: For kind STUB tells whether there is a function 4302 // cache is passed to the stub. 4303 inline bool has_function_cache(); 4304 inline void set_has_function_cache(bool flag); 4305 4306 // Get the safepoint entry for the given pc. 4307 SafepointEntry GetSafepointEntry(Address pc); 4308 4309 // Mark this code object as not having a stack check table. Assumes kind 4310 // is FUNCTION. 4311 void SetNoStackCheckTable(); 4312 4313 // Find the first map in an IC stub. 4314 Map* FindFirstMap(); 4315 4316 class ExtraICStateStrictMode: public BitField<StrictModeFlag, 0, 1> {}; 4317 class ExtraICStateKeyedAccessGrowMode: 4318 public BitField<KeyedAccessGrowMode, 1, 1> {}; // NOLINT 4319 4320 static const int kExtraICStateGrowModeShift = 1; 4321 GetStrictMode(ExtraICState extra_ic_state)4322 static inline StrictModeFlag GetStrictMode(ExtraICState extra_ic_state) { 4323 return ExtraICStateStrictMode::decode(extra_ic_state); 4324 } 4325 GetKeyedAccessGrowMode(ExtraICState extra_ic_state)4326 static inline KeyedAccessGrowMode GetKeyedAccessGrowMode( 4327 ExtraICState extra_ic_state) { 4328 return ExtraICStateKeyedAccessGrowMode::decode(extra_ic_state); 4329 } 4330 ComputeExtraICState(KeyedAccessGrowMode grow_mode,StrictModeFlag strict_mode)4331 static inline ExtraICState ComputeExtraICState( 4332 KeyedAccessGrowMode grow_mode, 4333 StrictModeFlag strict_mode) { 4334 return ExtraICStateKeyedAccessGrowMode::encode(grow_mode) | 4335 ExtraICStateStrictMode::encode(strict_mode); 4336 } 4337 4338 // Flags operations. 4339 static inline Flags ComputeFlags( 4340 Kind kind, 4341 InlineCacheState ic_state = UNINITIALIZED, 4342 ExtraICState extra_ic_state = kNoExtraICState, 4343 PropertyType type = NORMAL, 4344 int argc = -1, 4345 InlineCacheHolderFlag holder = OWN_MAP); 4346 4347 static inline Flags ComputeMonomorphicFlags( 4348 Kind kind, 4349 PropertyType type, 4350 ExtraICState extra_ic_state = kNoExtraICState, 4351 InlineCacheHolderFlag holder = OWN_MAP, 4352 int argc = -1); 4353 4354 static inline InlineCacheState ExtractICStateFromFlags(Flags flags); 4355 static inline PropertyType ExtractTypeFromFlags(Flags flags); 4356 static inline Kind ExtractKindFromFlags(Flags flags); 4357 static inline InlineCacheHolderFlag ExtractCacheHolderFromFlags(Flags flags); 4358 static inline ExtraICState ExtractExtraICStateFromFlags(Flags flags); 4359 static inline int ExtractArgumentsCountFromFlags(Flags flags); 4360 4361 static inline Flags RemoveTypeFromFlags(Flags flags); 4362 4363 // Convert a target address into a code object. 4364 static inline Code* GetCodeFromTargetAddress(Address address); 4365 4366 // Convert an entry address into an object. 4367 static inline Object* GetObjectFromEntryAddress(Address location_of_address); 4368 4369 // Returns the address of the first instruction. 4370 inline byte* instruction_start(); 4371 4372 // Returns the address right after the last instruction. 4373 inline byte* instruction_end(); 4374 4375 // Returns the size of the instructions, padding, and relocation information. 4376 inline int body_size(); 4377 4378 // Returns the address of the first relocation info (read backwards!). 4379 inline byte* relocation_start(); 4380 4381 // Code entry point. 4382 inline byte* entry(); 4383 4384 // Returns true if pc is inside this object's instructions. 4385 inline bool contains(byte* pc); 4386 4387 // Relocate the code by delta bytes. Called to signal that this code 4388 // object has been moved by delta bytes. 4389 void Relocate(intptr_t delta); 4390 4391 // Migrate code described by desc. 4392 void CopyFrom(const CodeDesc& desc); 4393 4394 // Returns the object size for a given body (used for allocation). SizeFor(int body_size)4395 static int SizeFor(int body_size) { 4396 ASSERT_SIZE_TAG_ALIGNED(body_size); 4397 return RoundUp(kHeaderSize + body_size, kCodeAlignment); 4398 } 4399 4400 // Calculate the size of the code object to report for log events. This takes 4401 // the layout of the code object into account. ExecutableSize()4402 int ExecutableSize() { 4403 // Check that the assumptions about the layout of the code object holds. 4404 ASSERT_EQ(static_cast<int>(instruction_start() - address()), 4405 Code::kHeaderSize); 4406 return instruction_size() + Code::kHeaderSize; 4407 } 4408 4409 // Locating source position. 4410 int SourcePosition(Address pc); 4411 int SourceStatementPosition(Address pc); 4412 4413 // Casting. 4414 static inline Code* cast(Object* obj); 4415 4416 // Dispatched behavior. CodeSize()4417 int CodeSize() { return SizeFor(body_size()); } 4418 inline void CodeIterateBody(ObjectVisitor* v); 4419 4420 template<typename StaticVisitor> 4421 inline void CodeIterateBody(Heap* heap); 4422 #ifdef OBJECT_PRINT CodePrint()4423 inline void CodePrint() { 4424 CodePrint(stdout); 4425 } 4426 void CodePrint(FILE* out); 4427 #endif 4428 #ifdef DEBUG 4429 void CodeVerify(); 4430 #endif 4431 void ClearInlineCaches(); 4432 4433 // Max loop nesting marker used to postpose OSR. We don't take loop 4434 // nesting that is deeper than 5 levels into account. 4435 static const int kMaxLoopNestingMarker = 6; 4436 4437 // Layout description. 4438 static const int kInstructionSizeOffset = HeapObject::kHeaderSize; 4439 static const int kRelocationInfoOffset = kInstructionSizeOffset + kIntSize; 4440 static const int kHandlerTableOffset = kRelocationInfoOffset + kPointerSize; 4441 static const int kDeoptimizationDataOffset = 4442 kHandlerTableOffset + kPointerSize; 4443 static const int kTypeFeedbackInfoOffset = 4444 kDeoptimizationDataOffset + kPointerSize; 4445 static const int kGCMetadataOffset = kTypeFeedbackInfoOffset + kPointerSize; 4446 static const int kICAgeOffset = 4447 kGCMetadataOffset + kPointerSize; 4448 static const int kFlagsOffset = kICAgeOffset + kIntSize; 4449 static const int kKindSpecificFlagsOffset = kFlagsOffset + kIntSize; 4450 static const int kKindSpecificFlagsSize = 2 * kIntSize; 4451 4452 static const int kHeaderPaddingStart = kKindSpecificFlagsOffset + 4453 kKindSpecificFlagsSize; 4454 4455 // Add padding to align the instruction start following right after 4456 // the Code object header. 4457 static const int kHeaderSize = 4458 (kHeaderPaddingStart + kCodeAlignmentMask) & ~kCodeAlignmentMask; 4459 4460 // Byte offsets within kKindSpecificFlagsOffset. 4461 static const int kStubMajorKeyOffset = kKindSpecificFlagsOffset; 4462 static const int kOptimizableOffset = kKindSpecificFlagsOffset; 4463 static const int kStackSlotsOffset = kKindSpecificFlagsOffset; 4464 static const int kCheckTypeOffset = kKindSpecificFlagsOffset; 4465 4466 static const int kUnaryOpTypeOffset = kStubMajorKeyOffset + 1; 4467 static const int kBinaryOpTypeOffset = kStubMajorKeyOffset + 1; 4468 static const int kCompareStateOffset = kStubMajorKeyOffset + 1; 4469 static const int kToBooleanTypeOffset = kStubMajorKeyOffset + 1; 4470 static const int kHasFunctionCacheOffset = kStubMajorKeyOffset + 1; 4471 4472 static const int kFullCodeFlags = kOptimizableOffset + 1; 4473 class FullCodeFlagsHasDeoptimizationSupportField: 4474 public BitField<bool, 0, 1> {}; // NOLINT 4475 class FullCodeFlagsHasDebugBreakSlotsField: public BitField<bool, 1, 1> {}; 4476 class FullCodeFlagsIsCompiledOptimizable: public BitField<bool, 2, 1> {}; 4477 class FullCodeFlagsHasSelfOptimizationHeader: public BitField<bool, 3, 1> {}; 4478 4479 static const int kBinaryOpReturnTypeOffset = kBinaryOpTypeOffset + 1; 4480 4481 static const int kAllowOSRAtLoopNestingLevelOffset = kFullCodeFlags + 1; 4482 static const int kProfilerTicksOffset = kAllowOSRAtLoopNestingLevelOffset + 1; 4483 4484 static const int kSafepointTableOffsetOffset = kStackSlotsOffset + kIntSize; 4485 static const int kStackCheckTableOffsetOffset = kStackSlotsOffset + kIntSize; 4486 4487 // Flags layout. BitField<type, shift, size>. 4488 class ICStateField: public BitField<InlineCacheState, 0, 3> {}; 4489 class TypeField: public BitField<PropertyType, 3, 4> {}; 4490 class CacheHolderField: public BitField<InlineCacheHolderFlag, 7, 1> {}; 4491 class KindField: public BitField<Kind, 8, 4> {}; 4492 class ExtraICStateField: public BitField<ExtraICState, 12, 2> {}; 4493 class IsPregeneratedField: public BitField<bool, 14, 1> {}; 4494 4495 // Signed field cannot be encoded using the BitField class. 4496 static const int kArgumentsCountShift = 15; 4497 static const int kArgumentsCountMask = ~((1 << kArgumentsCountShift) - 1); 4498 4499 // This constant should be encodable in an ARM instruction. 4500 static const int kFlagsNotUsedInLookup = 4501 TypeField::kMask | CacheHolderField::kMask; 4502 4503 private: 4504 DISALLOW_IMPLICIT_CONSTRUCTORS(Code); 4505 }; 4506 4507 4508 // All heap objects have a Map that describes their structure. 4509 // A Map contains information about: 4510 // - Size information about the object 4511 // - How to iterate over an object (for garbage collection) 4512 class Map: public HeapObject { 4513 public: 4514 // Instance size. 4515 // Size in bytes or kVariableSizeSentinel if instances do not have 4516 // a fixed size. 4517 inline int instance_size(); 4518 inline void set_instance_size(int value); 4519 4520 // Count of properties allocated in the object. 4521 inline int inobject_properties(); 4522 inline void set_inobject_properties(int value); 4523 4524 // Count of property fields pre-allocated in the object when first allocated. 4525 inline int pre_allocated_property_fields(); 4526 inline void set_pre_allocated_property_fields(int value); 4527 4528 // Instance type. 4529 inline InstanceType instance_type(); 4530 inline void set_instance_type(InstanceType value); 4531 4532 // Tells how many unused property fields are available in the 4533 // instance (only used for JSObject in fast mode). 4534 inline int unused_property_fields(); 4535 inline void set_unused_property_fields(int value); 4536 4537 // Bit field. 4538 inline byte bit_field(); 4539 inline void set_bit_field(byte value); 4540 4541 // Bit field 2. 4542 inline byte bit_field2(); 4543 inline void set_bit_field2(byte value); 4544 4545 // Bit field 3. 4546 // TODO(1399): It should be possible to make room for bit_field3 in the map 4547 // without overloading the instance descriptors field (and storing it in the 4548 // DescriptorArray when the map has one). 4549 inline int bit_field3(); 4550 inline void set_bit_field3(int value); 4551 4552 // Tells whether the object in the prototype property will be used 4553 // for instances created from this function. If the prototype 4554 // property is set to a value that is not a JSObject, the prototype 4555 // property will not be used to create instances of the function. 4556 // See ECMA-262, 13.2.2. 4557 inline void set_non_instance_prototype(bool value); 4558 inline bool has_non_instance_prototype(); 4559 4560 // Tells whether function has special prototype property. If not, prototype 4561 // property will not be created when accessed (will return undefined), 4562 // and construction from this function will not be allowed. 4563 inline void set_function_with_prototype(bool value); 4564 inline bool function_with_prototype(); 4565 4566 // Tells whether the instance with this map should be ignored by the 4567 // __proto__ accessor. set_is_hidden_prototype()4568 inline void set_is_hidden_prototype() { 4569 set_bit_field(bit_field() | (1 << kIsHiddenPrototype)); 4570 } 4571 is_hidden_prototype()4572 inline bool is_hidden_prototype() { 4573 return ((1 << kIsHiddenPrototype) & bit_field()) != 0; 4574 } 4575 4576 // Records and queries whether the instance has a named interceptor. set_has_named_interceptor()4577 inline void set_has_named_interceptor() { 4578 set_bit_field(bit_field() | (1 << kHasNamedInterceptor)); 4579 } 4580 has_named_interceptor()4581 inline bool has_named_interceptor() { 4582 return ((1 << kHasNamedInterceptor) & bit_field()) != 0; 4583 } 4584 4585 // Records and queries whether the instance has an indexed interceptor. set_has_indexed_interceptor()4586 inline void set_has_indexed_interceptor() { 4587 set_bit_field(bit_field() | (1 << kHasIndexedInterceptor)); 4588 } 4589 has_indexed_interceptor()4590 inline bool has_indexed_interceptor() { 4591 return ((1 << kHasIndexedInterceptor) & bit_field()) != 0; 4592 } 4593 4594 // Tells whether the instance is undetectable. 4595 // An undetectable object is a special class of JSObject: 'typeof' operator 4596 // returns undefined, ToBoolean returns false. Otherwise it behaves like 4597 // a normal JS object. It is useful for implementing undetectable 4598 // document.all in Firefox & Safari. 4599 // See https://bugzilla.mozilla.org/show_bug.cgi?id=248549. set_is_undetectable()4600 inline void set_is_undetectable() { 4601 set_bit_field(bit_field() | (1 << kIsUndetectable)); 4602 } 4603 is_undetectable()4604 inline bool is_undetectable() { 4605 return ((1 << kIsUndetectable) & bit_field()) != 0; 4606 } 4607 4608 // Tells whether the instance has a call-as-function handler. set_has_instance_call_handler()4609 inline void set_has_instance_call_handler() { 4610 set_bit_field(bit_field() | (1 << kHasInstanceCallHandler)); 4611 } 4612 has_instance_call_handler()4613 inline bool has_instance_call_handler() { 4614 return ((1 << kHasInstanceCallHandler) & bit_field()) != 0; 4615 } 4616 4617 inline void set_is_extensible(bool value); 4618 inline bool is_extensible(); 4619 set_elements_kind(ElementsKind elements_kind)4620 inline void set_elements_kind(ElementsKind elements_kind) { 4621 ASSERT(elements_kind < kElementsKindCount); 4622 ASSERT(kElementsKindCount <= (1 << kElementsKindBitCount)); 4623 set_bit_field2((bit_field2() & ~kElementsKindMask) | 4624 (elements_kind << kElementsKindShift)); 4625 ASSERT(this->elements_kind() == elements_kind); 4626 } 4627 elements_kind()4628 inline ElementsKind elements_kind() { 4629 return static_cast<ElementsKind>( 4630 (bit_field2() & kElementsKindMask) >> kElementsKindShift); 4631 } 4632 4633 // Tells whether the instance has fast elements that are only Smis. has_fast_smi_only_elements()4634 inline bool has_fast_smi_only_elements() { 4635 return elements_kind() == FAST_SMI_ONLY_ELEMENTS; 4636 } 4637 4638 // Tells whether the instance has fast elements. has_fast_elements()4639 inline bool has_fast_elements() { 4640 return elements_kind() == FAST_ELEMENTS; 4641 } 4642 has_fast_double_elements()4643 inline bool has_fast_double_elements() { 4644 return elements_kind() == FAST_DOUBLE_ELEMENTS; 4645 } 4646 has_non_strict_arguments_elements()4647 inline bool has_non_strict_arguments_elements() { 4648 return elements_kind() == NON_STRICT_ARGUMENTS_ELEMENTS; 4649 } 4650 has_external_array_elements()4651 inline bool has_external_array_elements() { 4652 ElementsKind kind(elements_kind()); 4653 return kind >= FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND && 4654 kind <= LAST_EXTERNAL_ARRAY_ELEMENTS_KIND; 4655 } 4656 has_dictionary_elements()4657 inline bool has_dictionary_elements() { 4658 return elements_kind() == DICTIONARY_ELEMENTS; 4659 } 4660 has_slow_elements_kind()4661 inline bool has_slow_elements_kind() { 4662 return elements_kind() == DICTIONARY_ELEMENTS 4663 || elements_kind() == NON_STRICT_ARGUMENTS_ELEMENTS; 4664 } 4665 4666 static bool IsValidElementsTransition(ElementsKind from_kind, 4667 ElementsKind to_kind); 4668 4669 // Tells whether the map is attached to SharedFunctionInfo 4670 // (for inobject slack tracking). 4671 inline void set_attached_to_shared_function_info(bool value); 4672 4673 inline bool attached_to_shared_function_info(); 4674 4675 // Tells whether the map is shared between objects that may have different 4676 // behavior. If true, the map should never be modified, instead a clone 4677 // should be created and modified. 4678 inline void set_is_shared(bool value); 4679 4680 inline bool is_shared(); 4681 4682 // Tells whether the instance needs security checks when accessing its 4683 // properties. 4684 inline void set_is_access_check_needed(bool access_check_needed); 4685 inline bool is_access_check_needed(); 4686 4687 // [prototype]: implicit prototype object. 4688 DECL_ACCESSORS(prototype, Object) 4689 4690 // [constructor]: points back to the function responsible for this map. 4691 DECL_ACCESSORS(constructor, Object) 4692 4693 inline JSFunction* unchecked_constructor(); 4694 4695 // Should only be called by the code that initializes map to set initial valid 4696 // value of the instance descriptor member. 4697 inline void init_instance_descriptors(); 4698 4699 // [instance descriptors]: describes the object. 4700 DECL_ACCESSORS(instance_descriptors, DescriptorArray) 4701 4702 // Sets the instance descriptor array for the map to be an empty descriptor 4703 // array. 4704 inline void clear_instance_descriptors(); 4705 4706 // [stub cache]: contains stubs compiled for this map. 4707 DECL_ACCESSORS(code_cache, Object) 4708 4709 // [prototype transitions]: cache of prototype transitions. 4710 // Prototype transition is a transition that happens 4711 // when we change object's prototype to a new one. 4712 // Cache format: 4713 // 0: finger - index of the first free cell in the cache 4714 // 1 + 2 * i: prototype 4715 // 2 + 2 * i: target map 4716 DECL_ACCESSORS(prototype_transitions, FixedArray) 4717 4718 inline FixedArray* unchecked_prototype_transitions(); 4719 4720 static const int kProtoTransitionHeaderSize = 1; 4721 static const int kProtoTransitionNumberOfEntriesOffset = 0; 4722 static const int kProtoTransitionElementsPerEntry = 2; 4723 static const int kProtoTransitionPrototypeOffset = 0; 4724 static const int kProtoTransitionMapOffset = 1; 4725 NumberOfProtoTransitions()4726 inline int NumberOfProtoTransitions() { 4727 FixedArray* cache = prototype_transitions(); 4728 if (cache->length() == 0) return 0; 4729 return 4730 Smi::cast(cache->get(kProtoTransitionNumberOfEntriesOffset))->value(); 4731 } 4732 SetNumberOfProtoTransitions(int value)4733 inline void SetNumberOfProtoTransitions(int value) { 4734 FixedArray* cache = prototype_transitions(); 4735 ASSERT(cache->length() != 0); 4736 cache->set_unchecked(kProtoTransitionNumberOfEntriesOffset, 4737 Smi::FromInt(value)); 4738 } 4739 4740 // Lookup in the map's instance descriptors and fill out the result 4741 // with the given holder if the name is found. The holder may be 4742 // NULL when this function is used from the compiler. 4743 void LookupInDescriptors(JSObject* holder, 4744 String* name, 4745 LookupResult* result); 4746 4747 MUST_USE_RESULT MaybeObject* CopyDropDescriptors(); 4748 4749 MUST_USE_RESULT MaybeObject* CopyNormalized(PropertyNormalizationMode mode, 4750 NormalizedMapSharingMode sharing); 4751 4752 // Returns a copy of the map, with all transitions dropped from the 4753 // instance descriptors. 4754 MUST_USE_RESULT MaybeObject* CopyDropTransitions(); 4755 4756 // Returns the property index for name (only valid for FAST MODE). 4757 int PropertyIndexFor(String* name); 4758 4759 // Returns the next free property index (only valid for FAST MODE). 4760 int NextFreePropertyIndex(); 4761 4762 // Returns the number of properties described in instance_descriptors 4763 // filtering out properties with the specified attributes. 4764 int NumberOfDescribedProperties(PropertyAttributes filter = NONE); 4765 4766 // Casting. 4767 static inline Map* cast(Object* obj); 4768 4769 // Locate an accessor in the instance descriptor. 4770 AccessorDescriptor* FindAccessor(String* name); 4771 4772 // Code cache operations. 4773 4774 // Clears the code cache. 4775 inline void ClearCodeCache(Heap* heap); 4776 4777 // Update code cache. 4778 static void UpdateCodeCache(Handle<Map> map, 4779 Handle<String> name, 4780 Handle<Code> code); 4781 MUST_USE_RESULT MaybeObject* UpdateCodeCache(String* name, Code* code); 4782 4783 // Returns the found code or undefined if absent. 4784 Object* FindInCodeCache(String* name, Code::Flags flags); 4785 4786 // Returns the non-negative index of the code object if it is in the 4787 // cache and -1 otherwise. 4788 int IndexInCodeCache(Object* name, Code* code); 4789 4790 // Removes a code object from the code cache at the given index. 4791 void RemoveFromCodeCache(String* name, Code* code, int index); 4792 4793 // For every transition in this map, makes the transition's 4794 // target's prototype pointer point back to this map. 4795 // This is undone in MarkCompactCollector::ClearNonLiveTransitions(). 4796 void CreateBackPointers(); 4797 4798 void CreateOneBackPointer(Object* transition_target); 4799 4800 // Set all map transitions from this map to dead maps to null. 4801 // Also, restore the original prototype on the targets of these 4802 // transitions, so that we do not process this map again while 4803 // following back pointers. 4804 void ClearNonLiveTransitions(Heap* heap, Object* real_prototype); 4805 4806 // Restore a possible back pointer in the prototype field of object. 4807 // Return true in that case and false otherwise. Set *keep_entry to 4808 // true when a live map transition has been found. 4809 bool RestoreOneBackPointer(Object* object, 4810 Object* real_prototype, 4811 bool* keep_entry); 4812 4813 // Computes a hash value for this map, to be used in HashTables and such. 4814 int Hash(); 4815 4816 // Compares this map to another to see if they describe equivalent objects. 4817 // If |mode| is set to CLEAR_INOBJECT_PROPERTIES, |other| is treated as if 4818 // it had exactly zero inobject properties. 4819 // The "shared" flags of both this map and |other| are ignored. 4820 bool EquivalentToForNormalization(Map* other, PropertyNormalizationMode mode); 4821 4822 // Returns the contents of this map's descriptor array for the given string. 4823 // May return NULL. |safe_to_add_transition| is set to false and NULL 4824 // is returned if adding transitions is not allowed. 4825 Object* GetDescriptorContents(String* sentinel_name, 4826 bool* safe_to_add_transitions); 4827 4828 // Returns the map that this map transitions to if its elements_kind 4829 // is changed to |elements_kind|, or NULL if no such map is cached yet. 4830 // |safe_to_add_transitions| is set to false if adding transitions is not 4831 // allowed. 4832 Map* LookupElementsTransitionMap(ElementsKind elements_kind, 4833 bool* safe_to_add_transition); 4834 4835 // Adds an entry to this map's descriptor array for a transition to 4836 // |transitioned_map| when its elements_kind is changed to |elements_kind|. 4837 MUST_USE_RESULT MaybeObject* AddElementsTransition( 4838 ElementsKind elements_kind, Map* transitioned_map); 4839 4840 // Returns the transitioned map for this map with the most generic 4841 // elements_kind that's found in |candidates|, or null handle if no match is 4842 // found at all. 4843 Handle<Map> FindTransitionedMap(MapHandleList* candidates); 4844 Map* FindTransitionedMap(MapList* candidates); 4845 4846 4847 // Dispatched behavior. 4848 #ifdef OBJECT_PRINT MapPrint()4849 inline void MapPrint() { 4850 MapPrint(stdout); 4851 } 4852 void MapPrint(FILE* out); 4853 #endif 4854 #ifdef DEBUG 4855 void MapVerify(); 4856 void SharedMapVerify(); 4857 #endif 4858 4859 inline int visitor_id(); 4860 inline void set_visitor_id(int visitor_id); 4861 4862 typedef void (*TraverseCallback)(Map* map, void* data); 4863 4864 void TraverseTransitionTree(TraverseCallback callback, void* data); 4865 4866 static const int kMaxCachedPrototypeTransitions = 256; 4867 4868 Object* GetPrototypeTransition(Object* prototype); 4869 4870 MUST_USE_RESULT MaybeObject* PutPrototypeTransition(Object* prototype, 4871 Map* map); 4872 4873 static const int kMaxPreAllocatedPropertyFields = 255; 4874 4875 // Layout description. 4876 static const int kInstanceSizesOffset = HeapObject::kHeaderSize; 4877 static const int kInstanceAttributesOffset = kInstanceSizesOffset + kIntSize; 4878 static const int kPrototypeOffset = kInstanceAttributesOffset + kIntSize; 4879 static const int kConstructorOffset = kPrototypeOffset + kPointerSize; 4880 // Storage for instance descriptors is overloaded to also contain additional 4881 // map flags when unused (bit_field3). When the map has instance descriptors, 4882 // the flags are transferred to the instance descriptor array and accessed 4883 // through an extra indirection. 4884 // TODO(1399): It should be possible to make room for bit_field3 in the map 4885 // without overloading the instance descriptors field, but the map is 4886 // currently perfectly aligned to 32 bytes and extending it at all would 4887 // double its size. After the increment GC work lands, this size restriction 4888 // could be loosened and bit_field3 moved directly back in the map. 4889 static const int kInstanceDescriptorsOrBitField3Offset = 4890 kConstructorOffset + kPointerSize; 4891 static const int kCodeCacheOffset = 4892 kInstanceDescriptorsOrBitField3Offset + kPointerSize; 4893 static const int kPrototypeTransitionsOffset = 4894 kCodeCacheOffset + kPointerSize; 4895 static const int kPadStart = kPrototypeTransitionsOffset + kPointerSize; 4896 static const int kSize = MAP_POINTER_ALIGN(kPadStart); 4897 4898 // Layout of pointer fields. Heap iteration code relies on them 4899 // being continuously allocated. 4900 static const int kPointerFieldsBeginOffset = Map::kPrototypeOffset; 4901 static const int kPointerFieldsEndOffset = 4902 Map::kPrototypeTransitionsOffset + kPointerSize; 4903 4904 // Byte offsets within kInstanceSizesOffset. 4905 static const int kInstanceSizeOffset = kInstanceSizesOffset + 0; 4906 static const int kInObjectPropertiesByte = 1; 4907 static const int kInObjectPropertiesOffset = 4908 kInstanceSizesOffset + kInObjectPropertiesByte; 4909 static const int kPreAllocatedPropertyFieldsByte = 2; 4910 static const int kPreAllocatedPropertyFieldsOffset = 4911 kInstanceSizesOffset + kPreAllocatedPropertyFieldsByte; 4912 static const int kVisitorIdByte = 3; 4913 static const int kVisitorIdOffset = kInstanceSizesOffset + kVisitorIdByte; 4914 4915 // Byte offsets within kInstanceAttributesOffset attributes. 4916 static const int kInstanceTypeOffset = kInstanceAttributesOffset + 0; 4917 static const int kUnusedPropertyFieldsOffset = kInstanceAttributesOffset + 1; 4918 static const int kBitFieldOffset = kInstanceAttributesOffset + 2; 4919 static const int kBitField2Offset = kInstanceAttributesOffset + 3; 4920 4921 STATIC_CHECK(kInstanceTypeOffset == Internals::kMapInstanceTypeOffset); 4922 4923 // Bit positions for bit field. 4924 static const int kUnused = 0; // To be used for marking recently used maps. 4925 static const int kHasNonInstancePrototype = 1; 4926 static const int kIsHiddenPrototype = 2; 4927 static const int kHasNamedInterceptor = 3; 4928 static const int kHasIndexedInterceptor = 4; 4929 static const int kIsUndetectable = 5; 4930 static const int kHasInstanceCallHandler = 6; 4931 static const int kIsAccessCheckNeeded = 7; 4932 4933 // Bit positions for bit field 2 4934 static const int kIsExtensible = 0; 4935 static const int kFunctionWithPrototype = 1; 4936 static const int kStringWrapperSafeForDefaultValueOf = 2; 4937 static const int kAttachedToSharedFunctionInfo = 3; 4938 // No bits can be used after kElementsKindFirstBit, they are all reserved for 4939 // storing ElementKind. 4940 static const int kElementsKindShift = 4; 4941 static const int kElementsKindBitCount = 4; 4942 4943 // Derived values from bit field 2 4944 static const int kElementsKindMask = (-1 << kElementsKindShift) & 4945 ((1 << (kElementsKindShift + kElementsKindBitCount)) - 1); 4946 static const int8_t kMaximumBitField2FastElementValue = static_cast<int8_t>( 4947 (FAST_ELEMENTS + 1) << Map::kElementsKindShift) - 1; 4948 static const int8_t kMaximumBitField2FastSmiOnlyElementValue = 4949 static_cast<int8_t>((FAST_SMI_ONLY_ELEMENTS + 1) << 4950 Map::kElementsKindShift) - 1; 4951 4952 // Bit positions for bit field 3 4953 static const int kIsShared = 0; 4954 4955 // Layout of the default cache. It holds alternating name and code objects. 4956 static const int kCodeCacheEntrySize = 2; 4957 static const int kCodeCacheEntryNameOffset = 0; 4958 static const int kCodeCacheEntryCodeOffset = 1; 4959 4960 typedef FixedBodyDescriptor<kPointerFieldsBeginOffset, 4961 kPointerFieldsEndOffset, 4962 kSize> BodyDescriptor; 4963 4964 private: 4965 String* elements_transition_sentinel_name(); 4966 DISALLOW_IMPLICIT_CONSTRUCTORS(Map); 4967 }; 4968 4969 4970 // An abstract superclass, a marker class really, for simple structure classes. 4971 // It doesn't carry much functionality but allows struct classes to be 4972 // identified in the type system. 4973 class Struct: public HeapObject { 4974 public: 4975 inline void InitializeBody(int object_size); 4976 static inline Struct* cast(Object* that); 4977 }; 4978 4979 4980 // Script describes a script which has been added to the VM. 4981 class Script: public Struct { 4982 public: 4983 // Script types. 4984 enum Type { 4985 TYPE_NATIVE = 0, 4986 TYPE_EXTENSION = 1, 4987 TYPE_NORMAL = 2 4988 }; 4989 4990 // Script compilation types. 4991 enum CompilationType { 4992 COMPILATION_TYPE_HOST = 0, 4993 COMPILATION_TYPE_EVAL = 1 4994 }; 4995 4996 // Script compilation state. 4997 enum CompilationState { 4998 COMPILATION_STATE_INITIAL = 0, 4999 COMPILATION_STATE_COMPILED = 1 5000 }; 5001 5002 // [source]: the script source. 5003 DECL_ACCESSORS(source, Object) 5004 5005 // [name]: the script name. 5006 DECL_ACCESSORS(name, Object) 5007 5008 // [id]: the script id. 5009 DECL_ACCESSORS(id, Object) 5010 5011 // [line_offset]: script line offset in resource from where it was extracted. 5012 DECL_ACCESSORS(line_offset, Smi) 5013 5014 // [column_offset]: script column offset in resource from where it was 5015 // extracted. 5016 DECL_ACCESSORS(column_offset, Smi) 5017 5018 // [data]: additional data associated with this script. 5019 DECL_ACCESSORS(data, Object) 5020 5021 // [context_data]: context data for the context this script was compiled in. 5022 DECL_ACCESSORS(context_data, Object) 5023 5024 // [wrapper]: the wrapper cache. 5025 DECL_ACCESSORS(wrapper, Foreign) 5026 5027 // [type]: the script type. 5028 DECL_ACCESSORS(type, Smi) 5029 5030 // [compilation]: how the the script was compiled. 5031 DECL_ACCESSORS(compilation_type, Smi) 5032 5033 // [is_compiled]: determines whether the script has already been compiled. 5034 DECL_ACCESSORS(compilation_state, Smi) 5035 5036 // [line_ends]: FixedArray of line ends positions. 5037 DECL_ACCESSORS(line_ends, Object) 5038 5039 // [eval_from_shared]: for eval scripts the shared funcion info for the 5040 // function from which eval was called. 5041 DECL_ACCESSORS(eval_from_shared, Object) 5042 5043 // [eval_from_instructions_offset]: the instruction offset in the code for the 5044 // function from which eval was called where eval was called. 5045 DECL_ACCESSORS(eval_from_instructions_offset, Smi) 5046 5047 static inline Script* cast(Object* obj); 5048 5049 // If script source is an external string, check that the underlying 5050 // resource is accessible. Otherwise, always return true. 5051 inline bool HasValidSource(); 5052 5053 #ifdef OBJECT_PRINT ScriptPrint()5054 inline void ScriptPrint() { 5055 ScriptPrint(stdout); 5056 } 5057 void ScriptPrint(FILE* out); 5058 #endif 5059 #ifdef DEBUG 5060 void ScriptVerify(); 5061 #endif 5062 5063 static const int kSourceOffset = HeapObject::kHeaderSize; 5064 static const int kNameOffset = kSourceOffset + kPointerSize; 5065 static const int kLineOffsetOffset = kNameOffset + kPointerSize; 5066 static const int kColumnOffsetOffset = kLineOffsetOffset + kPointerSize; 5067 static const int kDataOffset = kColumnOffsetOffset + kPointerSize; 5068 static const int kContextOffset = kDataOffset + kPointerSize; 5069 static const int kWrapperOffset = kContextOffset + kPointerSize; 5070 static const int kTypeOffset = kWrapperOffset + kPointerSize; 5071 static const int kCompilationTypeOffset = kTypeOffset + kPointerSize; 5072 static const int kCompilationStateOffset = 5073 kCompilationTypeOffset + kPointerSize; 5074 static const int kLineEndsOffset = kCompilationStateOffset + kPointerSize; 5075 static const int kIdOffset = kLineEndsOffset + kPointerSize; 5076 static const int kEvalFromSharedOffset = kIdOffset + kPointerSize; 5077 static const int kEvalFrominstructionsOffsetOffset = 5078 kEvalFromSharedOffset + kPointerSize; 5079 static const int kSize = kEvalFrominstructionsOffsetOffset + kPointerSize; 5080 5081 private: 5082 DISALLOW_IMPLICIT_CONSTRUCTORS(Script); 5083 }; 5084 5085 5086 // List of builtin functions we want to identify to improve code 5087 // generation. 5088 // 5089 // Each entry has a name of a global object property holding an object 5090 // optionally followed by ".prototype", a name of a builtin function 5091 // on the object (the one the id is set for), and a label. 5092 // 5093 // Installation of ids for the selected builtin functions is handled 5094 // by the bootstrapper. 5095 // 5096 // NOTE: Order is important: math functions should be at the end of 5097 // the list and MathFloor should be the first math function. 5098 #define FUNCTIONS_WITH_ID_LIST(V) \ 5099 V(Array.prototype, push, ArrayPush) \ 5100 V(Array.prototype, pop, ArrayPop) \ 5101 V(Function.prototype, apply, FunctionApply) \ 5102 V(String.prototype, charCodeAt, StringCharCodeAt) \ 5103 V(String.prototype, charAt, StringCharAt) \ 5104 V(String, fromCharCode, StringFromCharCode) \ 5105 V(Math, floor, MathFloor) \ 5106 V(Math, round, MathRound) \ 5107 V(Math, ceil, MathCeil) \ 5108 V(Math, abs, MathAbs) \ 5109 V(Math, log, MathLog) \ 5110 V(Math, sin, MathSin) \ 5111 V(Math, cos, MathCos) \ 5112 V(Math, tan, MathTan) \ 5113 V(Math, asin, MathASin) \ 5114 V(Math, acos, MathACos) \ 5115 V(Math, atan, MathATan) \ 5116 V(Math, exp, MathExp) \ 5117 V(Math, sqrt, MathSqrt) \ 5118 V(Math, pow, MathPow) \ 5119 V(Math, random, MathRandom) \ 5120 V(Math, max, MathMax) \ 5121 V(Math, min, MathMin) 5122 5123 5124 enum BuiltinFunctionId { 5125 #define DECLARE_FUNCTION_ID(ignored1, ignore2, name) \ 5126 k##name, 5127 FUNCTIONS_WITH_ID_LIST(DECLARE_FUNCTION_ID) 5128 #undef DECLARE_FUNCTION_ID 5129 // Fake id for a special case of Math.pow. Note, it continues the 5130 // list of math functions. 5131 kMathPowHalf, 5132 kFirstMathFunctionId = kMathFloor 5133 }; 5134 5135 5136 // SharedFunctionInfo describes the JSFunction information that can be 5137 // shared by multiple instances of the function. 5138 class SharedFunctionInfo: public HeapObject { 5139 public: 5140 // [name]: Function name. 5141 DECL_ACCESSORS(name, Object) 5142 5143 // [code]: Function code. 5144 DECL_ACCESSORS(code, Code) 5145 5146 // [scope_info]: Scope info. 5147 DECL_ACCESSORS(scope_info, ScopeInfo) 5148 5149 // [construct stub]: Code stub for constructing instances of this function. 5150 DECL_ACCESSORS(construct_stub, Code) 5151 5152 inline Code* unchecked_code(); 5153 5154 // Returns if this function has been compiled to native code yet. 5155 inline bool is_compiled(); 5156 5157 // [length]: The function length - usually the number of declared parameters. 5158 // Use up to 2^30 parameters. 5159 inline int length(); 5160 inline void set_length(int value); 5161 5162 // [formal parameter count]: The declared number of parameters. 5163 inline int formal_parameter_count(); 5164 inline void set_formal_parameter_count(int value); 5165 5166 // Set the formal parameter count so the function code will be 5167 // called without using argument adaptor frames. 5168 inline void DontAdaptArguments(); 5169 5170 // [expected_nof_properties]: Expected number of properties for the function. 5171 inline int expected_nof_properties(); 5172 inline void set_expected_nof_properties(int value); 5173 5174 // Inobject slack tracking is the way to reclaim unused inobject space. 5175 // 5176 // The instance size is initially determined by adding some slack to 5177 // expected_nof_properties (to allow for a few extra properties added 5178 // after the constructor). There is no guarantee that the extra space 5179 // will not be wasted. 5180 // 5181 // Here is the algorithm to reclaim the unused inobject space: 5182 // - Detect the first constructor call for this SharedFunctionInfo. 5183 // When it happens enter the "in progress" state: remember the 5184 // constructor's initial_map and install a special construct stub that 5185 // counts constructor calls. 5186 // - While the tracking is in progress create objects filled with 5187 // one_pointer_filler_map instead of undefined_value. This way they can be 5188 // resized quickly and safely. 5189 // - Once enough (kGenerousAllocationCount) objects have been created 5190 // compute the 'slack' (traverse the map transition tree starting from the 5191 // initial_map and find the lowest value of unused_property_fields). 5192 // - Traverse the transition tree again and decrease the instance size 5193 // of every map. Existing objects will resize automatically (they are 5194 // filled with one_pointer_filler_map). All further allocations will 5195 // use the adjusted instance size. 5196 // - Decrease expected_nof_properties so that an allocations made from 5197 // another context will use the adjusted instance size too. 5198 // - Exit "in progress" state by clearing the reference to the initial_map 5199 // and setting the regular construct stub (generic or inline). 5200 // 5201 // The above is the main event sequence. Some special cases are possible 5202 // while the tracking is in progress: 5203 // 5204 // - GC occurs. 5205 // Check if the initial_map is referenced by any live objects (except this 5206 // SharedFunctionInfo). If it is, continue tracking as usual. 5207 // If it is not, clear the reference and reset the tracking state. The 5208 // tracking will be initiated again on the next constructor call. 5209 // 5210 // - The constructor is called from another context. 5211 // Immediately complete the tracking, perform all the necessary changes 5212 // to maps. This is necessary because there is no efficient way to track 5213 // multiple initial_maps. 5214 // Proceed to create an object in the current context (with the adjusted 5215 // size). 5216 // 5217 // - A different constructor function sharing the same SharedFunctionInfo is 5218 // called in the same context. This could be another closure in the same 5219 // context, or the first function could have been disposed. 5220 // This is handled the same way as the previous case. 5221 // 5222 // Important: inobject slack tracking is not attempted during the snapshot 5223 // creation. 5224 5225 static const int kGenerousAllocationCount = 8; 5226 5227 // [construction_count]: Counter for constructor calls made during 5228 // the tracking phase. 5229 inline int construction_count(); 5230 inline void set_construction_count(int value); 5231 5232 // [initial_map]: initial map of the first function called as a constructor. 5233 // Saved for the duration of the tracking phase. 5234 // This is a weak link (GC resets it to undefined_value if no other live 5235 // object reference this map). 5236 DECL_ACCESSORS(initial_map, Object) 5237 5238 // True if the initial_map is not undefined and the countdown stub is 5239 // installed. 5240 inline bool IsInobjectSlackTrackingInProgress(); 5241 5242 // Starts the tracking. 5243 // Stores the initial map and installs the countdown stub. 5244 // IsInobjectSlackTrackingInProgress is normally true after this call, 5245 // except when tracking have not been started (e.g. the map has no unused 5246 // properties or the snapshot is being built). 5247 void StartInobjectSlackTracking(Map* map); 5248 5249 // Completes the tracking. 5250 // IsInobjectSlackTrackingInProgress is false after this call. 5251 void CompleteInobjectSlackTracking(); 5252 5253 // Clears the initial_map before the GC marking phase to ensure the reference 5254 // is weak. IsInobjectSlackTrackingInProgress is false after this call. 5255 void DetachInitialMap(); 5256 5257 // Restores the link to the initial map after the GC marking phase. 5258 // IsInobjectSlackTrackingInProgress is true after this call. 5259 void AttachInitialMap(Map* map); 5260 5261 // False if there are definitely no live objects created from this function. 5262 // True if live objects _may_ exist (existence not guaranteed). 5263 // May go back from true to false after GC. 5264 DECL_BOOLEAN_ACCESSORS(live_objects_may_exist) 5265 5266 // [instance class name]: class name for instances. 5267 DECL_ACCESSORS(instance_class_name, Object) 5268 5269 // [function data]: This field holds some additional data for function. 5270 // Currently it either has FunctionTemplateInfo to make benefit the API 5271 // or Smi identifying a builtin function. 5272 // In the long run we don't want all functions to have this field but 5273 // we can fix that when we have a better model for storing hidden data 5274 // on objects. 5275 DECL_ACCESSORS(function_data, Object) 5276 5277 inline bool IsApiFunction(); 5278 inline FunctionTemplateInfo* get_api_func_data(); 5279 inline bool HasBuiltinFunctionId(); 5280 inline BuiltinFunctionId builtin_function_id(); 5281 5282 // [script info]: Script from which the function originates. 5283 DECL_ACCESSORS(script, Object) 5284 5285 // [num_literals]: Number of literals used by this function. 5286 inline int num_literals(); 5287 inline void set_num_literals(int value); 5288 5289 // [start_position_and_type]: Field used to store both the source code 5290 // position, whether or not the function is a function expression, 5291 // and whether or not the function is a toplevel function. The two 5292 // least significants bit indicates whether the function is an 5293 // expression and the rest contains the source code position. 5294 inline int start_position_and_type(); 5295 inline void set_start_position_and_type(int value); 5296 5297 // [debug info]: Debug information. 5298 DECL_ACCESSORS(debug_info, Object) 5299 5300 // [inferred name]: Name inferred from variable or property 5301 // assignment of this function. Used to facilitate debugging and 5302 // profiling of JavaScript code written in OO style, where almost 5303 // all functions are anonymous but are assigned to object 5304 // properties. 5305 DECL_ACCESSORS(inferred_name, String) 5306 5307 // The function's name if it is non-empty, otherwise the inferred name. 5308 String* DebugName(); 5309 5310 // Position of the 'function' token in the script source. 5311 inline int function_token_position(); 5312 inline void set_function_token_position(int function_token_position); 5313 5314 // Position of this function in the script source. 5315 inline int start_position(); 5316 inline void set_start_position(int start_position); 5317 5318 // End position of this function in the script source. 5319 inline int end_position(); 5320 inline void set_end_position(int end_position); 5321 5322 // Is this function a function expression in the source code. 5323 DECL_BOOLEAN_ACCESSORS(is_expression) 5324 5325 // Is this function a top-level function (scripts, evals). 5326 DECL_BOOLEAN_ACCESSORS(is_toplevel) 5327 5328 // Bit field containing various information collected by the compiler to 5329 // drive optimization. 5330 inline int compiler_hints(); 5331 inline void set_compiler_hints(int value); 5332 5333 inline int ast_node_count(); 5334 inline void set_ast_node_count(int count); 5335 5336 // A counter used to determine when to stress the deoptimizer with a 5337 // deopt. 5338 inline int deopt_counter(); 5339 inline void set_deopt_counter(int counter); 5340 5341 // Inline cache age is used to infer whether the function survived a context 5342 // disposal or not. In the former case we reset the opt_count. 5343 inline int ic_age(); 5344 inline void set_ic_age(int age); 5345 5346 // Add information on assignments of the form this.x = ...; 5347 void SetThisPropertyAssignmentsInfo( 5348 bool has_only_simple_this_property_assignments, 5349 FixedArray* this_property_assignments); 5350 5351 // Clear information on assignments of the form this.x = ...; 5352 void ClearThisPropertyAssignmentsInfo(); 5353 5354 // Indicate that this function only consists of assignments of the form 5355 // this.x = y; where y is either a constant or refers to an argument. 5356 inline bool has_only_simple_this_property_assignments(); 5357 5358 // Indicates if this function can be lazy compiled. 5359 // This is used to determine if we can safely flush code from a function 5360 // when doing GC if we expect that the function will no longer be used. 5361 DECL_BOOLEAN_ACCESSORS(allows_lazy_compilation) 5362 5363 // Indicates how many full GCs this function has survived with assigned 5364 // code object. Used to determine when it is relatively safe to flush 5365 // this code object and replace it with lazy compilation stub. 5366 // Age is reset when GC notices that the code object is referenced 5367 // from the stack or compilation cache. 5368 inline int code_age(); 5369 inline void set_code_age(int age); 5370 5371 // Indicates whether optimizations have been disabled for this 5372 // shared function info. If a function is repeatedly optimized or if 5373 // we cannot optimize the function we disable optimization to avoid 5374 // spending time attempting to optimize it again. 5375 DECL_BOOLEAN_ACCESSORS(optimization_disabled) 5376 5377 // Indicates the language mode of the function's code as defined by the 5378 // current harmony drafts for the next ES language standard. Possible 5379 // values are: 5380 // 1. CLASSIC_MODE - Unrestricted syntax and semantics, same as in ES5. 5381 // 2. STRICT_MODE - Restricted syntax and semantics, same as in ES5. 5382 // 3. EXTENDED_MODE - Only available under the harmony flag, not part of ES5. 5383 inline LanguageMode language_mode(); 5384 inline void set_language_mode(LanguageMode language_mode); 5385 5386 // Indicates whether the language mode of this function is CLASSIC_MODE. 5387 inline bool is_classic_mode(); 5388 5389 // Indicates whether the language mode of this function is EXTENDED_MODE. 5390 inline bool is_extended_mode(); 5391 5392 // False if the function definitely does not allocate an arguments object. 5393 DECL_BOOLEAN_ACCESSORS(uses_arguments) 5394 5395 // True if the function has any duplicated parameter names. 5396 DECL_BOOLEAN_ACCESSORS(has_duplicate_parameters) 5397 5398 // Indicates whether the function is a native function. 5399 // These needs special treatment in .call and .apply since 5400 // null passed as the receiver should not be translated to the 5401 // global object. 5402 DECL_BOOLEAN_ACCESSORS(native) 5403 5404 // Indicates that the function was created by the Function function. 5405 // Though it's anonymous, toString should treat it as if it had the name 5406 // "anonymous". We don't set the name itself so that the system does not 5407 // see a binding for it. 5408 DECL_BOOLEAN_ACCESSORS(name_should_print_as_anonymous) 5409 5410 // Indicates whether the function is a bound function created using 5411 // the bind function. 5412 DECL_BOOLEAN_ACCESSORS(bound) 5413 5414 // Indicates that the function is anonymous (the name field can be set 5415 // through the API, which does not change this flag). 5416 DECL_BOOLEAN_ACCESSORS(is_anonymous) 5417 5418 // Is this a function or top-level/eval code. 5419 DECL_BOOLEAN_ACCESSORS(is_function) 5420 5421 // Indicates that the function cannot be optimized. 5422 DECL_BOOLEAN_ACCESSORS(dont_optimize) 5423 5424 // Indicates that the function cannot be inlined. 5425 DECL_BOOLEAN_ACCESSORS(dont_inline) 5426 5427 // Indicates whether or not the code in the shared function support 5428 // deoptimization. 5429 inline bool has_deoptimization_support(); 5430 5431 // Enable deoptimization support through recompiled code. 5432 void EnableDeoptimizationSupport(Code* recompiled); 5433 5434 // Disable (further) attempted optimization of all functions sharing this 5435 // shared function info. 5436 void DisableOptimization(); 5437 5438 // Lookup the bailout ID and ASSERT that it exists in the non-optimized 5439 // code, returns whether it asserted (i.e., always true if assertions are 5440 // disabled). 5441 bool VerifyBailoutId(int id); 5442 5443 // Check whether a inlined constructor can be generated with the given 5444 // prototype. 5445 bool CanGenerateInlineConstructor(Object* prototype); 5446 5447 // Prevents further attempts to generate inline constructors. 5448 // To be called if generation failed for any reason. 5449 void ForbidInlineConstructor(); 5450 5451 // For functions which only contains this property assignments this provides 5452 // access to the names for the properties assigned. 5453 DECL_ACCESSORS(this_property_assignments, Object) 5454 inline int this_property_assignments_count(); 5455 inline void set_this_property_assignments_count(int value); 5456 String* GetThisPropertyAssignmentName(int index); 5457 bool IsThisPropertyAssignmentArgument(int index); 5458 int GetThisPropertyAssignmentArgument(int index); 5459 Object* GetThisPropertyAssignmentConstant(int index); 5460 5461 // [source code]: Source code for the function. 5462 bool HasSourceCode(); 5463 Handle<Object> GetSourceCode(); 5464 5465 inline int opt_count(); 5466 inline void set_opt_count(int opt_count); 5467 5468 // Source size of this function. 5469 int SourceSize(); 5470 5471 // Calculate the instance size. 5472 int CalculateInstanceSize(); 5473 5474 // Calculate the number of in-object properties. 5475 int CalculateInObjectProperties(); 5476 5477 // Dispatched behavior. 5478 // Set max_length to -1 for unlimited length. 5479 void SourceCodePrint(StringStream* accumulator, int max_length); 5480 #ifdef OBJECT_PRINT SharedFunctionInfoPrint()5481 inline void SharedFunctionInfoPrint() { 5482 SharedFunctionInfoPrint(stdout); 5483 } 5484 void SharedFunctionInfoPrint(FILE* out); 5485 #endif 5486 #ifdef DEBUG 5487 void SharedFunctionInfoVerify(); 5488 #endif 5489 5490 void ResetForNewContext(int new_ic_age); 5491 5492 // Helpers to compile the shared code. Returns true on success, false on 5493 // failure (e.g., stack overflow during compilation). 5494 static bool EnsureCompiled(Handle<SharedFunctionInfo> shared, 5495 ClearExceptionFlag flag); 5496 static bool CompileLazy(Handle<SharedFunctionInfo> shared, 5497 ClearExceptionFlag flag); 5498 5499 void SharedFunctionInfoIterateBody(ObjectVisitor* v); 5500 5501 // Casting. 5502 static inline SharedFunctionInfo* cast(Object* obj); 5503 5504 // Constants. 5505 static const int kDontAdaptArgumentsSentinel = -1; 5506 5507 // Layout description. 5508 // Pointer fields. 5509 static const int kNameOffset = HeapObject::kHeaderSize; 5510 static const int kCodeOffset = kNameOffset + kPointerSize; 5511 static const int kScopeInfoOffset = kCodeOffset + kPointerSize; 5512 static const int kConstructStubOffset = kScopeInfoOffset + kPointerSize; 5513 static const int kInstanceClassNameOffset = 5514 kConstructStubOffset + kPointerSize; 5515 static const int kFunctionDataOffset = 5516 kInstanceClassNameOffset + kPointerSize; 5517 static const int kScriptOffset = kFunctionDataOffset + kPointerSize; 5518 static const int kDebugInfoOffset = kScriptOffset + kPointerSize; 5519 static const int kInferredNameOffset = kDebugInfoOffset + kPointerSize; 5520 static const int kInitialMapOffset = 5521 kInferredNameOffset + kPointerSize; 5522 static const int kThisPropertyAssignmentsOffset = 5523 kInitialMapOffset + kPointerSize; 5524 // ic_age is a Smi field. It could be grouped with another Smi field into a 5525 // PSEUDO_SMI_ACCESSORS pair (on x64), if one becomes available. 5526 static const int kICAgeOffset = kThisPropertyAssignmentsOffset + kPointerSize; 5527 #if V8_HOST_ARCH_32_BIT 5528 // Smi fields. 5529 static const int kLengthOffset = 5530 kICAgeOffset + kPointerSize; 5531 static const int kFormalParameterCountOffset = kLengthOffset + kPointerSize; 5532 static const int kExpectedNofPropertiesOffset = 5533 kFormalParameterCountOffset + kPointerSize; 5534 static const int kNumLiteralsOffset = 5535 kExpectedNofPropertiesOffset + kPointerSize; 5536 static const int kStartPositionAndTypeOffset = 5537 kNumLiteralsOffset + kPointerSize; 5538 static const int kEndPositionOffset = 5539 kStartPositionAndTypeOffset + kPointerSize; 5540 static const int kFunctionTokenPositionOffset = 5541 kEndPositionOffset + kPointerSize; 5542 static const int kCompilerHintsOffset = 5543 kFunctionTokenPositionOffset + kPointerSize; 5544 static const int kThisPropertyAssignmentsCountOffset = 5545 kCompilerHintsOffset + kPointerSize; 5546 static const int kOptCountOffset = 5547 kThisPropertyAssignmentsCountOffset + kPointerSize; 5548 static const int kAstNodeCountOffset = kOptCountOffset + kPointerSize; 5549 static const int kDeoptCounterOffset = kAstNodeCountOffset + kPointerSize; 5550 5551 5552 // Total size. 5553 static const int kSize = kDeoptCounterOffset + kPointerSize; 5554 #else 5555 // The only reason to use smi fields instead of int fields 5556 // is to allow iteration without maps decoding during 5557 // garbage collections. 5558 // To avoid wasting space on 64-bit architectures we use 5559 // the following trick: we group integer fields into pairs 5560 // First integer in each pair is shifted left by 1. 5561 // By doing this we guarantee that LSB of each kPointerSize aligned 5562 // word is not set and thus this word cannot be treated as pointer 5563 // to HeapObject during old space traversal. 5564 static const int kLengthOffset = 5565 kICAgeOffset + kPointerSize; 5566 static const int kFormalParameterCountOffset = 5567 kLengthOffset + kIntSize; 5568 5569 static const int kExpectedNofPropertiesOffset = 5570 kFormalParameterCountOffset + kIntSize; 5571 static const int kNumLiteralsOffset = 5572 kExpectedNofPropertiesOffset + kIntSize; 5573 5574 static const int kEndPositionOffset = 5575 kNumLiteralsOffset + kIntSize; 5576 static const int kStartPositionAndTypeOffset = 5577 kEndPositionOffset + kIntSize; 5578 5579 static const int kFunctionTokenPositionOffset = 5580 kStartPositionAndTypeOffset + kIntSize; 5581 static const int kCompilerHintsOffset = 5582 kFunctionTokenPositionOffset + kIntSize; 5583 5584 static const int kThisPropertyAssignmentsCountOffset = 5585 kCompilerHintsOffset + kIntSize; 5586 static const int kOptCountOffset = 5587 kThisPropertyAssignmentsCountOffset + kIntSize; 5588 5589 static const int kAstNodeCountOffset = kOptCountOffset + kIntSize; 5590 static const int kDeoptCounterOffset = kAstNodeCountOffset + kIntSize; 5591 5592 // Total size. 5593 static const int kSize = kDeoptCounterOffset + kIntSize; 5594 5595 #endif 5596 5597 // The construction counter for inobject slack tracking is stored in the 5598 // most significant byte of compiler_hints which is otherwise unused. 5599 // Its offset depends on the endian-ness of the architecture. 5600 #if __BYTE_ORDER == __LITTLE_ENDIAN 5601 static const int kConstructionCountOffset = kCompilerHintsOffset + 3; 5602 #elif __BYTE_ORDER == __BIG_ENDIAN 5603 static const int kConstructionCountOffset = kCompilerHintsOffset + 0; 5604 #else 5605 #error Unknown byte ordering 5606 #endif 5607 5608 static const int kAlignedSize = POINTER_SIZE_ALIGN(kSize); 5609 5610 typedef FixedBodyDescriptor<kNameOffset, 5611 kThisPropertyAssignmentsOffset + kPointerSize, 5612 kSize> BodyDescriptor; 5613 5614 // Bit positions in start_position_and_type. 5615 // The source code start position is in the 30 most significant bits of 5616 // the start_position_and_type field. 5617 static const int kIsExpressionBit = 0; 5618 static const int kIsTopLevelBit = 1; 5619 static const int kStartPositionShift = 2; 5620 static const int kStartPositionMask = ~((1 << kStartPositionShift) - 1); 5621 5622 // Bit positions in compiler_hints. 5623 static const int kCodeAgeSize = 3; 5624 static const int kCodeAgeMask = (1 << kCodeAgeSize) - 1; 5625 5626 enum CompilerHints { 5627 kHasOnlySimpleThisPropertyAssignments, 5628 kAllowLazyCompilation, 5629 kLiveObjectsMayExist, 5630 kCodeAgeShift, 5631 kOptimizationDisabled = kCodeAgeShift + kCodeAgeSize, 5632 kStrictModeFunction, 5633 kExtendedModeFunction, 5634 kUsesArguments, 5635 kHasDuplicateParameters, 5636 kNative, 5637 kBoundFunction, 5638 kIsAnonymous, 5639 kNameShouldPrintAsAnonymous, 5640 kIsFunction, 5641 kDontOptimize, 5642 kDontInline, 5643 kCompilerHintsCount // Pseudo entry 5644 }; 5645 5646 private: 5647 #if V8_HOST_ARCH_32_BIT 5648 // On 32 bit platforms, compiler hints is a smi. 5649 static const int kCompilerHintsSmiTagSize = kSmiTagSize; 5650 static const int kCompilerHintsSize = kPointerSize; 5651 #else 5652 // On 64 bit platforms, compiler hints is not a smi, see comment above. 5653 static const int kCompilerHintsSmiTagSize = 0; 5654 static const int kCompilerHintsSize = kIntSize; 5655 #endif 5656 5657 STATIC_ASSERT(SharedFunctionInfo::kCompilerHintsCount <= 5658 SharedFunctionInfo::kCompilerHintsSize * kBitsPerByte); 5659 5660 public: 5661 // Constants for optimizing codegen for strict mode function and 5662 // native tests. 5663 // Allows to use byte-width instructions. 5664 static const int kStrictModeBitWithinByte = 5665 (kStrictModeFunction + kCompilerHintsSmiTagSize) % kBitsPerByte; 5666 5667 static const int kExtendedModeBitWithinByte = 5668 (kExtendedModeFunction + kCompilerHintsSmiTagSize) % kBitsPerByte; 5669 5670 static const int kNativeBitWithinByte = 5671 (kNative + kCompilerHintsSmiTagSize) % kBitsPerByte; 5672 5673 #if __BYTE_ORDER == __LITTLE_ENDIAN 5674 static const int kStrictModeByteOffset = kCompilerHintsOffset + 5675 (kStrictModeFunction + kCompilerHintsSmiTagSize) / kBitsPerByte; 5676 static const int kExtendedModeByteOffset = kCompilerHintsOffset + 5677 (kExtendedModeFunction + kCompilerHintsSmiTagSize) / kBitsPerByte; 5678 static const int kNativeByteOffset = kCompilerHintsOffset + 5679 (kNative + kCompilerHintsSmiTagSize) / kBitsPerByte; 5680 #elif __BYTE_ORDER == __BIG_ENDIAN 5681 static const int kStrictModeByteOffset = kCompilerHintsOffset + 5682 (kCompilerHintsSize - 1) - 5683 ((kStrictModeFunction + kCompilerHintsSmiTagSize) / kBitsPerByte); 5684 static const int kExtendedModeByteOffset = kCompilerHintsOffset + 5685 (kCompilerHintsSize - 1) - 5686 ((kExtendedModeFunction + kCompilerHintsSmiTagSize) / kBitsPerByte); 5687 static const int kNativeByteOffset = kCompilerHintsOffset + 5688 (kCompilerHintsSize - 1) - 5689 ((kNative + kCompilerHintsSmiTagSize) / kBitsPerByte); 5690 #else 5691 #error Unknown byte ordering 5692 #endif 5693 5694 private: 5695 DISALLOW_IMPLICIT_CONSTRUCTORS(SharedFunctionInfo); 5696 }; 5697 5698 5699 // JSFunction describes JavaScript functions. 5700 class JSFunction: public JSObject { 5701 public: 5702 // [prototype_or_initial_map]: 5703 DECL_ACCESSORS(prototype_or_initial_map, Object) 5704 5705 // [shared]: The information about the function that 5706 // can be shared by instances. 5707 DECL_ACCESSORS(shared, SharedFunctionInfo) 5708 5709 inline SharedFunctionInfo* unchecked_shared(); 5710 5711 // [context]: The context for this function. 5712 inline Context* context(); 5713 inline Object* unchecked_context(); 5714 inline void set_context(Object* context); 5715 5716 // [code]: The generated code object for this function. Executed 5717 // when the function is invoked, e.g. foo() or new foo(). See 5718 // [[Call]] and [[Construct]] description in ECMA-262, section 5719 // 8.6.2, page 27. 5720 inline Code* code(); 5721 inline void set_code(Code* code); 5722 inline void ReplaceCode(Code* code); 5723 5724 inline Code* unchecked_code(); 5725 5726 // Tells whether this function is builtin. 5727 inline bool IsBuiltin(); 5728 5729 // Tells whether or not the function needs arguments adaption. 5730 inline bool NeedsArgumentsAdaption(); 5731 5732 // Tells whether or not this function has been optimized. 5733 inline bool IsOptimized(); 5734 5735 // Tells whether or not this function can be optimized. 5736 inline bool IsOptimizable(); 5737 5738 // Mark this function for lazy recompilation. The function will be 5739 // recompiled the next time it is executed. 5740 void MarkForLazyRecompilation(); 5741 5742 // Helpers to compile this function. Returns true on success, false on 5743 // failure (e.g., stack overflow during compilation). 5744 static bool CompileLazy(Handle<JSFunction> function, 5745 ClearExceptionFlag flag); 5746 static bool CompileOptimized(Handle<JSFunction> function, 5747 int osr_ast_id, 5748 ClearExceptionFlag flag); 5749 5750 // Tells whether or not the function is already marked for lazy 5751 // recompilation. 5752 inline bool IsMarkedForLazyRecompilation(); 5753 5754 // Check whether or not this function is inlineable. 5755 bool IsInlineable(); 5756 5757 // [literals_or_bindings]: Fixed array holding either 5758 // the materialized literals or the bindings of a bound function. 5759 // 5760 // If the function contains object, regexp or array literals, the 5761 // literals array prefix contains the object, regexp, and array 5762 // function to be used when creating these literals. This is 5763 // necessary so that we do not dynamically lookup the object, regexp 5764 // or array functions. Performing a dynamic lookup, we might end up 5765 // using the functions from a new context that we should not have 5766 // access to. 5767 // 5768 // On bound functions, the array is a (copy-on-write) fixed-array containing 5769 // the function that was bound, bound this-value and any bound 5770 // arguments. Bound functions never contain literals. 5771 DECL_ACCESSORS(literals_or_bindings, FixedArray) 5772 5773 inline FixedArray* literals(); 5774 inline void set_literals(FixedArray* literals); 5775 5776 inline FixedArray* function_bindings(); 5777 inline void set_function_bindings(FixedArray* bindings); 5778 5779 // The initial map for an object created by this constructor. 5780 inline Map* initial_map(); 5781 inline void set_initial_map(Map* value); 5782 MUST_USE_RESULT inline MaybeObject* set_initial_map_and_cache_transitions( 5783 Map* value); 5784 inline bool has_initial_map(); 5785 5786 // Get and set the prototype property on a JSFunction. If the 5787 // function has an initial map the prototype is set on the initial 5788 // map. Otherwise, the prototype is put in the initial map field 5789 // until an initial map is needed. 5790 inline bool has_prototype(); 5791 inline bool has_instance_prototype(); 5792 inline Object* prototype(); 5793 inline Object* instance_prototype(); 5794 MUST_USE_RESULT MaybeObject* SetInstancePrototype(Object* value); 5795 MUST_USE_RESULT MaybeObject* SetPrototype(Object* value); 5796 5797 // After prototype is removed, it will not be created when accessed, and 5798 // [[Construct]] from this function will not be allowed. 5799 Object* RemovePrototype(); 5800 inline bool should_have_prototype(); 5801 5802 // Accessor for this function's initial map's [[class]] 5803 // property. This is primarily used by ECMA native functions. This 5804 // method sets the class_name field of this function's initial map 5805 // to a given value. It creates an initial map if this function does 5806 // not have one. Note that this method does not copy the initial map 5807 // if it has one already, but simply replaces it with the new value. 5808 // Instances created afterwards will have a map whose [[class]] is 5809 // set to 'value', but there is no guarantees on instances created 5810 // before. 5811 Object* SetInstanceClassName(String* name); 5812 5813 // Returns if this function has been compiled to native code yet. 5814 inline bool is_compiled(); 5815 5816 // [next_function_link]: Field for linking functions. This list is treated as 5817 // a weak list by the GC. DECL_ACCESSORS(next_function_link,Object)5818 DECL_ACCESSORS(next_function_link, Object) 5819 5820 // Prints the name of the function using PrintF. 5821 inline void PrintName() { 5822 PrintName(stdout); 5823 } 5824 void PrintName(FILE* out); 5825 5826 // Casting. 5827 static inline JSFunction* cast(Object* obj); 5828 5829 // Iterates the objects, including code objects indirectly referenced 5830 // through pointers to the first instruction in the code object. 5831 void JSFunctionIterateBody(int object_size, ObjectVisitor* v); 5832 5833 // Dispatched behavior. 5834 #ifdef OBJECT_PRINT JSFunctionPrint()5835 inline void JSFunctionPrint() { 5836 JSFunctionPrint(stdout); 5837 } 5838 void JSFunctionPrint(FILE* out); 5839 #endif 5840 #ifdef DEBUG 5841 void JSFunctionVerify(); 5842 #endif 5843 5844 // Returns the number of allocated literals. 5845 inline int NumberOfLiterals(); 5846 5847 // Retrieve the global context from a function's literal array. 5848 static Context* GlobalContextFromLiterals(FixedArray* literals); 5849 5850 // Layout descriptors. The last property (from kNonWeakFieldsEndOffset to 5851 // kSize) is weak and has special handling during garbage collection. 5852 static const int kCodeEntryOffset = JSObject::kHeaderSize; 5853 static const int kPrototypeOrInitialMapOffset = 5854 kCodeEntryOffset + kPointerSize; 5855 static const int kSharedFunctionInfoOffset = 5856 kPrototypeOrInitialMapOffset + kPointerSize; 5857 static const int kContextOffset = kSharedFunctionInfoOffset + kPointerSize; 5858 static const int kLiteralsOffset = kContextOffset + kPointerSize; 5859 static const int kNonWeakFieldsEndOffset = kLiteralsOffset + kPointerSize; 5860 static const int kNextFunctionLinkOffset = kNonWeakFieldsEndOffset; 5861 static const int kSize = kNextFunctionLinkOffset + kPointerSize; 5862 5863 // Layout of the literals array. 5864 static const int kLiteralsPrefixSize = 1; 5865 static const int kLiteralGlobalContextIndex = 0; 5866 5867 // Layout of the bound-function binding array. 5868 static const int kBoundFunctionIndex = 0; 5869 static const int kBoundThisIndex = 1; 5870 static const int kBoundArgumentsStartIndex = 2; 5871 5872 private: 5873 DISALLOW_IMPLICIT_CONSTRUCTORS(JSFunction); 5874 }; 5875 5876 5877 // JSGlobalProxy's prototype must be a JSGlobalObject or null, 5878 // and the prototype is hidden. JSGlobalProxy always delegates 5879 // property accesses to its prototype if the prototype is not null. 5880 // 5881 // A JSGlobalProxy can be reinitialized which will preserve its identity. 5882 // 5883 // Accessing a JSGlobalProxy requires security check. 5884 5885 class JSGlobalProxy : public JSObject { 5886 public: 5887 // [context]: the owner global context of this global proxy object. 5888 // It is null value if this object is not used by any context. 5889 DECL_ACCESSORS(context, Object) 5890 5891 // Casting. 5892 static inline JSGlobalProxy* cast(Object* obj); 5893 5894 // Dispatched behavior. 5895 #ifdef OBJECT_PRINT JSGlobalProxyPrint()5896 inline void JSGlobalProxyPrint() { 5897 JSGlobalProxyPrint(stdout); 5898 } 5899 void JSGlobalProxyPrint(FILE* out); 5900 #endif 5901 #ifdef DEBUG 5902 void JSGlobalProxyVerify(); 5903 #endif 5904 5905 // Layout description. 5906 static const int kContextOffset = JSObject::kHeaderSize; 5907 static const int kSize = kContextOffset + kPointerSize; 5908 5909 private: 5910 DISALLOW_IMPLICIT_CONSTRUCTORS(JSGlobalProxy); 5911 }; 5912 5913 5914 // Forward declaration. 5915 class JSBuiltinsObject; 5916 5917 // Common super class for JavaScript global objects and the special 5918 // builtins global objects. 5919 class GlobalObject: public JSObject { 5920 public: 5921 // [builtins]: the object holding the runtime routines written in JS. 5922 DECL_ACCESSORS(builtins, JSBuiltinsObject) 5923 5924 // [global context]: the global context corresponding to this global object. 5925 DECL_ACCESSORS(global_context, Context) 5926 5927 // [global receiver]: the global receiver object of the context 5928 DECL_ACCESSORS(global_receiver, JSObject) 5929 5930 // Retrieve the property cell used to store a property. 5931 JSGlobalPropertyCell* GetPropertyCell(LookupResult* result); 5932 5933 // This is like GetProperty, but is used when you know the lookup won't fail 5934 // by throwing an exception. This is for the debug and builtins global 5935 // objects, where it is known which properties can be expected to be present 5936 // on the object. GetPropertyNoExceptionThrown(String * key)5937 Object* GetPropertyNoExceptionThrown(String* key) { 5938 Object* answer = GetProperty(key)->ToObjectUnchecked(); 5939 return answer; 5940 } 5941 5942 // Ensure that the global object has a cell for the given property name. 5943 static Handle<JSGlobalPropertyCell> EnsurePropertyCell( 5944 Handle<GlobalObject> global, 5945 Handle<String> name); 5946 // TODO(kmillikin): This function can be eliminated once the stub cache is 5947 // full handlified (and the static helper can be written directly). 5948 MUST_USE_RESULT MaybeObject* EnsurePropertyCell(String* name); 5949 5950 // Casting. 5951 static inline GlobalObject* cast(Object* obj); 5952 5953 // Layout description. 5954 static const int kBuiltinsOffset = JSObject::kHeaderSize; 5955 static const int kGlobalContextOffset = kBuiltinsOffset + kPointerSize; 5956 static const int kGlobalReceiverOffset = kGlobalContextOffset + kPointerSize; 5957 static const int kHeaderSize = kGlobalReceiverOffset + kPointerSize; 5958 5959 private: 5960 DISALLOW_IMPLICIT_CONSTRUCTORS(GlobalObject); 5961 }; 5962 5963 5964 // JavaScript global object. 5965 class JSGlobalObject: public GlobalObject { 5966 public: 5967 // Casting. 5968 static inline JSGlobalObject* cast(Object* obj); 5969 5970 // Dispatched behavior. 5971 #ifdef OBJECT_PRINT JSGlobalObjectPrint()5972 inline void JSGlobalObjectPrint() { 5973 JSGlobalObjectPrint(stdout); 5974 } 5975 void JSGlobalObjectPrint(FILE* out); 5976 #endif 5977 #ifdef DEBUG 5978 void JSGlobalObjectVerify(); 5979 #endif 5980 5981 // Layout description. 5982 static const int kSize = GlobalObject::kHeaderSize; 5983 5984 private: 5985 DISALLOW_IMPLICIT_CONSTRUCTORS(JSGlobalObject); 5986 }; 5987 5988 5989 // Builtins global object which holds the runtime routines written in 5990 // JavaScript. 5991 class JSBuiltinsObject: public GlobalObject { 5992 public: 5993 // Accessors for the runtime routines written in JavaScript. 5994 inline Object* javascript_builtin(Builtins::JavaScript id); 5995 inline void set_javascript_builtin(Builtins::JavaScript id, Object* value); 5996 5997 // Accessors for code of the runtime routines written in JavaScript. 5998 inline Code* javascript_builtin_code(Builtins::JavaScript id); 5999 inline void set_javascript_builtin_code(Builtins::JavaScript id, Code* value); 6000 6001 // Casting. 6002 static inline JSBuiltinsObject* cast(Object* obj); 6003 6004 // Dispatched behavior. 6005 #ifdef OBJECT_PRINT JSBuiltinsObjectPrint()6006 inline void JSBuiltinsObjectPrint() { 6007 JSBuiltinsObjectPrint(stdout); 6008 } 6009 void JSBuiltinsObjectPrint(FILE* out); 6010 #endif 6011 #ifdef DEBUG 6012 void JSBuiltinsObjectVerify(); 6013 #endif 6014 6015 // Layout description. The size of the builtins object includes 6016 // room for two pointers per runtime routine written in javascript 6017 // (function and code object). 6018 static const int kJSBuiltinsCount = Builtins::id_count; 6019 static const int kJSBuiltinsOffset = GlobalObject::kHeaderSize; 6020 static const int kJSBuiltinsCodeOffset = 6021 GlobalObject::kHeaderSize + (kJSBuiltinsCount * kPointerSize); 6022 static const int kSize = 6023 kJSBuiltinsCodeOffset + (kJSBuiltinsCount * kPointerSize); 6024 OffsetOfFunctionWithId(Builtins::JavaScript id)6025 static int OffsetOfFunctionWithId(Builtins::JavaScript id) { 6026 return kJSBuiltinsOffset + id * kPointerSize; 6027 } 6028 OffsetOfCodeWithId(Builtins::JavaScript id)6029 static int OffsetOfCodeWithId(Builtins::JavaScript id) { 6030 return kJSBuiltinsCodeOffset + id * kPointerSize; 6031 } 6032 6033 private: 6034 DISALLOW_IMPLICIT_CONSTRUCTORS(JSBuiltinsObject); 6035 }; 6036 6037 6038 // Representation for JS Wrapper objects, String, Number, Boolean, etc. 6039 class JSValue: public JSObject { 6040 public: 6041 // [value]: the object being wrapped. 6042 DECL_ACCESSORS(value, Object) 6043 6044 // Casting. 6045 static inline JSValue* cast(Object* obj); 6046 6047 // Dispatched behavior. 6048 #ifdef OBJECT_PRINT JSValuePrint()6049 inline void JSValuePrint() { 6050 JSValuePrint(stdout); 6051 } 6052 void JSValuePrint(FILE* out); 6053 #endif 6054 #ifdef DEBUG 6055 void JSValueVerify(); 6056 #endif 6057 6058 // Layout description. 6059 static const int kValueOffset = JSObject::kHeaderSize; 6060 static const int kSize = kValueOffset + kPointerSize; 6061 6062 private: 6063 DISALLOW_IMPLICIT_CONSTRUCTORS(JSValue); 6064 }; 6065 6066 6067 class DateCache; 6068 6069 // Representation for JS date objects. 6070 class JSDate: public JSObject { 6071 public: 6072 // If one component is NaN, all of them are, indicating a NaN time value. 6073 // [value]: the time value. 6074 DECL_ACCESSORS(value, Object) 6075 // [year]: caches year. Either undefined, smi, or NaN. 6076 DECL_ACCESSORS(year, Object) 6077 // [month]: caches month. Either undefined, smi, or NaN. 6078 DECL_ACCESSORS(month, Object) 6079 // [day]: caches day. Either undefined, smi, or NaN. 6080 DECL_ACCESSORS(day, Object) 6081 // [weekday]: caches day of week. Either undefined, smi, or NaN. 6082 DECL_ACCESSORS(weekday, Object) 6083 // [hour]: caches hours. Either undefined, smi, or NaN. 6084 DECL_ACCESSORS(hour, Object) 6085 // [min]: caches minutes. Either undefined, smi, or NaN. 6086 DECL_ACCESSORS(min, Object) 6087 // [sec]: caches seconds. Either undefined, smi, or NaN. 6088 DECL_ACCESSORS(sec, Object) 6089 // [cache stamp]: sample of the date cache stamp at the 6090 // moment when local fields were cached. 6091 DECL_ACCESSORS(cache_stamp, Object) 6092 6093 // Casting. 6094 static inline JSDate* cast(Object* obj); 6095 6096 // Returns the date field with the specified index. 6097 // See FieldIndex for the list of date fields. 6098 static MaybeObject* GetField(Object* date, Smi* index); 6099 6100 void SetValue(Object* value, bool is_value_nan); 6101 6102 6103 // Dispatched behavior. 6104 #ifdef OBJECT_PRINT JSDatePrint()6105 inline void JSDatePrint() { 6106 JSDatePrint(stdout); 6107 } 6108 void JSDatePrint(FILE* out); 6109 #endif 6110 #ifdef DEBUG 6111 void JSDateVerify(); 6112 #endif 6113 // The order is important. It must be kept in sync with date macros 6114 // in macros.py. 6115 enum FieldIndex { 6116 kDateValue, 6117 kYear, 6118 kMonth, 6119 kDay, 6120 kWeekday, 6121 kHour, 6122 kMinute, 6123 kSecond, 6124 kFirstUncachedField, 6125 kMillisecond = kFirstUncachedField, 6126 kDays, 6127 kTimeInDay, 6128 kFirstUTCField, 6129 kYearUTC = kFirstUTCField, 6130 kMonthUTC, 6131 kDayUTC, 6132 kWeekdayUTC, 6133 kHourUTC, 6134 kMinuteUTC, 6135 kSecondUTC, 6136 kMillisecondUTC, 6137 kDaysUTC, 6138 kTimeInDayUTC, 6139 kTimezoneOffset 6140 }; 6141 6142 // Layout description. 6143 static const int kValueOffset = JSObject::kHeaderSize; 6144 static const int kYearOffset = kValueOffset + kPointerSize; 6145 static const int kMonthOffset = kYearOffset + kPointerSize; 6146 static const int kDayOffset = kMonthOffset + kPointerSize; 6147 static const int kWeekdayOffset = kDayOffset + kPointerSize; 6148 static const int kHourOffset = kWeekdayOffset + kPointerSize; 6149 static const int kMinOffset = kHourOffset + kPointerSize; 6150 static const int kSecOffset = kMinOffset + kPointerSize; 6151 static const int kCacheStampOffset = kSecOffset + kPointerSize; 6152 static const int kSize = kCacheStampOffset + kPointerSize; 6153 6154 private: 6155 inline Object* DoGetField(FieldIndex index); 6156 6157 Object* GetUTCField(FieldIndex index, double value, DateCache* date_cache); 6158 6159 // Computes and caches the cacheable fields of the date. 6160 inline void SetLocalFields(int64_t local_time_ms, DateCache* date_cache); 6161 6162 6163 DISALLOW_IMPLICIT_CONSTRUCTORS(JSDate); 6164 }; 6165 6166 6167 // Representation of message objects used for error reporting through 6168 // the API. The messages are formatted in JavaScript so this object is 6169 // a real JavaScript object. The information used for formatting the 6170 // error messages are not directly accessible from JavaScript to 6171 // prevent leaking information to user code called during error 6172 // formatting. 6173 class JSMessageObject: public JSObject { 6174 public: 6175 // [type]: the type of error message. 6176 DECL_ACCESSORS(type, String) 6177 6178 // [arguments]: the arguments for formatting the error message. 6179 DECL_ACCESSORS(arguments, JSArray) 6180 6181 // [script]: the script from which the error message originated. 6182 DECL_ACCESSORS(script, Object) 6183 6184 // [stack_trace]: the stack trace for this error message. 6185 DECL_ACCESSORS(stack_trace, Object) 6186 6187 // [stack_frames]: an array of stack frames for this error object. 6188 DECL_ACCESSORS(stack_frames, Object) 6189 6190 // [start_position]: the start position in the script for the error message. 6191 inline int start_position(); 6192 inline void set_start_position(int value); 6193 6194 // [end_position]: the end position in the script for the error message. 6195 inline int end_position(); 6196 inline void set_end_position(int value); 6197 6198 // Casting. 6199 static inline JSMessageObject* cast(Object* obj); 6200 6201 // Dispatched behavior. 6202 #ifdef OBJECT_PRINT JSMessageObjectPrint()6203 inline void JSMessageObjectPrint() { 6204 JSMessageObjectPrint(stdout); 6205 } 6206 void JSMessageObjectPrint(FILE* out); 6207 #endif 6208 #ifdef DEBUG 6209 void JSMessageObjectVerify(); 6210 #endif 6211 6212 // Layout description. 6213 static const int kTypeOffset = JSObject::kHeaderSize; 6214 static const int kArgumentsOffset = kTypeOffset + kPointerSize; 6215 static const int kScriptOffset = kArgumentsOffset + kPointerSize; 6216 static const int kStackTraceOffset = kScriptOffset + kPointerSize; 6217 static const int kStackFramesOffset = kStackTraceOffset + kPointerSize; 6218 static const int kStartPositionOffset = kStackFramesOffset + kPointerSize; 6219 static const int kEndPositionOffset = kStartPositionOffset + kPointerSize; 6220 static const int kSize = kEndPositionOffset + kPointerSize; 6221 6222 typedef FixedBodyDescriptor<HeapObject::kMapOffset, 6223 kStackFramesOffset + kPointerSize, 6224 kSize> BodyDescriptor; 6225 }; 6226 6227 6228 // Regular expressions 6229 // The regular expression holds a single reference to a FixedArray in 6230 // the kDataOffset field. 6231 // The FixedArray contains the following data: 6232 // - tag : type of regexp implementation (not compiled yet, atom or irregexp) 6233 // - reference to the original source string 6234 // - reference to the original flag string 6235 // If it is an atom regexp 6236 // - a reference to a literal string to search for 6237 // If it is an irregexp regexp: 6238 // - a reference to code for ASCII inputs (bytecode or compiled), or a smi 6239 // used for tracking the last usage (used for code flushing). 6240 // - a reference to code for UC16 inputs (bytecode or compiled), or a smi 6241 // used for tracking the last usage (used for code flushing).. 6242 // - max number of registers used by irregexp implementations. 6243 // - number of capture registers (output values) of the regexp. 6244 class JSRegExp: public JSObject { 6245 public: 6246 // Meaning of Type: 6247 // NOT_COMPILED: Initial value. No data has been stored in the JSRegExp yet. 6248 // ATOM: A simple string to match against using an indexOf operation. 6249 // IRREGEXP: Compiled with Irregexp. 6250 // IRREGEXP_NATIVE: Compiled to native code with Irregexp. 6251 enum Type { NOT_COMPILED, ATOM, IRREGEXP }; 6252 enum Flag { NONE = 0, GLOBAL = 1, IGNORE_CASE = 2, MULTILINE = 4 }; 6253 6254 class Flags { 6255 public: Flags(uint32_t value)6256 explicit Flags(uint32_t value) : value_(value) { } is_global()6257 bool is_global() { return (value_ & GLOBAL) != 0; } is_ignore_case()6258 bool is_ignore_case() { return (value_ & IGNORE_CASE) != 0; } is_multiline()6259 bool is_multiline() { return (value_ & MULTILINE) != 0; } value()6260 uint32_t value() { return value_; } 6261 private: 6262 uint32_t value_; 6263 }; 6264 6265 DECL_ACCESSORS(data, Object) 6266 6267 inline Type TypeTag(); 6268 inline int CaptureCount(); 6269 inline Flags GetFlags(); 6270 inline String* Pattern(); 6271 inline Object* DataAt(int index); 6272 // Set implementation data after the object has been prepared. 6273 inline void SetDataAt(int index, Object* value); 6274 6275 // Used during GC when flushing code or setting age. 6276 inline Object* DataAtUnchecked(int index); 6277 inline void SetDataAtUnchecked(int index, Object* value, Heap* heap); 6278 inline Type TypeTagUnchecked(); 6279 code_index(bool is_ascii)6280 static int code_index(bool is_ascii) { 6281 if (is_ascii) { 6282 return kIrregexpASCIICodeIndex; 6283 } else { 6284 return kIrregexpUC16CodeIndex; 6285 } 6286 } 6287 saved_code_index(bool is_ascii)6288 static int saved_code_index(bool is_ascii) { 6289 if (is_ascii) { 6290 return kIrregexpASCIICodeSavedIndex; 6291 } else { 6292 return kIrregexpUC16CodeSavedIndex; 6293 } 6294 } 6295 6296 static inline JSRegExp* cast(Object* obj); 6297 6298 // Dispatched behavior. 6299 #ifdef DEBUG 6300 void JSRegExpVerify(); 6301 #endif 6302 6303 static const int kDataOffset = JSObject::kHeaderSize; 6304 static const int kSize = kDataOffset + kPointerSize; 6305 6306 // Indices in the data array. 6307 static const int kTagIndex = 0; 6308 static const int kSourceIndex = kTagIndex + 1; 6309 static const int kFlagsIndex = kSourceIndex + 1; 6310 static const int kDataIndex = kFlagsIndex + 1; 6311 // The data fields are used in different ways depending on the 6312 // value of the tag. 6313 // Atom regexps (literal strings). 6314 static const int kAtomPatternIndex = kDataIndex; 6315 6316 static const int kAtomDataSize = kAtomPatternIndex + 1; 6317 6318 // Irregexp compiled code or bytecode for ASCII. If compilation 6319 // fails, this fields hold an exception object that should be 6320 // thrown if the regexp is used again. 6321 static const int kIrregexpASCIICodeIndex = kDataIndex; 6322 // Irregexp compiled code or bytecode for UC16. If compilation 6323 // fails, this fields hold an exception object that should be 6324 // thrown if the regexp is used again. 6325 static const int kIrregexpUC16CodeIndex = kDataIndex + 1; 6326 6327 // Saved instance of Irregexp compiled code or bytecode for ASCII that 6328 // is a potential candidate for flushing. 6329 static const int kIrregexpASCIICodeSavedIndex = kDataIndex + 2; 6330 // Saved instance of Irregexp compiled code or bytecode for UC16 that is 6331 // a potential candidate for flushing. 6332 static const int kIrregexpUC16CodeSavedIndex = kDataIndex + 3; 6333 6334 // Maximal number of registers used by either ASCII or UC16. 6335 // Only used to check that there is enough stack space 6336 static const int kIrregexpMaxRegisterCountIndex = kDataIndex + 4; 6337 // Number of captures in the compiled regexp. 6338 static const int kIrregexpCaptureCountIndex = kDataIndex + 5; 6339 6340 static const int kIrregexpDataSize = kIrregexpCaptureCountIndex + 1; 6341 6342 // Offsets directly into the data fixed array. 6343 static const int kDataTagOffset = 6344 FixedArray::kHeaderSize + kTagIndex * kPointerSize; 6345 static const int kDataAsciiCodeOffset = 6346 FixedArray::kHeaderSize + kIrregexpASCIICodeIndex * kPointerSize; 6347 static const int kDataUC16CodeOffset = 6348 FixedArray::kHeaderSize + kIrregexpUC16CodeIndex * kPointerSize; 6349 static const int kIrregexpCaptureCountOffset = 6350 FixedArray::kHeaderSize + kIrregexpCaptureCountIndex * kPointerSize; 6351 6352 // In-object fields. 6353 static const int kSourceFieldIndex = 0; 6354 static const int kGlobalFieldIndex = 1; 6355 static const int kIgnoreCaseFieldIndex = 2; 6356 static const int kMultilineFieldIndex = 3; 6357 static const int kLastIndexFieldIndex = 4; 6358 static const int kInObjectFieldCount = 5; 6359 6360 // The uninitialized value for a regexp code object. 6361 static const int kUninitializedValue = -1; 6362 6363 // The compilation error value for the regexp code object. The real error 6364 // object is in the saved code field. 6365 static const int kCompilationErrorValue = -2; 6366 6367 // When we store the sweep generation at which we moved the code from the 6368 // code index to the saved code index we mask it of to be in the [0:255] 6369 // range. 6370 static const int kCodeAgeMask = 0xff; 6371 }; 6372 6373 6374 class CompilationCacheShape : public BaseShape<HashTableKey*> { 6375 public: IsMatch(HashTableKey * key,Object * value)6376 static inline bool IsMatch(HashTableKey* key, Object* value) { 6377 return key->IsMatch(value); 6378 } 6379 Hash(HashTableKey * key)6380 static inline uint32_t Hash(HashTableKey* key) { 6381 return key->Hash(); 6382 } 6383 HashForObject(HashTableKey * key,Object * object)6384 static inline uint32_t HashForObject(HashTableKey* key, Object* object) { 6385 return key->HashForObject(object); 6386 } 6387 AsObject(HashTableKey * key)6388 MUST_USE_RESULT static MaybeObject* AsObject(HashTableKey* key) { 6389 return key->AsObject(); 6390 } 6391 6392 static const int kPrefixSize = 0; 6393 static const int kEntrySize = 2; 6394 }; 6395 6396 6397 class CompilationCacheTable: public HashTable<CompilationCacheShape, 6398 HashTableKey*> { 6399 public: 6400 // Find cached value for a string key, otherwise return null. 6401 Object* Lookup(String* src); 6402 Object* LookupEval(String* src, 6403 Context* context, 6404 LanguageMode language_mode, 6405 int scope_position); 6406 Object* LookupRegExp(String* source, JSRegExp::Flags flags); 6407 MUST_USE_RESULT MaybeObject* Put(String* src, Object* value); 6408 MUST_USE_RESULT MaybeObject* PutEval(String* src, 6409 Context* context, 6410 SharedFunctionInfo* value, 6411 int scope_position); 6412 MUST_USE_RESULT MaybeObject* PutRegExp(String* src, 6413 JSRegExp::Flags flags, 6414 FixedArray* value); 6415 6416 // Remove given value from cache. 6417 void Remove(Object* value); 6418 6419 static inline CompilationCacheTable* cast(Object* obj); 6420 6421 private: 6422 DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationCacheTable); 6423 }; 6424 6425 6426 class CodeCache: public Struct { 6427 public: 6428 DECL_ACCESSORS(default_cache, FixedArray) 6429 DECL_ACCESSORS(normal_type_cache, Object) 6430 6431 // Add the code object to the cache. 6432 MUST_USE_RESULT MaybeObject* Update(String* name, Code* code); 6433 6434 // Lookup code object in the cache. Returns code object if found and undefined 6435 // if not. 6436 Object* Lookup(String* name, Code::Flags flags); 6437 6438 // Get the internal index of a code object in the cache. Returns -1 if the 6439 // code object is not in that cache. This index can be used to later call 6440 // RemoveByIndex. The cache cannot be modified between a call to GetIndex and 6441 // RemoveByIndex. 6442 int GetIndex(Object* name, Code* code); 6443 6444 // Remove an object from the cache with the provided internal index. 6445 void RemoveByIndex(Object* name, Code* code, int index); 6446 6447 static inline CodeCache* cast(Object* obj); 6448 6449 #ifdef OBJECT_PRINT CodeCachePrint()6450 inline void CodeCachePrint() { 6451 CodeCachePrint(stdout); 6452 } 6453 void CodeCachePrint(FILE* out); 6454 #endif 6455 #ifdef DEBUG 6456 void CodeCacheVerify(); 6457 #endif 6458 6459 static const int kDefaultCacheOffset = HeapObject::kHeaderSize; 6460 static const int kNormalTypeCacheOffset = 6461 kDefaultCacheOffset + kPointerSize; 6462 static const int kSize = kNormalTypeCacheOffset + kPointerSize; 6463 6464 private: 6465 MUST_USE_RESULT MaybeObject* UpdateDefaultCache(String* name, Code* code); 6466 MUST_USE_RESULT MaybeObject* UpdateNormalTypeCache(String* name, Code* code); 6467 Object* LookupDefaultCache(String* name, Code::Flags flags); 6468 Object* LookupNormalTypeCache(String* name, Code::Flags flags); 6469 6470 // Code cache layout of the default cache. Elements are alternating name and 6471 // code objects for non normal load/store/call IC's. 6472 static const int kCodeCacheEntrySize = 2; 6473 static const int kCodeCacheEntryNameOffset = 0; 6474 static const int kCodeCacheEntryCodeOffset = 1; 6475 6476 DISALLOW_IMPLICIT_CONSTRUCTORS(CodeCache); 6477 }; 6478 6479 6480 class CodeCacheHashTableShape : public BaseShape<HashTableKey*> { 6481 public: IsMatch(HashTableKey * key,Object * value)6482 static inline bool IsMatch(HashTableKey* key, Object* value) { 6483 return key->IsMatch(value); 6484 } 6485 Hash(HashTableKey * key)6486 static inline uint32_t Hash(HashTableKey* key) { 6487 return key->Hash(); 6488 } 6489 HashForObject(HashTableKey * key,Object * object)6490 static inline uint32_t HashForObject(HashTableKey* key, Object* object) { 6491 return key->HashForObject(object); 6492 } 6493 AsObject(HashTableKey * key)6494 MUST_USE_RESULT static MaybeObject* AsObject(HashTableKey* key) { 6495 return key->AsObject(); 6496 } 6497 6498 static const int kPrefixSize = 0; 6499 static const int kEntrySize = 2; 6500 }; 6501 6502 6503 class CodeCacheHashTable: public HashTable<CodeCacheHashTableShape, 6504 HashTableKey*> { 6505 public: 6506 Object* Lookup(String* name, Code::Flags flags); 6507 MUST_USE_RESULT MaybeObject* Put(String* name, Code* code); 6508 6509 int GetIndex(String* name, Code::Flags flags); 6510 void RemoveByIndex(int index); 6511 6512 static inline CodeCacheHashTable* cast(Object* obj); 6513 6514 // Initial size of the fixed array backing the hash table. 6515 static const int kInitialSize = 64; 6516 6517 private: 6518 DISALLOW_IMPLICIT_CONSTRUCTORS(CodeCacheHashTable); 6519 }; 6520 6521 6522 class PolymorphicCodeCache: public Struct { 6523 public: 6524 DECL_ACCESSORS(cache, Object) 6525 6526 static void Update(Handle<PolymorphicCodeCache> cache, 6527 MapHandleList* maps, 6528 Code::Flags flags, 6529 Handle<Code> code); 6530 6531 MUST_USE_RESULT MaybeObject* Update(MapHandleList* maps, 6532 Code::Flags flags, 6533 Code* code); 6534 6535 // Returns an undefined value if the entry is not found. 6536 Handle<Object> Lookup(MapHandleList* maps, Code::Flags flags); 6537 6538 static inline PolymorphicCodeCache* cast(Object* obj); 6539 6540 #ifdef OBJECT_PRINT PolymorphicCodeCachePrint()6541 inline void PolymorphicCodeCachePrint() { 6542 PolymorphicCodeCachePrint(stdout); 6543 } 6544 void PolymorphicCodeCachePrint(FILE* out); 6545 #endif 6546 #ifdef DEBUG 6547 void PolymorphicCodeCacheVerify(); 6548 #endif 6549 6550 static const int kCacheOffset = HeapObject::kHeaderSize; 6551 static const int kSize = kCacheOffset + kPointerSize; 6552 6553 private: 6554 DISALLOW_IMPLICIT_CONSTRUCTORS(PolymorphicCodeCache); 6555 }; 6556 6557 6558 class PolymorphicCodeCacheHashTable 6559 : public HashTable<CodeCacheHashTableShape, HashTableKey*> { 6560 public: 6561 Object* Lookup(MapHandleList* maps, int code_kind); 6562 6563 MUST_USE_RESULT MaybeObject* Put(MapHandleList* maps, 6564 int code_kind, 6565 Code* code); 6566 6567 static inline PolymorphicCodeCacheHashTable* cast(Object* obj); 6568 6569 static const int kInitialSize = 64; 6570 private: 6571 DISALLOW_IMPLICIT_CONSTRUCTORS(PolymorphicCodeCacheHashTable); 6572 }; 6573 6574 6575 class TypeFeedbackInfo: public Struct { 6576 public: 6577 inline int ic_total_count(); 6578 inline void set_ic_total_count(int count); 6579 6580 inline int ic_with_type_info_count(); 6581 inline void set_ic_with_type_info_count(int count); 6582 6583 DECL_ACCESSORS(type_feedback_cells, TypeFeedbackCells) 6584 6585 static inline TypeFeedbackInfo* cast(Object* obj); 6586 6587 #ifdef OBJECT_PRINT TypeFeedbackInfoPrint()6588 inline void TypeFeedbackInfoPrint() { 6589 TypeFeedbackInfoPrint(stdout); 6590 } 6591 void TypeFeedbackInfoPrint(FILE* out); 6592 #endif 6593 #ifdef DEBUG 6594 void TypeFeedbackInfoVerify(); 6595 #endif 6596 6597 static const int kIcTotalCountOffset = HeapObject::kHeaderSize; 6598 static const int kIcWithTypeinfoCountOffset = 6599 kIcTotalCountOffset + kPointerSize; 6600 static const int kTypeFeedbackCellsOffset = 6601 kIcWithTypeinfoCountOffset + kPointerSize; 6602 static const int kSize = kTypeFeedbackCellsOffset + kPointerSize; 6603 6604 private: 6605 DISALLOW_IMPLICIT_CONSTRUCTORS(TypeFeedbackInfo); 6606 }; 6607 6608 6609 // Representation of a slow alias as part of a non-strict arguments objects. 6610 // For fast aliases (if HasNonStrictArgumentsElements()): 6611 // - the parameter map contains an index into the context 6612 // - all attributes of the element have default values 6613 // For slow aliases (if HasDictionaryArgumentsElements()): 6614 // - the parameter map contains no fast alias mapping (i.e. the hole) 6615 // - this struct (in the slow backing store) contains an index into the context 6616 // - all attributes are available as part if the property details 6617 class AliasedArgumentsEntry: public Struct { 6618 public: 6619 inline int aliased_context_slot(); 6620 inline void set_aliased_context_slot(int count); 6621 6622 static inline AliasedArgumentsEntry* cast(Object* obj); 6623 6624 #ifdef OBJECT_PRINT AliasedArgumentsEntryPrint()6625 inline void AliasedArgumentsEntryPrint() { 6626 AliasedArgumentsEntryPrint(stdout); 6627 } 6628 void AliasedArgumentsEntryPrint(FILE* out); 6629 #endif 6630 #ifdef DEBUG 6631 void AliasedArgumentsEntryVerify(); 6632 #endif 6633 6634 static const int kAliasedContextSlot = HeapObject::kHeaderSize; 6635 static const int kSize = kAliasedContextSlot + kPointerSize; 6636 6637 private: 6638 DISALLOW_IMPLICIT_CONSTRUCTORS(AliasedArgumentsEntry); 6639 }; 6640 6641 6642 enum AllowNullsFlag {ALLOW_NULLS, DISALLOW_NULLS}; 6643 enum RobustnessFlag {ROBUST_STRING_TRAVERSAL, FAST_STRING_TRAVERSAL}; 6644 6645 6646 class StringHasher { 6647 public: 6648 explicit inline StringHasher(int length, uint32_t seed); 6649 6650 // Returns true if the hash of this string can be computed without 6651 // looking at the contents. 6652 inline bool has_trivial_hash(); 6653 6654 // Add a character to the hash and update the array index calculation. 6655 inline void AddCharacter(uint32_t c); 6656 6657 // Adds a character to the hash but does not update the array index 6658 // calculation. This can only be called when it has been verified 6659 // that the input is not an array index. 6660 inline void AddCharacterNoIndex(uint32_t c); 6661 6662 // Add a character above 0xffff as a surrogate pair. These can get into 6663 // the hasher through the routines that take a UTF-8 string and make a symbol. 6664 void AddSurrogatePair(uc32 c); 6665 void AddSurrogatePairNoIndex(uc32 c); 6666 6667 // Returns the value to store in the hash field of a string with 6668 // the given length and contents. 6669 uint32_t GetHashField(); 6670 6671 // Returns true if the characters seen so far make up a legal array 6672 // index. is_array_index()6673 bool is_array_index() { return is_array_index_; } 6674 is_valid()6675 bool is_valid() { return is_valid_; } 6676 invalidate()6677 void invalidate() { is_valid_ = false; } 6678 6679 // Calculated hash value for a string consisting of 1 to 6680 // String::kMaxArrayIndexSize digits with no leading zeros (except "0"). 6681 // value is represented decimal value. 6682 static uint32_t MakeArrayIndexHash(uint32_t value, int length); 6683 6684 // No string is allowed to have a hash of zero. That value is reserved 6685 // for internal properties. If the hash calculation yields zero then we 6686 // use 27 instead. 6687 static const int kZeroHash = 27; 6688 6689 private: array_index()6690 uint32_t array_index() { 6691 ASSERT(is_array_index()); 6692 return array_index_; 6693 } 6694 6695 inline uint32_t GetHash(); 6696 6697 int length_; 6698 uint32_t raw_running_hash_; 6699 uint32_t array_index_; 6700 bool is_array_index_; 6701 bool is_first_char_; 6702 bool is_valid_; 6703 friend class TwoCharHashTableKey; 6704 }; 6705 6706 6707 // Calculates string hash. 6708 template <typename schar> 6709 inline uint32_t HashSequentialString(const schar* chars, 6710 int length, 6711 uint32_t seed); 6712 6713 6714 // The characteristics of a string are stored in its map. Retrieving these 6715 // few bits of information is moderately expensive, involving two memory 6716 // loads where the second is dependent on the first. To improve efficiency 6717 // the shape of the string is given its own class so that it can be retrieved 6718 // once and used for several string operations. A StringShape is small enough 6719 // to be passed by value and is immutable, but be aware that flattening a 6720 // string can potentially alter its shape. Also be aware that a GC caused by 6721 // something else can alter the shape of a string due to ConsString 6722 // shortcutting. Keeping these restrictions in mind has proven to be error- 6723 // prone and so we no longer put StringShapes in variables unless there is a 6724 // concrete performance benefit at that particular point in the code. 6725 class StringShape BASE_EMBEDDED { 6726 public: 6727 inline explicit StringShape(String* s); 6728 inline explicit StringShape(Map* s); 6729 inline explicit StringShape(InstanceType t); 6730 inline bool IsSequential(); 6731 inline bool IsExternal(); 6732 inline bool IsCons(); 6733 inline bool IsSliced(); 6734 inline bool IsIndirect(); 6735 inline bool IsExternalAscii(); 6736 inline bool IsExternalTwoByte(); 6737 inline bool IsSequentialAscii(); 6738 inline bool IsSequentialTwoByte(); 6739 inline bool IsSymbol(); 6740 inline StringRepresentationTag representation_tag(); 6741 inline uint32_t encoding_tag(); 6742 inline uint32_t full_representation_tag(); 6743 inline uint32_t size_tag(); 6744 #ifdef DEBUG type()6745 inline uint32_t type() { return type_; } invalidate()6746 inline void invalidate() { valid_ = false; } valid()6747 inline bool valid() { return valid_; } 6748 #else invalidate()6749 inline void invalidate() { } 6750 #endif 6751 6752 private: 6753 uint32_t type_; 6754 #ifdef DEBUG set_valid()6755 inline void set_valid() { valid_ = true; } 6756 bool valid_; 6757 #else set_valid()6758 inline void set_valid() { } 6759 #endif 6760 }; 6761 6762 6763 // The String abstract class captures JavaScript string values: 6764 // 6765 // Ecma-262: 6766 // 4.3.16 String Value 6767 // A string value is a member of the type String and is a finite 6768 // ordered sequence of zero or more 16-bit unsigned integer values. 6769 // 6770 // All string values have a length field. 6771 class String: public HeapObject { 6772 public: 6773 // Representation of the flat content of a String. 6774 // A non-flat string doesn't have flat content. 6775 // A flat string has content that's encoded as a sequence of either 6776 // ASCII chars or two-byte UC16. 6777 // Returned by String::GetFlatContent(). 6778 class FlatContent { 6779 public: 6780 // Returns true if the string is flat and this structure contains content. IsFlat()6781 bool IsFlat() { return state_ != NON_FLAT; } 6782 // Returns true if the structure contains ASCII content. IsAscii()6783 bool IsAscii() { return state_ == ASCII; } 6784 // Returns true if the structure contains two-byte content. IsTwoByte()6785 bool IsTwoByte() { return state_ == TWO_BYTE; } 6786 6787 // Return the ASCII content of the string. Only use if IsAscii() returns 6788 // true. ToAsciiVector()6789 Vector<const char> ToAsciiVector() { 6790 ASSERT_EQ(ASCII, state_); 6791 return Vector<const char>::cast(buffer_); 6792 } 6793 // Return the two-byte content of the string. Only use if IsTwoByte() 6794 // returns true. ToUC16Vector()6795 Vector<const uc16> ToUC16Vector() { 6796 ASSERT_EQ(TWO_BYTE, state_); 6797 return Vector<const uc16>::cast(buffer_); 6798 } 6799 6800 private: 6801 enum State { NON_FLAT, ASCII, TWO_BYTE }; 6802 6803 // Constructors only used by String::GetFlatContent(). FlatContent(Vector<const char> chars)6804 explicit FlatContent(Vector<const char> chars) 6805 : buffer_(Vector<const byte>::cast(chars)), 6806 state_(ASCII) { } FlatContent(Vector<const uc16> chars)6807 explicit FlatContent(Vector<const uc16> chars) 6808 : buffer_(Vector<const byte>::cast(chars)), 6809 state_(TWO_BYTE) { } FlatContent()6810 FlatContent() : buffer_(), state_(NON_FLAT) { } 6811 6812 Vector<const byte> buffer_; 6813 State state_; 6814 6815 friend class String; 6816 }; 6817 6818 // Get and set the length of the string. 6819 inline int length(); 6820 inline void set_length(int value); 6821 6822 // Get and set the hash field of the string. 6823 inline uint32_t hash_field(); 6824 inline void set_hash_field(uint32_t value); 6825 6826 // Returns whether this string has only ASCII chars, i.e. all of them can 6827 // be ASCII encoded. This might be the case even if the string is 6828 // two-byte. Such strings may appear when the embedder prefers 6829 // two-byte external representations even for ASCII data. 6830 inline bool IsAsciiRepresentation(); 6831 inline bool IsTwoByteRepresentation(); 6832 6833 // Cons and slices have an encoding flag that may not represent the actual 6834 // encoding of the underlying string. This is taken into account here. 6835 // Requires: this->IsFlat() 6836 inline bool IsAsciiRepresentationUnderneath(); 6837 inline bool IsTwoByteRepresentationUnderneath(); 6838 6839 // NOTE: this should be considered only a hint. False negatives are 6840 // possible. 6841 inline bool HasOnlyAsciiChars(); 6842 6843 // Get and set individual two byte chars in the string. 6844 inline void Set(int index, uint16_t value); 6845 // Get individual two byte char in the string. Repeated calls 6846 // to this method are not efficient unless the string is flat. 6847 inline uint16_t Get(int index); 6848 6849 // Try to flatten the string. Checks first inline to see if it is 6850 // necessary. Does nothing if the string is not a cons string. 6851 // Flattening allocates a sequential string with the same data as 6852 // the given string and mutates the cons string to a degenerate 6853 // form, where the first component is the new sequential string and 6854 // the second component is the empty string. If allocation fails, 6855 // this function returns a failure. If flattening succeeds, this 6856 // function returns the sequential string that is now the first 6857 // component of the cons string. 6858 // 6859 // Degenerate cons strings are handled specially by the garbage 6860 // collector (see IsShortcutCandidate). 6861 // 6862 // Use FlattenString from Handles.cc to flatten even in case an 6863 // allocation failure happens. 6864 inline MaybeObject* TryFlatten(PretenureFlag pretenure = NOT_TENURED); 6865 6866 // Convenience function. Has exactly the same behavior as 6867 // TryFlatten(), except in the case of failure returns the original 6868 // string. 6869 inline String* TryFlattenGetString(PretenureFlag pretenure = NOT_TENURED); 6870 6871 // Tries to return the content of a flat string as a structure holding either 6872 // a flat vector of char or of uc16. 6873 // If the string isn't flat, and therefore doesn't have flat content, the 6874 // returned structure will report so, and can't provide a vector of either 6875 // kind. 6876 FlatContent GetFlatContent(); 6877 6878 // Returns the parent of a sliced string or first part of a flat cons string. 6879 // Requires: StringShape(this).IsIndirect() && this->IsFlat() 6880 inline String* GetUnderlying(); 6881 6882 // Mark the string as an undetectable object. It only applies to 6883 // ASCII and two byte string types. 6884 bool MarkAsUndetectable(); 6885 6886 // Return a substring. 6887 MUST_USE_RESULT MaybeObject* SubString(int from, 6888 int to, 6889 PretenureFlag pretenure = NOT_TENURED); 6890 6891 // String equality operations. 6892 inline bool Equals(String* other); 6893 bool IsEqualTo(Vector<const char> str); 6894 bool IsAsciiEqualTo(Vector<const char> str); 6895 bool IsTwoByteEqualTo(Vector<const uc16> str); 6896 6897 // Return a UTF8 representation of the string. The string is null 6898 // terminated but may optionally contain nulls. Length is returned 6899 // in length_output if length_output is not a null pointer The string 6900 // should be nearly flat, otherwise the performance of this method may 6901 // be very slow (quadratic in the length). Setting robustness_flag to 6902 // ROBUST_STRING_TRAVERSAL invokes behaviour that is robust This means it 6903 // handles unexpected data without causing assert failures and it does not 6904 // do any heap allocations. This is useful when printing stack traces. 6905 SmartArrayPointer<char> ToCString(AllowNullsFlag allow_nulls, 6906 RobustnessFlag robustness_flag, 6907 int offset, 6908 int length, 6909 int* length_output = 0); 6910 SmartArrayPointer<char> ToCString( 6911 AllowNullsFlag allow_nulls = DISALLOW_NULLS, 6912 RobustnessFlag robustness_flag = FAST_STRING_TRAVERSAL, 6913 int* length_output = 0); 6914 6915 // Return a 16 bit Unicode representation of the string. 6916 // The string should be nearly flat, otherwise the performance of 6917 // of this method may be very bad. Setting robustness_flag to 6918 // ROBUST_STRING_TRAVERSAL invokes behaviour that is robust This means it 6919 // handles unexpected data without causing assert failures and it does not 6920 // do any heap allocations. This is useful when printing stack traces. 6921 SmartArrayPointer<uc16> ToWideCString( 6922 RobustnessFlag robustness_flag = FAST_STRING_TRAVERSAL); 6923 6924 // Tells whether the hash code has been computed. 6925 inline bool HasHashCode(); 6926 6927 // Returns a hash value used for the property table 6928 inline uint32_t Hash(); 6929 6930 static uint32_t ComputeHashField(unibrow::CharacterStream* buffer, 6931 int length, 6932 uint32_t seed); 6933 6934 static bool ComputeArrayIndex(unibrow::CharacterStream* buffer, 6935 uint32_t* index, 6936 int length); 6937 6938 // Externalization. 6939 bool MakeExternal(v8::String::ExternalStringResource* resource); 6940 bool MakeExternal(v8::String::ExternalAsciiStringResource* resource); 6941 6942 // Conversion. 6943 inline bool AsArrayIndex(uint32_t* index); 6944 6945 // Casting. 6946 static inline String* cast(Object* obj); 6947 6948 void PrintOn(FILE* out); 6949 6950 // For use during stack traces. Performs rudimentary sanity check. 6951 bool LooksValid(); 6952 6953 // Dispatched behavior. 6954 void StringShortPrint(StringStream* accumulator); 6955 #ifdef OBJECT_PRINT StringPrint()6956 inline void StringPrint() { 6957 StringPrint(stdout); 6958 } 6959 void StringPrint(FILE* out); 6960 6961 char* ToAsciiArray(); 6962 #endif 6963 #ifdef DEBUG 6964 void StringVerify(); 6965 #endif 6966 inline bool IsFlat(); 6967 6968 // Layout description. 6969 static const int kLengthOffset = HeapObject::kHeaderSize; 6970 static const int kHashFieldOffset = kLengthOffset + kPointerSize; 6971 static const int kSize = kHashFieldOffset + kPointerSize; 6972 6973 // Maximum number of characters to consider when trying to convert a string 6974 // value into an array index. 6975 static const int kMaxArrayIndexSize = 10; 6976 6977 // Max ASCII char code. 6978 static const int kMaxAsciiCharCode = unibrow::Utf8::kMaxOneByteChar; 6979 static const unsigned kMaxAsciiCharCodeU = unibrow::Utf8::kMaxOneByteChar; 6980 static const int kMaxUtf16CodeUnit = 0xffff; 6981 6982 // Mask constant for checking if a string has a computed hash code 6983 // and if it is an array index. The least significant bit indicates 6984 // whether a hash code has been computed. If the hash code has been 6985 // computed the 2nd bit tells whether the string can be used as an 6986 // array index. 6987 static const int kHashNotComputedMask = 1; 6988 static const int kIsNotArrayIndexMask = 1 << 1; 6989 static const int kNofHashBitFields = 2; 6990 6991 // Shift constant retrieving hash code from hash field. 6992 static const int kHashShift = kNofHashBitFields; 6993 6994 // Only these bits are relevant in the hash, since the top two are shifted 6995 // out. 6996 static const uint32_t kHashBitMask = 0xffffffffu >> kHashShift; 6997 6998 // Array index strings this short can keep their index in the hash 6999 // field. 7000 static const int kMaxCachedArrayIndexLength = 7; 7001 7002 // For strings which are array indexes the hash value has the string length 7003 // mixed into the hash, mainly to avoid a hash value of zero which would be 7004 // the case for the string '0'. 24 bits are used for the array index value. 7005 static const int kArrayIndexValueBits = 24; 7006 static const int kArrayIndexLengthBits = 7007 kBitsPerInt - kArrayIndexValueBits - kNofHashBitFields; 7008 7009 STATIC_CHECK((kArrayIndexLengthBits > 0)); 7010 STATIC_CHECK(kMaxArrayIndexSize < (1 << kArrayIndexLengthBits)); 7011 7012 static const int kArrayIndexHashLengthShift = 7013 kArrayIndexValueBits + kNofHashBitFields; 7014 7015 static const int kArrayIndexHashMask = (1 << kArrayIndexHashLengthShift) - 1; 7016 7017 static const int kArrayIndexValueMask = 7018 ((1 << kArrayIndexValueBits) - 1) << kHashShift; 7019 7020 // Check that kMaxCachedArrayIndexLength + 1 is a power of two so we 7021 // could use a mask to test if the length of string is less than or equal to 7022 // kMaxCachedArrayIndexLength. 7023 STATIC_CHECK(IS_POWER_OF_TWO(kMaxCachedArrayIndexLength + 1)); 7024 7025 static const int kContainsCachedArrayIndexMask = 7026 (~kMaxCachedArrayIndexLength << kArrayIndexHashLengthShift) | 7027 kIsNotArrayIndexMask; 7028 7029 // Value of empty hash field indicating that the hash is not computed. 7030 static const int kEmptyHashField = 7031 kIsNotArrayIndexMask | kHashNotComputedMask; 7032 7033 // Value of hash field containing computed hash equal to zero. 7034 static const int kZeroHash = kIsNotArrayIndexMask; 7035 7036 // Maximal string length. 7037 static const int kMaxLength = (1 << (32 - 2)) - 1; 7038 7039 // Max length for computing hash. For strings longer than this limit the 7040 // string length is used as the hash value. 7041 static const int kMaxHashCalcLength = 16383; 7042 7043 // Limit for truncation in short printing. 7044 static const int kMaxShortPrintLength = 1024; 7045 7046 // Support for regular expressions. 7047 const uc16* GetTwoByteData(); 7048 const uc16* GetTwoByteData(unsigned start); 7049 7050 // Support for StringInputBuffer 7051 static const unibrow::byte* ReadBlock(String* input, 7052 unibrow::byte* util_buffer, 7053 unsigned capacity, 7054 unsigned* remaining, 7055 unsigned* offset); 7056 static const unibrow::byte* ReadBlock(String** input, 7057 unibrow::byte* util_buffer, 7058 unsigned capacity, 7059 unsigned* remaining, 7060 unsigned* offset); 7061 7062 // Helper function for flattening strings. 7063 template <typename sinkchar> 7064 static void WriteToFlat(String* source, 7065 sinkchar* sink, 7066 int from, 7067 int to); 7068 IsAscii(const char * chars,int length)7069 static inline bool IsAscii(const char* chars, int length) { 7070 const char* limit = chars + length; 7071 #ifdef V8_HOST_CAN_READ_UNALIGNED 7072 ASSERT(kMaxAsciiCharCode == 0x7F); 7073 const uintptr_t non_ascii_mask = kUintptrAllBitsSet / 0xFF * 0x80; 7074 while (chars <= limit - sizeof(uintptr_t)) { 7075 if (*reinterpret_cast<const uintptr_t*>(chars) & non_ascii_mask) { 7076 return false; 7077 } 7078 chars += sizeof(uintptr_t); 7079 } 7080 #endif 7081 while (chars < limit) { 7082 if (static_cast<uint8_t>(*chars) > kMaxAsciiCharCodeU) return false; 7083 ++chars; 7084 } 7085 return true; 7086 } 7087 IsAscii(const uc16 * chars,int length)7088 static inline bool IsAscii(const uc16* chars, int length) { 7089 const uc16* limit = chars + length; 7090 while (chars < limit) { 7091 if (*chars > kMaxAsciiCharCodeU) return false; 7092 ++chars; 7093 } 7094 return true; 7095 } 7096 7097 protected: 7098 class ReadBlockBuffer { 7099 public: ReadBlockBuffer(unibrow::byte * util_buffer_,unsigned cursor_,unsigned capacity_,unsigned remaining_)7100 ReadBlockBuffer(unibrow::byte* util_buffer_, 7101 unsigned cursor_, 7102 unsigned capacity_, 7103 unsigned remaining_) : 7104 util_buffer(util_buffer_), 7105 cursor(cursor_), 7106 capacity(capacity_), 7107 remaining(remaining_) { 7108 } 7109 unibrow::byte* util_buffer; 7110 unsigned cursor; 7111 unsigned capacity; 7112 unsigned remaining; 7113 }; 7114 7115 static inline const unibrow::byte* ReadBlock(String* input, 7116 ReadBlockBuffer* buffer, 7117 unsigned* offset, 7118 unsigned max_chars); 7119 static void ReadBlockIntoBuffer(String* input, 7120 ReadBlockBuffer* buffer, 7121 unsigned* offset_ptr, 7122 unsigned max_chars); 7123 7124 private: 7125 // Try to flatten the top level ConsString that is hiding behind this 7126 // string. This is a no-op unless the string is a ConsString. Flatten 7127 // mutates the ConsString and might return a failure. 7128 MUST_USE_RESULT MaybeObject* SlowTryFlatten(PretenureFlag pretenure); 7129 7130 static inline bool IsHashFieldComputed(uint32_t field); 7131 7132 // Slow case of String::Equals. This implementation works on any strings 7133 // but it is most efficient on strings that are almost flat. 7134 bool SlowEquals(String* other); 7135 7136 // Slow case of AsArrayIndex. 7137 bool SlowAsArrayIndex(uint32_t* index); 7138 7139 // Compute and set the hash code. 7140 uint32_t ComputeAndSetHash(); 7141 7142 DISALLOW_IMPLICIT_CONSTRUCTORS(String); 7143 }; 7144 7145 7146 // The SeqString abstract class captures sequential string values. 7147 class SeqString: public String { 7148 public: 7149 // Casting. 7150 static inline SeqString* cast(Object* obj); 7151 7152 // Layout description. 7153 static const int kHeaderSize = String::kSize; 7154 7155 private: 7156 DISALLOW_IMPLICIT_CONSTRUCTORS(SeqString); 7157 }; 7158 7159 7160 // The AsciiString class captures sequential ASCII string objects. 7161 // Each character in the AsciiString is an ASCII character. 7162 class SeqAsciiString: public SeqString { 7163 public: 7164 static const bool kHasAsciiEncoding = true; 7165 7166 // Dispatched behavior. 7167 inline uint16_t SeqAsciiStringGet(int index); 7168 inline void SeqAsciiStringSet(int index, uint16_t value); 7169 7170 // Get the address of the characters in this string. 7171 inline Address GetCharsAddress(); 7172 7173 inline char* GetChars(); 7174 7175 // Casting 7176 static inline SeqAsciiString* cast(Object* obj); 7177 7178 // Garbage collection support. This method is called by the 7179 // garbage collector to compute the actual size of an AsciiString 7180 // instance. 7181 inline int SeqAsciiStringSize(InstanceType instance_type); 7182 7183 // Computes the size for an AsciiString instance of a given length. SizeFor(int length)7184 static int SizeFor(int length) { 7185 return OBJECT_POINTER_ALIGN(kHeaderSize + length * kCharSize); 7186 } 7187 7188 // Maximal memory usage for a single sequential ASCII string. 7189 static const int kMaxSize = 512 * MB - 1; 7190 // Maximal length of a single sequential ASCII string. 7191 // Q.v. String::kMaxLength which is the maximal size of concatenated strings. 7192 static const int kMaxLength = (kMaxSize - kHeaderSize); 7193 7194 // Support for StringInputBuffer. 7195 inline void SeqAsciiStringReadBlockIntoBuffer(ReadBlockBuffer* buffer, 7196 unsigned* offset, 7197 unsigned chars); 7198 inline const unibrow::byte* SeqAsciiStringReadBlock(unsigned* remaining, 7199 unsigned* offset, 7200 unsigned chars); 7201 7202 private: 7203 DISALLOW_IMPLICIT_CONSTRUCTORS(SeqAsciiString); 7204 }; 7205 7206 7207 // The TwoByteString class captures sequential unicode string objects. 7208 // Each character in the TwoByteString is a two-byte uint16_t. 7209 class SeqTwoByteString: public SeqString { 7210 public: 7211 static const bool kHasAsciiEncoding = false; 7212 7213 // Dispatched behavior. 7214 inline uint16_t SeqTwoByteStringGet(int index); 7215 inline void SeqTwoByteStringSet(int index, uint16_t value); 7216 7217 // Get the address of the characters in this string. 7218 inline Address GetCharsAddress(); 7219 7220 inline uc16* GetChars(); 7221 7222 // For regexp code. 7223 const uint16_t* SeqTwoByteStringGetData(unsigned start); 7224 7225 // Casting 7226 static inline SeqTwoByteString* cast(Object* obj); 7227 7228 // Garbage collection support. This method is called by the 7229 // garbage collector to compute the actual size of a TwoByteString 7230 // instance. 7231 inline int SeqTwoByteStringSize(InstanceType instance_type); 7232 7233 // Computes the size for a TwoByteString instance of a given length. SizeFor(int length)7234 static int SizeFor(int length) { 7235 return OBJECT_POINTER_ALIGN(kHeaderSize + length * kShortSize); 7236 } 7237 7238 // Maximal memory usage for a single sequential two-byte string. 7239 static const int kMaxSize = 512 * MB - 1; 7240 // Maximal length of a single sequential two-byte string. 7241 // Q.v. String::kMaxLength which is the maximal size of concatenated strings. 7242 static const int kMaxLength = (kMaxSize - kHeaderSize) / sizeof(uint16_t); 7243 7244 // Support for StringInputBuffer. 7245 inline void SeqTwoByteStringReadBlockIntoBuffer(ReadBlockBuffer* buffer, 7246 unsigned* offset_ptr, 7247 unsigned chars); 7248 7249 private: 7250 DISALLOW_IMPLICIT_CONSTRUCTORS(SeqTwoByteString); 7251 }; 7252 7253 7254 // The ConsString class describes string values built by using the 7255 // addition operator on strings. A ConsString is a pair where the 7256 // first and second components are pointers to other string values. 7257 // One or both components of a ConsString can be pointers to other 7258 // ConsStrings, creating a binary tree of ConsStrings where the leaves 7259 // are non-ConsString string values. The string value represented by 7260 // a ConsString can be obtained by concatenating the leaf string 7261 // values in a left-to-right depth-first traversal of the tree. 7262 class ConsString: public String { 7263 public: 7264 // First string of the cons cell. 7265 inline String* first(); 7266 // Doesn't check that the result is a string, even in debug mode. This is 7267 // useful during GC where the mark bits confuse the checks. 7268 inline Object* unchecked_first(); 7269 inline void set_first(String* first, 7270 WriteBarrierMode mode = UPDATE_WRITE_BARRIER); 7271 7272 // Second string of the cons cell. 7273 inline String* second(); 7274 // Doesn't check that the result is a string, even in debug mode. This is 7275 // useful during GC where the mark bits confuse the checks. 7276 inline Object* unchecked_second(); 7277 inline void set_second(String* second, 7278 WriteBarrierMode mode = UPDATE_WRITE_BARRIER); 7279 7280 // Dispatched behavior. 7281 uint16_t ConsStringGet(int index); 7282 7283 // Casting. 7284 static inline ConsString* cast(Object* obj); 7285 7286 // Layout description. 7287 static const int kFirstOffset = POINTER_SIZE_ALIGN(String::kSize); 7288 static const int kSecondOffset = kFirstOffset + kPointerSize; 7289 static const int kSize = kSecondOffset + kPointerSize; 7290 7291 // Support for StringInputBuffer. 7292 inline const unibrow::byte* ConsStringReadBlock(ReadBlockBuffer* buffer, 7293 unsigned* offset_ptr, 7294 unsigned chars); 7295 inline void ConsStringReadBlockIntoBuffer(ReadBlockBuffer* buffer, 7296 unsigned* offset_ptr, 7297 unsigned chars); 7298 7299 // Minimum length for a cons string. 7300 static const int kMinLength = 13; 7301 7302 typedef FixedBodyDescriptor<kFirstOffset, kSecondOffset + kPointerSize, kSize> 7303 BodyDescriptor; 7304 7305 #ifdef DEBUG 7306 void ConsStringVerify(); 7307 #endif 7308 7309 private: 7310 DISALLOW_IMPLICIT_CONSTRUCTORS(ConsString); 7311 }; 7312 7313 7314 // The Sliced String class describes strings that are substrings of another 7315 // sequential string. The motivation is to save time and memory when creating 7316 // a substring. A Sliced String is described as a pointer to the parent, 7317 // the offset from the start of the parent string and the length. Using 7318 // a Sliced String therefore requires unpacking of the parent string and 7319 // adding the offset to the start address. A substring of a Sliced String 7320 // are not nested since the double indirection is simplified when creating 7321 // such a substring. 7322 // Currently missing features are: 7323 // - handling externalized parent strings 7324 // - external strings as parent 7325 // - truncating sliced string to enable otherwise unneeded parent to be GC'ed. 7326 class SlicedString: public String { 7327 public: 7328 inline String* parent(); 7329 inline void set_parent(String* parent); 7330 inline int offset(); 7331 inline void set_offset(int offset); 7332 7333 // Dispatched behavior. 7334 uint16_t SlicedStringGet(int index); 7335 7336 // Casting. 7337 static inline SlicedString* cast(Object* obj); 7338 7339 // Layout description. 7340 static const int kParentOffset = POINTER_SIZE_ALIGN(String::kSize); 7341 static const int kOffsetOffset = kParentOffset + kPointerSize; 7342 static const int kSize = kOffsetOffset + kPointerSize; 7343 7344 // Support for StringInputBuffer 7345 inline const unibrow::byte* SlicedStringReadBlock(ReadBlockBuffer* buffer, 7346 unsigned* offset_ptr, 7347 unsigned chars); 7348 inline void SlicedStringReadBlockIntoBuffer(ReadBlockBuffer* buffer, 7349 unsigned* offset_ptr, 7350 unsigned chars); 7351 // Minimum length for a sliced string. 7352 static const int kMinLength = 13; 7353 7354 typedef FixedBodyDescriptor<kParentOffset, 7355 kOffsetOffset + kPointerSize, kSize> 7356 BodyDescriptor; 7357 7358 #ifdef DEBUG 7359 void SlicedStringVerify(); 7360 #endif 7361 7362 private: 7363 DISALLOW_IMPLICIT_CONSTRUCTORS(SlicedString); 7364 }; 7365 7366 7367 // The ExternalString class describes string values that are backed by 7368 // a string resource that lies outside the V8 heap. ExternalStrings 7369 // consist of the length field common to all strings, a pointer to the 7370 // external resource. It is important to ensure (externally) that the 7371 // resource is not deallocated while the ExternalString is live in the 7372 // V8 heap. 7373 // 7374 // The API expects that all ExternalStrings are created through the 7375 // API. Therefore, ExternalStrings should not be used internally. 7376 class ExternalString: public String { 7377 public: 7378 // Casting 7379 static inline ExternalString* cast(Object* obj); 7380 7381 // Layout description. 7382 static const int kResourceOffset = POINTER_SIZE_ALIGN(String::kSize); 7383 static const int kShortSize = kResourceOffset + kPointerSize; 7384 static const int kResourceDataOffset = kResourceOffset + kPointerSize; 7385 static const int kSize = kResourceDataOffset + kPointerSize; 7386 7387 // Return whether external string is short (data pointer is not cached). 7388 inline bool is_short(); 7389 7390 STATIC_CHECK(kResourceOffset == Internals::kStringResourceOffset); 7391 7392 private: 7393 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalString); 7394 }; 7395 7396 7397 // The ExternalAsciiString class is an external string backed by an 7398 // ASCII string. 7399 class ExternalAsciiString: public ExternalString { 7400 public: 7401 static const bool kHasAsciiEncoding = true; 7402 7403 typedef v8::String::ExternalAsciiStringResource Resource; 7404 7405 // The underlying resource. 7406 inline const Resource* resource(); 7407 inline void set_resource(const Resource* buffer); 7408 7409 // Update the pointer cache to the external character array. 7410 // The cached pointer is always valid, as the external character array does = 7411 // not move during lifetime. Deserialization is the only exception, after 7412 // which the pointer cache has to be refreshed. 7413 inline void update_data_cache(); 7414 7415 inline const char* GetChars(); 7416 7417 // Dispatched behavior. 7418 inline uint16_t ExternalAsciiStringGet(int index); 7419 7420 // Casting. 7421 static inline ExternalAsciiString* cast(Object* obj); 7422 7423 // Garbage collection support. 7424 inline void ExternalAsciiStringIterateBody(ObjectVisitor* v); 7425 7426 template<typename StaticVisitor> 7427 inline void ExternalAsciiStringIterateBody(); 7428 7429 // Support for StringInputBuffer. 7430 const unibrow::byte* ExternalAsciiStringReadBlock(unsigned* remaining, 7431 unsigned* offset, 7432 unsigned chars); 7433 inline void ExternalAsciiStringReadBlockIntoBuffer(ReadBlockBuffer* buffer, 7434 unsigned* offset, 7435 unsigned chars); 7436 7437 private: 7438 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalAsciiString); 7439 }; 7440 7441 7442 // The ExternalTwoByteString class is an external string backed by a UTF-16 7443 // encoded string. 7444 class ExternalTwoByteString: public ExternalString { 7445 public: 7446 static const bool kHasAsciiEncoding = false; 7447 7448 typedef v8::String::ExternalStringResource Resource; 7449 7450 // The underlying string resource. 7451 inline const Resource* resource(); 7452 inline void set_resource(const Resource* buffer); 7453 7454 // Update the pointer cache to the external character array. 7455 // The cached pointer is always valid, as the external character array does = 7456 // not move during lifetime. Deserialization is the only exception, after 7457 // which the pointer cache has to be refreshed. 7458 inline void update_data_cache(); 7459 7460 inline const uint16_t* GetChars(); 7461 7462 // Dispatched behavior. 7463 inline uint16_t ExternalTwoByteStringGet(int index); 7464 7465 // For regexp code. 7466 inline const uint16_t* ExternalTwoByteStringGetData(unsigned start); 7467 7468 // Casting. 7469 static inline ExternalTwoByteString* cast(Object* obj); 7470 7471 // Garbage collection support. 7472 inline void ExternalTwoByteStringIterateBody(ObjectVisitor* v); 7473 7474 template<typename StaticVisitor> 7475 inline void ExternalTwoByteStringIterateBody(); 7476 7477 7478 // Support for StringInputBuffer. 7479 void ExternalTwoByteStringReadBlockIntoBuffer(ReadBlockBuffer* buffer, 7480 unsigned* offset_ptr, 7481 unsigned chars); 7482 7483 private: 7484 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalTwoByteString); 7485 }; 7486 7487 7488 // Utility superclass for stack-allocated objects that must be updated 7489 // on gc. It provides two ways for the gc to update instances, either 7490 // iterating or updating after gc. 7491 class Relocatable BASE_EMBEDDED { 7492 public: 7493 explicit inline Relocatable(Isolate* isolate); 7494 inline virtual ~Relocatable(); IterateInstance(ObjectVisitor * v)7495 virtual void IterateInstance(ObjectVisitor* v) { } PostGarbageCollection()7496 virtual void PostGarbageCollection() { } 7497 7498 static void PostGarbageCollectionProcessing(); 7499 static int ArchiveSpacePerThread(); 7500 static char* ArchiveState(Isolate* isolate, char* to); 7501 static char* RestoreState(Isolate* isolate, char* from); 7502 static void Iterate(ObjectVisitor* v); 7503 static void Iterate(ObjectVisitor* v, Relocatable* top); 7504 static char* Iterate(ObjectVisitor* v, char* t); 7505 private: 7506 Isolate* isolate_; 7507 Relocatable* prev_; 7508 }; 7509 7510 7511 // A flat string reader provides random access to the contents of a 7512 // string independent of the character width of the string. The handle 7513 // must be valid as long as the reader is being used. 7514 class FlatStringReader : public Relocatable { 7515 public: 7516 FlatStringReader(Isolate* isolate, Handle<String> str); 7517 FlatStringReader(Isolate* isolate, Vector<const char> input); 7518 void PostGarbageCollection(); 7519 inline uc32 Get(int index); length()7520 int length() { return length_; } 7521 private: 7522 String** str_; 7523 bool is_ascii_; 7524 int length_; 7525 const void* start_; 7526 }; 7527 7528 7529 // Note that StringInputBuffers are not valid across a GC! To fix this 7530 // it would have to store a String Handle instead of a String* and 7531 // AsciiStringReadBlock would have to be modified to use memcpy. 7532 // 7533 // StringInputBuffer is able to traverse any string regardless of how 7534 // deeply nested a sequence of ConsStrings it is made of. However, 7535 // performance will be better if deep strings are flattened before they 7536 // are traversed. Since flattening requires memory allocation this is 7537 // not always desirable, however (esp. in debugging situations). 7538 class StringInputBuffer: public unibrow::InputBuffer<String, String*, 1024> { 7539 public: 7540 virtual void Seek(unsigned pos); StringInputBuffer()7541 inline StringInputBuffer(): unibrow::InputBuffer<String, String*, 1024>() {} StringInputBuffer(String * backing)7542 explicit inline StringInputBuffer(String* backing): 7543 unibrow::InputBuffer<String, String*, 1024>(backing) {} 7544 }; 7545 7546 7547 class SafeStringInputBuffer 7548 : public unibrow::InputBuffer<String, String**, 256> { 7549 public: 7550 virtual void Seek(unsigned pos); SafeStringInputBuffer()7551 inline SafeStringInputBuffer() 7552 : unibrow::InputBuffer<String, String**, 256>() {} SafeStringInputBuffer(String ** backing)7553 explicit inline SafeStringInputBuffer(String** backing) 7554 : unibrow::InputBuffer<String, String**, 256>(backing) {} 7555 }; 7556 7557 7558 template <typename T> 7559 class VectorIterator { 7560 public: VectorIterator(T * d,int l)7561 VectorIterator(T* d, int l) : data_(Vector<const T>(d, l)), index_(0) { } VectorIterator(Vector<const T> data)7562 explicit VectorIterator(Vector<const T> data) : data_(data), index_(0) { } GetNext()7563 T GetNext() { return data_[index_++]; } has_more()7564 bool has_more() { return index_ < data_.length(); } 7565 private: 7566 Vector<const T> data_; 7567 int index_; 7568 }; 7569 7570 7571 // The Oddball describes objects null, undefined, true, and false. 7572 class Oddball: public HeapObject { 7573 public: 7574 // [to_string]: Cached to_string computed at startup. 7575 DECL_ACCESSORS(to_string, String) 7576 7577 // [to_number]: Cached to_number computed at startup. 7578 DECL_ACCESSORS(to_number, Object) 7579 7580 inline byte kind(); 7581 inline void set_kind(byte kind); 7582 7583 // Casting. 7584 static inline Oddball* cast(Object* obj); 7585 7586 // Dispatched behavior. 7587 #ifdef DEBUG 7588 void OddballVerify(); 7589 #endif 7590 7591 // Initialize the fields. 7592 MUST_USE_RESULT MaybeObject* Initialize(const char* to_string, 7593 Object* to_number, 7594 byte kind); 7595 7596 // Layout description. 7597 static const int kToStringOffset = HeapObject::kHeaderSize; 7598 static const int kToNumberOffset = kToStringOffset + kPointerSize; 7599 static const int kKindOffset = kToNumberOffset + kPointerSize; 7600 static const int kSize = kKindOffset + kPointerSize; 7601 7602 static const byte kFalse = 0; 7603 static const byte kTrue = 1; 7604 static const byte kNotBooleanMask = ~1; 7605 static const byte kTheHole = 2; 7606 static const byte kNull = 3; 7607 static const byte kArgumentMarker = 4; 7608 static const byte kUndefined = 5; 7609 static const byte kOther = 6; 7610 7611 typedef FixedBodyDescriptor<kToStringOffset, 7612 kToNumberOffset + kPointerSize, 7613 kSize> BodyDescriptor; 7614 7615 private: 7616 DISALLOW_IMPLICIT_CONSTRUCTORS(Oddball); 7617 }; 7618 7619 7620 class JSGlobalPropertyCell: public HeapObject { 7621 public: 7622 // [value]: value of the global property. 7623 DECL_ACCESSORS(value, Object) 7624 7625 // Casting. 7626 static inline JSGlobalPropertyCell* cast(Object* obj); 7627 7628 #ifdef DEBUG 7629 void JSGlobalPropertyCellVerify(); 7630 #endif 7631 #ifdef OBJECT_PRINT JSGlobalPropertyCellPrint()7632 inline void JSGlobalPropertyCellPrint() { 7633 JSGlobalPropertyCellPrint(stdout); 7634 } 7635 void JSGlobalPropertyCellPrint(FILE* out); 7636 #endif 7637 7638 // Layout description. 7639 static const int kValueOffset = HeapObject::kHeaderSize; 7640 static const int kSize = kValueOffset + kPointerSize; 7641 7642 typedef FixedBodyDescriptor<kValueOffset, 7643 kValueOffset + kPointerSize, 7644 kSize> BodyDescriptor; 7645 7646 private: 7647 DISALLOW_IMPLICIT_CONSTRUCTORS(JSGlobalPropertyCell); 7648 }; 7649 7650 7651 // The JSProxy describes EcmaScript Harmony proxies 7652 class JSProxy: public JSReceiver { 7653 public: 7654 // [handler]: The handler property. 7655 DECL_ACCESSORS(handler, Object) 7656 7657 // [hash]: The hash code property (undefined if not initialized yet). 7658 DECL_ACCESSORS(hash, Object) 7659 7660 // Casting. 7661 static inline JSProxy* cast(Object* obj); 7662 7663 bool HasPropertyWithHandler(String* name); 7664 bool HasElementWithHandler(uint32_t index); 7665 7666 MUST_USE_RESULT MaybeObject* GetPropertyWithHandler( 7667 Object* receiver, 7668 String* name); 7669 MUST_USE_RESULT MaybeObject* GetElementWithHandler( 7670 Object* receiver, 7671 uint32_t index); 7672 7673 MUST_USE_RESULT MaybeObject* SetPropertyWithHandler( 7674 String* name, 7675 Object* value, 7676 PropertyAttributes attributes, 7677 StrictModeFlag strict_mode); 7678 MUST_USE_RESULT MaybeObject* SetElementWithHandler( 7679 uint32_t index, 7680 Object* value, 7681 StrictModeFlag strict_mode); 7682 7683 // If the handler defines an accessor property, invoke its setter 7684 // (or throw if only a getter exists) and set *found to true. Otherwise false. 7685 MUST_USE_RESULT MaybeObject* SetPropertyWithHandlerIfDefiningSetter( 7686 String* name, 7687 Object* value, 7688 PropertyAttributes attributes, 7689 StrictModeFlag strict_mode, 7690 bool* found); 7691 7692 MUST_USE_RESULT MaybeObject* DeletePropertyWithHandler( 7693 String* name, 7694 DeleteMode mode); 7695 MUST_USE_RESULT MaybeObject* DeleteElementWithHandler( 7696 uint32_t index, 7697 DeleteMode mode); 7698 7699 MUST_USE_RESULT PropertyAttributes GetPropertyAttributeWithHandler( 7700 JSReceiver* receiver, 7701 String* name); 7702 MUST_USE_RESULT PropertyAttributes GetElementAttributeWithHandler( 7703 JSReceiver* receiver, 7704 uint32_t index); 7705 7706 MUST_USE_RESULT MaybeObject* GetIdentityHash(CreationFlag flag); 7707 7708 // Turn this into an (empty) JSObject. 7709 void Fix(); 7710 7711 // Initializes the body after the handler slot. 7712 inline void InitializeBody(int object_size, Object* value); 7713 7714 // Invoke a trap by name. If the trap does not exist on this's handler, 7715 // but derived_trap is non-NULL, invoke that instead. May cause GC. 7716 Handle<Object> CallTrap(const char* name, 7717 Handle<Object> derived_trap, 7718 int argc, 7719 Handle<Object> args[]); 7720 7721 // Dispatched behavior. 7722 #ifdef OBJECT_PRINT JSProxyPrint()7723 inline void JSProxyPrint() { 7724 JSProxyPrint(stdout); 7725 } 7726 void JSProxyPrint(FILE* out); 7727 #endif 7728 #ifdef DEBUG 7729 void JSProxyVerify(); 7730 #endif 7731 7732 // Layout description. We add padding so that a proxy has the same 7733 // size as a virgin JSObject. This is essential for becoming a JSObject 7734 // upon freeze. 7735 static const int kHandlerOffset = HeapObject::kHeaderSize; 7736 static const int kHashOffset = kHandlerOffset + kPointerSize; 7737 static const int kPaddingOffset = kHashOffset + kPointerSize; 7738 static const int kSize = JSObject::kHeaderSize; 7739 static const int kHeaderSize = kPaddingOffset; 7740 static const int kPaddingSize = kSize - kPaddingOffset; 7741 7742 STATIC_CHECK(kPaddingSize >= 0); 7743 7744 typedef FixedBodyDescriptor<kHandlerOffset, 7745 kPaddingOffset, 7746 kSize> BodyDescriptor; 7747 7748 private: 7749 DISALLOW_IMPLICIT_CONSTRUCTORS(JSProxy); 7750 }; 7751 7752 7753 class JSFunctionProxy: public JSProxy { 7754 public: 7755 // [call_trap]: The call trap. 7756 DECL_ACCESSORS(call_trap, Object) 7757 7758 // [construct_trap]: The construct trap. 7759 DECL_ACCESSORS(construct_trap, Object) 7760 7761 // Casting. 7762 static inline JSFunctionProxy* cast(Object* obj); 7763 7764 // Dispatched behavior. 7765 #ifdef OBJECT_PRINT JSFunctionProxyPrint()7766 inline void JSFunctionProxyPrint() { 7767 JSFunctionProxyPrint(stdout); 7768 } 7769 void JSFunctionProxyPrint(FILE* out); 7770 #endif 7771 #ifdef DEBUG 7772 void JSFunctionProxyVerify(); 7773 #endif 7774 7775 // Layout description. 7776 static const int kCallTrapOffset = JSProxy::kPaddingOffset; 7777 static const int kConstructTrapOffset = kCallTrapOffset + kPointerSize; 7778 static const int kPaddingOffset = kConstructTrapOffset + kPointerSize; 7779 static const int kSize = JSFunction::kSize; 7780 static const int kPaddingSize = kSize - kPaddingOffset; 7781 7782 STATIC_CHECK(kPaddingSize >= 0); 7783 7784 typedef FixedBodyDescriptor<kHandlerOffset, 7785 kConstructTrapOffset + kPointerSize, 7786 kSize> BodyDescriptor; 7787 7788 private: 7789 DISALLOW_IMPLICIT_CONSTRUCTORS(JSFunctionProxy); 7790 }; 7791 7792 7793 // The JSSet describes EcmaScript Harmony sets 7794 class JSSet: public JSObject { 7795 public: 7796 // [set]: the backing hash set containing keys. 7797 DECL_ACCESSORS(table, Object) 7798 7799 // Casting. 7800 static inline JSSet* cast(Object* obj); 7801 7802 #ifdef OBJECT_PRINT JSSetPrint()7803 inline void JSSetPrint() { 7804 JSSetPrint(stdout); 7805 } 7806 void JSSetPrint(FILE* out); 7807 #endif 7808 #ifdef DEBUG 7809 void JSSetVerify(); 7810 #endif 7811 7812 static const int kTableOffset = JSObject::kHeaderSize; 7813 static const int kSize = kTableOffset + kPointerSize; 7814 7815 private: 7816 DISALLOW_IMPLICIT_CONSTRUCTORS(JSSet); 7817 }; 7818 7819 7820 // The JSMap describes EcmaScript Harmony maps 7821 class JSMap: public JSObject { 7822 public: 7823 // [table]: the backing hash table mapping keys to values. 7824 DECL_ACCESSORS(table, Object) 7825 7826 // Casting. 7827 static inline JSMap* cast(Object* obj); 7828 7829 #ifdef OBJECT_PRINT JSMapPrint()7830 inline void JSMapPrint() { 7831 JSMapPrint(stdout); 7832 } 7833 void JSMapPrint(FILE* out); 7834 #endif 7835 #ifdef DEBUG 7836 void JSMapVerify(); 7837 #endif 7838 7839 static const int kTableOffset = JSObject::kHeaderSize; 7840 static const int kSize = kTableOffset + kPointerSize; 7841 7842 private: 7843 DISALLOW_IMPLICIT_CONSTRUCTORS(JSMap); 7844 }; 7845 7846 7847 // The JSWeakMap describes EcmaScript Harmony weak maps 7848 class JSWeakMap: public JSObject { 7849 public: 7850 // [table]: the backing hash table mapping keys to values. 7851 DECL_ACCESSORS(table, Object) 7852 7853 // [next]: linked list of encountered weak maps during GC. 7854 DECL_ACCESSORS(next, Object) 7855 7856 // Casting. 7857 static inline JSWeakMap* cast(Object* obj); 7858 7859 #ifdef OBJECT_PRINT JSWeakMapPrint()7860 inline void JSWeakMapPrint() { 7861 JSWeakMapPrint(stdout); 7862 } 7863 void JSWeakMapPrint(FILE* out); 7864 #endif 7865 #ifdef DEBUG 7866 void JSWeakMapVerify(); 7867 #endif 7868 7869 static const int kTableOffset = JSObject::kHeaderSize; 7870 static const int kNextOffset = kTableOffset + kPointerSize; 7871 static const int kSize = kNextOffset + kPointerSize; 7872 7873 private: 7874 DISALLOW_IMPLICIT_CONSTRUCTORS(JSWeakMap); 7875 }; 7876 7877 7878 // Foreign describes objects pointing from JavaScript to C structures. 7879 // Since they cannot contain references to JS HeapObjects they can be 7880 // placed in old_data_space. 7881 class Foreign: public HeapObject { 7882 public: 7883 // [address]: field containing the address. 7884 inline Address foreign_address(); 7885 inline void set_foreign_address(Address value); 7886 7887 // Casting. 7888 static inline Foreign* cast(Object* obj); 7889 7890 // Dispatched behavior. 7891 inline void ForeignIterateBody(ObjectVisitor* v); 7892 7893 template<typename StaticVisitor> 7894 inline void ForeignIterateBody(); 7895 7896 #ifdef OBJECT_PRINT ForeignPrint()7897 inline void ForeignPrint() { 7898 ForeignPrint(stdout); 7899 } 7900 void ForeignPrint(FILE* out); 7901 #endif 7902 #ifdef DEBUG 7903 void ForeignVerify(); 7904 #endif 7905 7906 // Layout description. 7907 7908 static const int kForeignAddressOffset = HeapObject::kHeaderSize; 7909 static const int kSize = kForeignAddressOffset + kPointerSize; 7910 7911 STATIC_CHECK(kForeignAddressOffset == Internals::kForeignAddressOffset); 7912 7913 private: 7914 DISALLOW_IMPLICIT_CONSTRUCTORS(Foreign); 7915 }; 7916 7917 7918 // The JSArray describes JavaScript Arrays 7919 // Such an array can be in one of two modes: 7920 // - fast, backing storage is a FixedArray and length <= elements.length(); 7921 // Please note: push and pop can be used to grow and shrink the array. 7922 // - slow, backing storage is a HashTable with numbers as keys. 7923 class JSArray: public JSObject { 7924 public: 7925 // [length]: The length property. 7926 DECL_ACCESSORS(length, Object) 7927 7928 // Overload the length setter to skip write barrier when the length 7929 // is set to a smi. This matches the set function on FixedArray. 7930 inline void set_length(Smi* length); 7931 7932 MUST_USE_RESULT MaybeObject* JSArrayUpdateLengthFromIndex(uint32_t index, 7933 Object* value); 7934 7935 // Initialize the array with the given capacity. The function may 7936 // fail due to out-of-memory situations, but only if the requested 7937 // capacity is non-zero. 7938 MUST_USE_RESULT MaybeObject* Initialize(int capacity); 7939 7940 // Initializes the array to a certain length. 7941 inline bool AllowsSetElementsLength(); 7942 MUST_USE_RESULT MaybeObject* SetElementsLength(Object* length); 7943 7944 // Set the content of the array to the content of storage. 7945 MUST_USE_RESULT inline MaybeObject* SetContent(FixedArrayBase* storage); 7946 7947 // Casting. 7948 static inline JSArray* cast(Object* obj); 7949 7950 // Uses handles. Ensures that the fixed array backing the JSArray has at 7951 // least the stated size. 7952 inline void EnsureSize(int minimum_size_of_backing_fixed_array); 7953 7954 // Dispatched behavior. 7955 #ifdef OBJECT_PRINT JSArrayPrint()7956 inline void JSArrayPrint() { 7957 JSArrayPrint(stdout); 7958 } 7959 void JSArrayPrint(FILE* out); 7960 #endif 7961 #ifdef DEBUG 7962 void JSArrayVerify(); 7963 #endif 7964 7965 // Number of element slots to pre-allocate for an empty array. 7966 static const int kPreallocatedArrayElements = 4; 7967 7968 // Layout description. 7969 static const int kLengthOffset = JSObject::kHeaderSize; 7970 static const int kSize = kLengthOffset + kPointerSize; 7971 7972 private: 7973 // Expand the fixed array backing of a fast-case JSArray to at least 7974 // the requested size. 7975 void Expand(int minimum_size_of_backing_fixed_array); 7976 7977 DISALLOW_IMPLICIT_CONSTRUCTORS(JSArray); 7978 }; 7979 7980 7981 // JSRegExpResult is just a JSArray with a specific initial map. 7982 // This initial map adds in-object properties for "index" and "input" 7983 // properties, as assigned by RegExp.prototype.exec, which allows 7984 // faster creation of RegExp exec results. 7985 // This class just holds constants used when creating the result. 7986 // After creation the result must be treated as a JSArray in all regards. 7987 class JSRegExpResult: public JSArray { 7988 public: 7989 // Offsets of object fields. 7990 static const int kIndexOffset = JSArray::kSize; 7991 static const int kInputOffset = kIndexOffset + kPointerSize; 7992 static const int kSize = kInputOffset + kPointerSize; 7993 // Indices of in-object properties. 7994 static const int kIndexIndex = 0; 7995 static const int kInputIndex = 1; 7996 private: 7997 DISALLOW_IMPLICIT_CONSTRUCTORS(JSRegExpResult); 7998 }; 7999 8000 8001 // An accessor must have a getter, but can have no setter. 8002 // 8003 // When setting a property, V8 searches accessors in prototypes. 8004 // If an accessor was found and it does not have a setter, 8005 // the request is ignored. 8006 // 8007 // If the accessor in the prototype has the READ_ONLY property attribute, then 8008 // a new value is added to the local object when the property is set. 8009 // This shadows the accessor in the prototype. 8010 class AccessorInfo: public Struct { 8011 public: 8012 DECL_ACCESSORS(getter, Object) 8013 DECL_ACCESSORS(setter, Object) 8014 DECL_ACCESSORS(data, Object) 8015 DECL_ACCESSORS(name, Object) 8016 DECL_ACCESSORS(flag, Smi) 8017 8018 inline bool all_can_read(); 8019 inline void set_all_can_read(bool value); 8020 8021 inline bool all_can_write(); 8022 inline void set_all_can_write(bool value); 8023 8024 inline bool prohibits_overwriting(); 8025 inline void set_prohibits_overwriting(bool value); 8026 8027 inline PropertyAttributes property_attributes(); 8028 inline void set_property_attributes(PropertyAttributes attributes); 8029 8030 static inline AccessorInfo* cast(Object* obj); 8031 8032 #ifdef OBJECT_PRINT AccessorInfoPrint()8033 inline void AccessorInfoPrint() { 8034 AccessorInfoPrint(stdout); 8035 } 8036 void AccessorInfoPrint(FILE* out); 8037 #endif 8038 #ifdef DEBUG 8039 void AccessorInfoVerify(); 8040 #endif 8041 8042 static const int kGetterOffset = HeapObject::kHeaderSize; 8043 static const int kSetterOffset = kGetterOffset + kPointerSize; 8044 static const int kDataOffset = kSetterOffset + kPointerSize; 8045 static const int kNameOffset = kDataOffset + kPointerSize; 8046 static const int kFlagOffset = kNameOffset + kPointerSize; 8047 static const int kSize = kFlagOffset + kPointerSize; 8048 8049 private: 8050 // Bit positions in flag. 8051 static const int kAllCanReadBit = 0; 8052 static const int kAllCanWriteBit = 1; 8053 static const int kProhibitsOverwritingBit = 2; 8054 class AttributesField: public BitField<PropertyAttributes, 3, 3> {}; 8055 8056 DISALLOW_IMPLICIT_CONSTRUCTORS(AccessorInfo); 8057 }; 8058 8059 8060 // Support for JavaScript accessors: A pair of a getter and a setter. Each 8061 // accessor can either be 8062 // * a pointer to a JavaScript function or proxy: a real accessor 8063 // * undefined: considered an accessor by the spec, too, strangely enough 8064 // * the hole: an accessor which has not been set 8065 // * a pointer to a map: a transition used to ensure map sharing 8066 class AccessorPair: public Struct { 8067 public: 8068 DECL_ACCESSORS(getter, Object) 8069 DECL_ACCESSORS(setter, Object) 8070 8071 static inline AccessorPair* cast(Object* obj); 8072 8073 MUST_USE_RESULT MaybeObject* CopyWithoutTransitions(); 8074 8075 // Note: Returns undefined instead in case of a hole. 8076 Object* GetComponent(AccessorComponent component); 8077 8078 // Set both components, skipping arguments which are a JavaScript null. SetComponents(Object * getter,Object * setter)8079 void SetComponents(Object* getter, Object* setter) { 8080 if (!getter->IsNull()) set_getter(getter); 8081 if (!setter->IsNull()) set_setter(setter); 8082 } 8083 ContainsAccessor()8084 bool ContainsAccessor() { 8085 return IsJSAccessor(getter()) || IsJSAccessor(setter()); 8086 } 8087 8088 #ifdef OBJECT_PRINT 8089 void AccessorPairPrint(FILE* out = stdout); 8090 #endif 8091 #ifdef DEBUG 8092 void AccessorPairVerify(); 8093 #endif 8094 8095 static const int kGetterOffset = HeapObject::kHeaderSize; 8096 static const int kSetterOffset = kGetterOffset + kPointerSize; 8097 static const int kSize = kSetterOffset + kPointerSize; 8098 8099 private: 8100 // Strangely enough, in addition to functions and harmony proxies, the spec 8101 // requires us to consider undefined as a kind of accessor, too: 8102 // var obj = {}; 8103 // Object.defineProperty(obj, "foo", {get: undefined}); 8104 // assertTrue("foo" in obj); IsJSAccessor(Object * obj)8105 bool IsJSAccessor(Object* obj) { 8106 return obj->IsSpecFunction() || obj->IsUndefined(); 8107 } 8108 8109 DISALLOW_IMPLICIT_CONSTRUCTORS(AccessorPair); 8110 }; 8111 8112 8113 class AccessCheckInfo: public Struct { 8114 public: 8115 DECL_ACCESSORS(named_callback, Object) 8116 DECL_ACCESSORS(indexed_callback, Object) 8117 DECL_ACCESSORS(data, Object) 8118 8119 static inline AccessCheckInfo* cast(Object* obj); 8120 8121 #ifdef OBJECT_PRINT AccessCheckInfoPrint()8122 inline void AccessCheckInfoPrint() { 8123 AccessCheckInfoPrint(stdout); 8124 } 8125 void AccessCheckInfoPrint(FILE* out); 8126 #endif 8127 #ifdef DEBUG 8128 void AccessCheckInfoVerify(); 8129 #endif 8130 8131 static const int kNamedCallbackOffset = HeapObject::kHeaderSize; 8132 static const int kIndexedCallbackOffset = kNamedCallbackOffset + kPointerSize; 8133 static const int kDataOffset = kIndexedCallbackOffset + kPointerSize; 8134 static const int kSize = kDataOffset + kPointerSize; 8135 8136 private: 8137 DISALLOW_IMPLICIT_CONSTRUCTORS(AccessCheckInfo); 8138 }; 8139 8140 8141 class InterceptorInfo: public Struct { 8142 public: 8143 DECL_ACCESSORS(getter, Object) 8144 DECL_ACCESSORS(setter, Object) 8145 DECL_ACCESSORS(query, Object) 8146 DECL_ACCESSORS(deleter, Object) 8147 DECL_ACCESSORS(enumerator, Object) 8148 DECL_ACCESSORS(data, Object) 8149 8150 static inline InterceptorInfo* cast(Object* obj); 8151 8152 #ifdef OBJECT_PRINT InterceptorInfoPrint()8153 inline void InterceptorInfoPrint() { 8154 InterceptorInfoPrint(stdout); 8155 } 8156 void InterceptorInfoPrint(FILE* out); 8157 #endif 8158 #ifdef DEBUG 8159 void InterceptorInfoVerify(); 8160 #endif 8161 8162 static const int kGetterOffset = HeapObject::kHeaderSize; 8163 static const int kSetterOffset = kGetterOffset + kPointerSize; 8164 static const int kQueryOffset = kSetterOffset + kPointerSize; 8165 static const int kDeleterOffset = kQueryOffset + kPointerSize; 8166 static const int kEnumeratorOffset = kDeleterOffset + kPointerSize; 8167 static const int kDataOffset = kEnumeratorOffset + kPointerSize; 8168 static const int kSize = kDataOffset + kPointerSize; 8169 8170 private: 8171 DISALLOW_IMPLICIT_CONSTRUCTORS(InterceptorInfo); 8172 }; 8173 8174 8175 class CallHandlerInfo: public Struct { 8176 public: 8177 DECL_ACCESSORS(callback, Object) 8178 DECL_ACCESSORS(data, Object) 8179 8180 static inline CallHandlerInfo* cast(Object* obj); 8181 8182 #ifdef OBJECT_PRINT CallHandlerInfoPrint()8183 inline void CallHandlerInfoPrint() { 8184 CallHandlerInfoPrint(stdout); 8185 } 8186 void CallHandlerInfoPrint(FILE* out); 8187 #endif 8188 #ifdef DEBUG 8189 void CallHandlerInfoVerify(); 8190 #endif 8191 8192 static const int kCallbackOffset = HeapObject::kHeaderSize; 8193 static const int kDataOffset = kCallbackOffset + kPointerSize; 8194 static const int kSize = kDataOffset + kPointerSize; 8195 8196 private: 8197 DISALLOW_IMPLICIT_CONSTRUCTORS(CallHandlerInfo); 8198 }; 8199 8200 8201 class TemplateInfo: public Struct { 8202 public: 8203 DECL_ACCESSORS(tag, Object) 8204 DECL_ACCESSORS(property_list, Object) 8205 8206 #ifdef DEBUG 8207 void TemplateInfoVerify(); 8208 #endif 8209 8210 static const int kTagOffset = HeapObject::kHeaderSize; 8211 static const int kPropertyListOffset = kTagOffset + kPointerSize; 8212 static const int kHeaderSize = kPropertyListOffset + kPointerSize; 8213 8214 private: 8215 DISALLOW_IMPLICIT_CONSTRUCTORS(TemplateInfo); 8216 }; 8217 8218 8219 class FunctionTemplateInfo: public TemplateInfo { 8220 public: 8221 DECL_ACCESSORS(serial_number, Object) 8222 DECL_ACCESSORS(call_code, Object) 8223 DECL_ACCESSORS(property_accessors, Object) 8224 DECL_ACCESSORS(prototype_template, Object) 8225 DECL_ACCESSORS(parent_template, Object) 8226 DECL_ACCESSORS(named_property_handler, Object) 8227 DECL_ACCESSORS(indexed_property_handler, Object) 8228 DECL_ACCESSORS(instance_template, Object) 8229 DECL_ACCESSORS(class_name, Object) 8230 DECL_ACCESSORS(signature, Object) 8231 DECL_ACCESSORS(instance_call_handler, Object) 8232 DECL_ACCESSORS(access_check_info, Object) 8233 DECL_ACCESSORS(flag, Smi) 8234 8235 // Following properties use flag bits. 8236 DECL_BOOLEAN_ACCESSORS(hidden_prototype) 8237 DECL_BOOLEAN_ACCESSORS(undetectable) 8238 // If the bit is set, object instances created by this function 8239 // requires access check. 8240 DECL_BOOLEAN_ACCESSORS(needs_access_check) 8241 DECL_BOOLEAN_ACCESSORS(read_only_prototype) 8242 8243 static inline FunctionTemplateInfo* cast(Object* obj); 8244 8245 #ifdef OBJECT_PRINT FunctionTemplateInfoPrint()8246 inline void FunctionTemplateInfoPrint() { 8247 FunctionTemplateInfoPrint(stdout); 8248 } 8249 void FunctionTemplateInfoPrint(FILE* out); 8250 #endif 8251 #ifdef DEBUG 8252 void FunctionTemplateInfoVerify(); 8253 #endif 8254 8255 static const int kSerialNumberOffset = TemplateInfo::kHeaderSize; 8256 static const int kCallCodeOffset = kSerialNumberOffset + kPointerSize; 8257 static const int kPropertyAccessorsOffset = kCallCodeOffset + kPointerSize; 8258 static const int kPrototypeTemplateOffset = 8259 kPropertyAccessorsOffset + kPointerSize; 8260 static const int kParentTemplateOffset = 8261 kPrototypeTemplateOffset + kPointerSize; 8262 static const int kNamedPropertyHandlerOffset = 8263 kParentTemplateOffset + kPointerSize; 8264 static const int kIndexedPropertyHandlerOffset = 8265 kNamedPropertyHandlerOffset + kPointerSize; 8266 static const int kInstanceTemplateOffset = 8267 kIndexedPropertyHandlerOffset + kPointerSize; 8268 static const int kClassNameOffset = kInstanceTemplateOffset + kPointerSize; 8269 static const int kSignatureOffset = kClassNameOffset + kPointerSize; 8270 static const int kInstanceCallHandlerOffset = kSignatureOffset + kPointerSize; 8271 static const int kAccessCheckInfoOffset = 8272 kInstanceCallHandlerOffset + kPointerSize; 8273 static const int kFlagOffset = kAccessCheckInfoOffset + kPointerSize; 8274 static const int kSize = kFlagOffset + kPointerSize; 8275 8276 private: 8277 // Bit position in the flag, from least significant bit position. 8278 static const int kHiddenPrototypeBit = 0; 8279 static const int kUndetectableBit = 1; 8280 static const int kNeedsAccessCheckBit = 2; 8281 static const int kReadOnlyPrototypeBit = 3; 8282 8283 DISALLOW_IMPLICIT_CONSTRUCTORS(FunctionTemplateInfo); 8284 }; 8285 8286 8287 class ObjectTemplateInfo: public TemplateInfo { 8288 public: 8289 DECL_ACCESSORS(constructor, Object) 8290 DECL_ACCESSORS(internal_field_count, Object) 8291 8292 static inline ObjectTemplateInfo* cast(Object* obj); 8293 8294 #ifdef OBJECT_PRINT ObjectTemplateInfoPrint()8295 inline void ObjectTemplateInfoPrint() { 8296 ObjectTemplateInfoPrint(stdout); 8297 } 8298 void ObjectTemplateInfoPrint(FILE* out); 8299 #endif 8300 #ifdef DEBUG 8301 void ObjectTemplateInfoVerify(); 8302 #endif 8303 8304 static const int kConstructorOffset = TemplateInfo::kHeaderSize; 8305 static const int kInternalFieldCountOffset = 8306 kConstructorOffset + kPointerSize; 8307 static const int kSize = kInternalFieldCountOffset + kPointerSize; 8308 }; 8309 8310 8311 class SignatureInfo: public Struct { 8312 public: 8313 DECL_ACCESSORS(receiver, Object) 8314 DECL_ACCESSORS(args, Object) 8315 8316 static inline SignatureInfo* cast(Object* obj); 8317 8318 #ifdef OBJECT_PRINT SignatureInfoPrint()8319 inline void SignatureInfoPrint() { 8320 SignatureInfoPrint(stdout); 8321 } 8322 void SignatureInfoPrint(FILE* out); 8323 #endif 8324 #ifdef DEBUG 8325 void SignatureInfoVerify(); 8326 #endif 8327 8328 static const int kReceiverOffset = Struct::kHeaderSize; 8329 static const int kArgsOffset = kReceiverOffset + kPointerSize; 8330 static const int kSize = kArgsOffset + kPointerSize; 8331 8332 private: 8333 DISALLOW_IMPLICIT_CONSTRUCTORS(SignatureInfo); 8334 }; 8335 8336 8337 class TypeSwitchInfo: public Struct { 8338 public: 8339 DECL_ACCESSORS(types, Object) 8340 8341 static inline TypeSwitchInfo* cast(Object* obj); 8342 8343 #ifdef OBJECT_PRINT TypeSwitchInfoPrint()8344 inline void TypeSwitchInfoPrint() { 8345 TypeSwitchInfoPrint(stdout); 8346 } 8347 void TypeSwitchInfoPrint(FILE* out); 8348 #endif 8349 #ifdef DEBUG 8350 void TypeSwitchInfoVerify(); 8351 #endif 8352 8353 static const int kTypesOffset = Struct::kHeaderSize; 8354 static const int kSize = kTypesOffset + kPointerSize; 8355 }; 8356 8357 8358 #ifdef ENABLE_DEBUGGER_SUPPORT 8359 // The DebugInfo class holds additional information for a function being 8360 // debugged. 8361 class DebugInfo: public Struct { 8362 public: 8363 // The shared function info for the source being debugged. 8364 DECL_ACCESSORS(shared, SharedFunctionInfo) 8365 // Code object for the original code. 8366 DECL_ACCESSORS(original_code, Code) 8367 // Code object for the patched code. This code object is the code object 8368 // currently active for the function. 8369 DECL_ACCESSORS(code, Code) 8370 // Fixed array holding status information for each active break point. 8371 DECL_ACCESSORS(break_points, FixedArray) 8372 8373 // Check if there is a break point at a code position. 8374 bool HasBreakPoint(int code_position); 8375 // Get the break point info object for a code position. 8376 Object* GetBreakPointInfo(int code_position); 8377 // Clear a break point. 8378 static void ClearBreakPoint(Handle<DebugInfo> debug_info, 8379 int code_position, 8380 Handle<Object> break_point_object); 8381 // Set a break point. 8382 static void SetBreakPoint(Handle<DebugInfo> debug_info, int code_position, 8383 int source_position, int statement_position, 8384 Handle<Object> break_point_object); 8385 // Get the break point objects for a code position. 8386 Object* GetBreakPointObjects(int code_position); 8387 // Find the break point info holding this break point object. 8388 static Object* FindBreakPointInfo(Handle<DebugInfo> debug_info, 8389 Handle<Object> break_point_object); 8390 // Get the number of break points for this function. 8391 int GetBreakPointCount(); 8392 8393 static inline DebugInfo* cast(Object* obj); 8394 8395 #ifdef OBJECT_PRINT DebugInfoPrint()8396 inline void DebugInfoPrint() { 8397 DebugInfoPrint(stdout); 8398 } 8399 void DebugInfoPrint(FILE* out); 8400 #endif 8401 #ifdef DEBUG 8402 void DebugInfoVerify(); 8403 #endif 8404 8405 static const int kSharedFunctionInfoIndex = Struct::kHeaderSize; 8406 static const int kOriginalCodeIndex = kSharedFunctionInfoIndex + kPointerSize; 8407 static const int kPatchedCodeIndex = kOriginalCodeIndex + kPointerSize; 8408 static const int kActiveBreakPointsCountIndex = 8409 kPatchedCodeIndex + kPointerSize; 8410 static const int kBreakPointsStateIndex = 8411 kActiveBreakPointsCountIndex + kPointerSize; 8412 static const int kSize = kBreakPointsStateIndex + kPointerSize; 8413 8414 private: 8415 static const int kNoBreakPointInfo = -1; 8416 8417 // Lookup the index in the break_points array for a code position. 8418 int GetBreakPointInfoIndex(int code_position); 8419 8420 DISALLOW_IMPLICIT_CONSTRUCTORS(DebugInfo); 8421 }; 8422 8423 8424 // The BreakPointInfo class holds information for break points set in a 8425 // function. The DebugInfo object holds a BreakPointInfo object for each code 8426 // position with one or more break points. 8427 class BreakPointInfo: public Struct { 8428 public: 8429 // The position in the code for the break point. 8430 DECL_ACCESSORS(code_position, Smi) 8431 // The position in the source for the break position. 8432 DECL_ACCESSORS(source_position, Smi) 8433 // The position in the source for the last statement before this break 8434 // position. 8435 DECL_ACCESSORS(statement_position, Smi) 8436 // List of related JavaScript break points. 8437 DECL_ACCESSORS(break_point_objects, Object) 8438 8439 // Removes a break point. 8440 static void ClearBreakPoint(Handle<BreakPointInfo> info, 8441 Handle<Object> break_point_object); 8442 // Set a break point. 8443 static void SetBreakPoint(Handle<BreakPointInfo> info, 8444 Handle<Object> break_point_object); 8445 // Check if break point info has this break point object. 8446 static bool HasBreakPointObject(Handle<BreakPointInfo> info, 8447 Handle<Object> break_point_object); 8448 // Get the number of break points for this code position. 8449 int GetBreakPointCount(); 8450 8451 static inline BreakPointInfo* cast(Object* obj); 8452 8453 #ifdef OBJECT_PRINT BreakPointInfoPrint()8454 inline void BreakPointInfoPrint() { 8455 BreakPointInfoPrint(stdout); 8456 } 8457 void BreakPointInfoPrint(FILE* out); 8458 #endif 8459 #ifdef DEBUG 8460 void BreakPointInfoVerify(); 8461 #endif 8462 8463 static const int kCodePositionIndex = Struct::kHeaderSize; 8464 static const int kSourcePositionIndex = kCodePositionIndex + kPointerSize; 8465 static const int kStatementPositionIndex = 8466 kSourcePositionIndex + kPointerSize; 8467 static const int kBreakPointObjectsIndex = 8468 kStatementPositionIndex + kPointerSize; 8469 static const int kSize = kBreakPointObjectsIndex + kPointerSize; 8470 8471 private: 8472 DISALLOW_IMPLICIT_CONSTRUCTORS(BreakPointInfo); 8473 }; 8474 #endif // ENABLE_DEBUGGER_SUPPORT 8475 8476 8477 #undef DECL_BOOLEAN_ACCESSORS 8478 #undef DECL_ACCESSORS 8479 8480 #define VISITOR_SYNCHRONIZATION_TAGS_LIST(V) \ 8481 V(kSymbolTable, "symbol_table", "(Symbols)") \ 8482 V(kExternalStringsTable, "external_strings_table", "(External strings)") \ 8483 V(kStrongRootList, "strong_root_list", "(Strong roots)") \ 8484 V(kSymbol, "symbol", "(Symbol)") \ 8485 V(kBootstrapper, "bootstrapper", "(Bootstrapper)") \ 8486 V(kTop, "top", "(Isolate)") \ 8487 V(kRelocatable, "relocatable", "(Relocatable)") \ 8488 V(kDebug, "debug", "(Debugger)") \ 8489 V(kCompilationCache, "compilationcache", "(Compilation cache)") \ 8490 V(kHandleScope, "handlescope", "(Handle scope)") \ 8491 V(kBuiltins, "builtins", "(Builtins)") \ 8492 V(kGlobalHandles, "globalhandles", "(Global handles)") \ 8493 V(kThreadManager, "threadmanager", "(Thread manager)") \ 8494 V(kExtensions, "Extensions", "(Extensions)") 8495 8496 class VisitorSynchronization : public AllStatic { 8497 public: 8498 #define DECLARE_ENUM(enum_item, ignore1, ignore2) enum_item, 8499 enum SyncTag { 8500 VISITOR_SYNCHRONIZATION_TAGS_LIST(DECLARE_ENUM) 8501 kNumberOfSyncTags 8502 }; 8503 #undef DECLARE_ENUM 8504 8505 static const char* const kTags[kNumberOfSyncTags]; 8506 static const char* const kTagNames[kNumberOfSyncTags]; 8507 }; 8508 8509 // Abstract base class for visiting, and optionally modifying, the 8510 // pointers contained in Objects. Used in GC and serialization/deserialization. 8511 class ObjectVisitor BASE_EMBEDDED { 8512 public: ~ObjectVisitor()8513 virtual ~ObjectVisitor() {} 8514 8515 // Visits a contiguous arrays of pointers in the half-open range 8516 // [start, end). Any or all of the values may be modified on return. 8517 virtual void VisitPointers(Object** start, Object** end) = 0; 8518 8519 // To allow lazy clearing of inline caches the visitor has 8520 // a rich interface for iterating over Code objects.. 8521 8522 // Visits a code target in the instruction stream. 8523 virtual void VisitCodeTarget(RelocInfo* rinfo); 8524 8525 // Visits a code entry in a JS function. 8526 virtual void VisitCodeEntry(Address entry_address); 8527 8528 // Visits a global property cell reference in the instruction stream. 8529 virtual void VisitGlobalPropertyCell(RelocInfo* rinfo); 8530 8531 // Visits a runtime entry in the instruction stream. VisitRuntimeEntry(RelocInfo * rinfo)8532 virtual void VisitRuntimeEntry(RelocInfo* rinfo) {} 8533 8534 // Visits the resource of an ASCII or two-byte string. VisitExternalAsciiString(v8::String::ExternalAsciiStringResource ** resource)8535 virtual void VisitExternalAsciiString( 8536 v8::String::ExternalAsciiStringResource** resource) {} VisitExternalTwoByteString(v8::String::ExternalStringResource ** resource)8537 virtual void VisitExternalTwoByteString( 8538 v8::String::ExternalStringResource** resource) {} 8539 8540 // Visits a debug call target in the instruction stream. 8541 virtual void VisitDebugTarget(RelocInfo* rinfo); 8542 8543 // Handy shorthand for visiting a single pointer. VisitPointer(Object ** p)8544 virtual void VisitPointer(Object** p) { VisitPointers(p, p + 1); } 8545 8546 // Visit pointer embedded into a code object. 8547 virtual void VisitEmbeddedPointer(RelocInfo* rinfo); 8548 VisitSharedFunctionInfo(SharedFunctionInfo * shared)8549 virtual void VisitSharedFunctionInfo(SharedFunctionInfo* shared) {} 8550 8551 // Visits a contiguous arrays of external references (references to the C++ 8552 // heap) in the half-open range [start, end). Any or all of the values 8553 // may be modified on return. VisitExternalReferences(Address * start,Address * end)8554 virtual void VisitExternalReferences(Address* start, Address* end) {} 8555 8556 virtual void VisitExternalReference(RelocInfo* rinfo); 8557 VisitExternalReference(Address * p)8558 inline void VisitExternalReference(Address* p) { 8559 VisitExternalReferences(p, p + 1); 8560 } 8561 8562 // Visits a handle that has an embedder-assigned class ID. VisitEmbedderReference(Object ** p,uint16_t class_id)8563 virtual void VisitEmbedderReference(Object** p, uint16_t class_id) {} 8564 8565 // Intended for serialization/deserialization checking: insert, or 8566 // check for the presence of, a tag at this position in the stream. 8567 // Also used for marking up GC roots in heap snapshots. Synchronize(VisitorSynchronization::SyncTag tag)8568 virtual void Synchronize(VisitorSynchronization::SyncTag tag) {} 8569 }; 8570 8571 8572 class StructBodyDescriptor : public 8573 FlexibleBodyDescriptor<HeapObject::kHeaderSize> { 8574 public: SizeOf(Map * map,HeapObject * object)8575 static inline int SizeOf(Map* map, HeapObject* object) { 8576 return map->instance_size(); 8577 } 8578 }; 8579 8580 8581 // BooleanBit is a helper class for setting and getting a bit in an 8582 // integer or Smi. 8583 class BooleanBit : public AllStatic { 8584 public: get(Smi * smi,int bit_position)8585 static inline bool get(Smi* smi, int bit_position) { 8586 return get(smi->value(), bit_position); 8587 } 8588 get(int value,int bit_position)8589 static inline bool get(int value, int bit_position) { 8590 return (value & (1 << bit_position)) != 0; 8591 } 8592 set(Smi * smi,int bit_position,bool v)8593 static inline Smi* set(Smi* smi, int bit_position, bool v) { 8594 return Smi::FromInt(set(smi->value(), bit_position, v)); 8595 } 8596 set(int value,int bit_position,bool v)8597 static inline int set(int value, int bit_position, bool v) { 8598 if (v) { 8599 value |= (1 << bit_position); 8600 } else { 8601 value &= ~(1 << bit_position); 8602 } 8603 return value; 8604 } 8605 }; 8606 8607 } } // namespace v8::internal 8608 8609 #endif // V8_OBJECTS_H_ 8610