1 // Copyright 2011 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 "builtins.h" 32 #include "smart-pointer.h" 33 #include "unicode-inl.h" 34 #if V8_TARGET_ARCH_ARM 35 #include "arm/constants-arm.h" 36 #elif V8_TARGET_ARCH_MIPS 37 #include "mips/constants-mips.h" 38 #endif 39 40 // 41 // Most object types in the V8 JavaScript are described in this file. 42 // 43 // Inheritance hierarchy: 44 // - MaybeObject (an object or a failure) 45 // - Failure (immediate for marking failed operation) 46 // - Object 47 // - Smi (immediate small integer) 48 // - HeapObject (superclass for everything allocated in the heap) 49 // - JSObject 50 // - JSArray 51 // - JSRegExp 52 // - JSFunction 53 // - GlobalObject 54 // - JSGlobalObject 55 // - JSBuiltinsObject 56 // - JSGlobalProxy 57 // - JSValue 58 // - JSMessageObject 59 // - ByteArray 60 // - ExternalArray 61 // - ExternalPixelArray 62 // - ExternalByteArray 63 // - ExternalUnsignedByteArray 64 // - ExternalShortArray 65 // - ExternalUnsignedShortArray 66 // - ExternalIntArray 67 // - ExternalUnsignedIntArray 68 // - ExternalFloatArray 69 // - FixedArray 70 // - DescriptorArray 71 // - HashTable 72 // - Dictionary 73 // - SymbolTable 74 // - CompilationCacheTable 75 // - CodeCacheHashTable 76 // - MapCache 77 // - Context 78 // - JSFunctionResultCache 79 // - SerializedScopeInfo 80 // - String 81 // - SeqString 82 // - SeqAsciiString 83 // - SeqTwoByteString 84 // - ConsString 85 // - ExternalString 86 // - ExternalAsciiString 87 // - ExternalTwoByteString 88 // - HeapNumber 89 // - Code 90 // - Map 91 // - Oddball 92 // - Proxy 93 // - SharedFunctionInfo 94 // - Struct 95 // - AccessorInfo 96 // - AccessCheckInfo 97 // - InterceptorInfo 98 // - CallHandlerInfo 99 // - TemplateInfo 100 // - FunctionTemplateInfo 101 // - ObjectTemplateInfo 102 // - Script 103 // - SignatureInfo 104 // - TypeSwitchInfo 105 // - DebugInfo 106 // - BreakPointInfo 107 // - CodeCache 108 // 109 // Formats of Object*: 110 // Smi: [31 bit signed int] 0 111 // HeapObject: [32 bit direct pointer] (4 byte aligned) | 01 112 // Failure: [30 bit signed int] 11 113 114 // Ecma-262 3rd 8.6.1 115 enum PropertyAttributes { 116 NONE = v8::None, 117 READ_ONLY = v8::ReadOnly, 118 DONT_ENUM = v8::DontEnum, 119 DONT_DELETE = v8::DontDelete, 120 ABSENT = 16 // Used in runtime to indicate a property is absent. 121 // ABSENT can never be stored in or returned from a descriptor's attributes 122 // bitfield. It is only used as a return value meaning the attributes of 123 // a non-existent property. 124 }; 125 126 namespace v8 { 127 namespace internal { 128 129 130 // PropertyDetails captures type and attributes for a property. 131 // They are used both in property dictionaries and instance descriptors. 132 class PropertyDetails BASE_EMBEDDED { 133 public: 134 135 PropertyDetails(PropertyAttributes attributes, 136 PropertyType type, 137 int index = 0) { 138 ASSERT(type != EXTERNAL_ARRAY_TRANSITION); 139 ASSERT(TypeField::is_valid(type)); 140 ASSERT(AttributesField::is_valid(attributes)); 141 ASSERT(StorageField::is_valid(index)); 142 143 value_ = TypeField::encode(type) 144 | AttributesField::encode(attributes) 145 | StorageField::encode(index); 146 147 ASSERT(type == this->type()); 148 ASSERT(attributes == this->attributes()); 149 ASSERT(index == this->index()); 150 } 151 152 PropertyDetails(PropertyAttributes attributes, 153 PropertyType type, 154 ExternalArrayType array_type) { 155 ASSERT(type == EXTERNAL_ARRAY_TRANSITION); 156 ASSERT(TypeField::is_valid(type)); 157 ASSERT(AttributesField::is_valid(attributes)); 158 ASSERT(StorageField::is_valid(static_cast<int>(array_type))); 159 160 value_ = TypeField::encode(type) 161 | AttributesField::encode(attributes) 162 | StorageField::encode(static_cast<int>(array_type)); 163 164 ASSERT(type == this->type()); 165 ASSERT(attributes == this->attributes()); 166 ASSERT(array_type == this->array_type()); 167 } 168 169 // Conversion for storing details as Object*. 170 explicit inline PropertyDetails(Smi* smi); 171 inline Smi* AsSmi(); 172 173 PropertyType type() { return TypeField::decode(value_); } 174 175 bool IsTransition() { 176 PropertyType t = type(); 177 ASSERT(t != INTERCEPTOR); 178 return t == MAP_TRANSITION || t == CONSTANT_TRANSITION || 179 t == EXTERNAL_ARRAY_TRANSITION; 180 } 181 182 bool IsProperty() { 183 return type() < FIRST_PHANTOM_PROPERTY_TYPE; 184 } 185 186 PropertyAttributes attributes() { return AttributesField::decode(value_); } 187 188 int index() { return StorageField::decode(value_); } 189 190 ExternalArrayType array_type() { 191 ASSERT(type() == EXTERNAL_ARRAY_TRANSITION); 192 return static_cast<ExternalArrayType>(StorageField::decode(value_)); 193 } 194 195 inline PropertyDetails AsDeleted(); 196 197 static bool IsValidIndex(int index) { 198 return StorageField::is_valid(index); 199 } 200 201 bool IsReadOnly() { return (attributes() & READ_ONLY) != 0; } 202 bool IsDontDelete() { return (attributes() & DONT_DELETE) != 0; } 203 bool IsDontEnum() { return (attributes() & DONT_ENUM) != 0; } 204 bool IsDeleted() { return DeletedField::decode(value_) != 0;} 205 206 // Bit fields in value_ (type, shift, size). Must be public so the 207 // constants can be embedded in generated code. 208 class TypeField: public BitField<PropertyType, 0, 4> {}; 209 class AttributesField: public BitField<PropertyAttributes, 4, 3> {}; 210 class DeletedField: public BitField<uint32_t, 7, 1> {}; 211 class StorageField: public BitField<uint32_t, 8, 32-8> {}; 212 213 static const int kInitialIndex = 1; 214 private: 215 uint32_t value_; 216 }; 217 218 219 // Setter that skips the write barrier if mode is SKIP_WRITE_BARRIER. 220 enum WriteBarrierMode { SKIP_WRITE_BARRIER, UPDATE_WRITE_BARRIER }; 221 222 223 // PropertyNormalizationMode is used to specify whether to keep 224 // inobject properties when normalizing properties of a JSObject. 225 enum PropertyNormalizationMode { 226 CLEAR_INOBJECT_PROPERTIES, 227 KEEP_INOBJECT_PROPERTIES 228 }; 229 230 231 // NormalizedMapSharingMode is used to specify whether a map may be shared 232 // by different objects with normalized properties. 233 enum NormalizedMapSharingMode { 234 UNIQUE_NORMALIZED_MAP, 235 SHARED_NORMALIZED_MAP 236 }; 237 238 239 // Instance size sentinel for objects of variable size. 240 static const int kVariableSizeSentinel = 0; 241 242 243 // All Maps have a field instance_type containing a InstanceType. 244 // It describes the type of the instances. 245 // 246 // As an example, a JavaScript object is a heap object and its map 247 // instance_type is JS_OBJECT_TYPE. 248 // 249 // The names of the string instance types are intended to systematically 250 // mirror their encoding in the instance_type field of the map. The default 251 // encoding is considered TWO_BYTE. It is not mentioned in the name. ASCII 252 // encoding is mentioned explicitly in the name. Likewise, the default 253 // representation is considered sequential. It is not mentioned in the 254 // name. The other representations (eg, CONS, EXTERNAL) are explicitly 255 // mentioned. Finally, the string is either a SYMBOL_TYPE (if it is a 256 // symbol) or a STRING_TYPE (if it is not a symbol). 257 // 258 // NOTE: The following things are some that depend on the string types having 259 // instance_types that are less than those of all other types: 260 // HeapObject::Size, HeapObject::IterateBody, the typeof operator, and 261 // Object::IsString. 262 // 263 // NOTE: Everything following JS_VALUE_TYPE is considered a 264 // JSObject for GC purposes. The first four entries here have typeof 265 // 'object', whereas JS_FUNCTION_TYPE has typeof 'function'. 266 #define INSTANCE_TYPE_LIST_ALL(V) \ 267 V(SYMBOL_TYPE) \ 268 V(ASCII_SYMBOL_TYPE) \ 269 V(CONS_SYMBOL_TYPE) \ 270 V(CONS_ASCII_SYMBOL_TYPE) \ 271 V(EXTERNAL_SYMBOL_TYPE) \ 272 V(EXTERNAL_SYMBOL_WITH_ASCII_DATA_TYPE) \ 273 V(EXTERNAL_ASCII_SYMBOL_TYPE) \ 274 V(STRING_TYPE) \ 275 V(ASCII_STRING_TYPE) \ 276 V(CONS_STRING_TYPE) \ 277 V(CONS_ASCII_STRING_TYPE) \ 278 V(EXTERNAL_STRING_TYPE) \ 279 V(EXTERNAL_STRING_WITH_ASCII_DATA_TYPE) \ 280 V(EXTERNAL_ASCII_STRING_TYPE) \ 281 V(PRIVATE_EXTERNAL_ASCII_STRING_TYPE) \ 282 \ 283 V(MAP_TYPE) \ 284 V(CODE_TYPE) \ 285 V(ODDBALL_TYPE) \ 286 V(JS_GLOBAL_PROPERTY_CELL_TYPE) \ 287 \ 288 V(HEAP_NUMBER_TYPE) \ 289 V(PROXY_TYPE) \ 290 V(BYTE_ARRAY_TYPE) \ 291 /* Note: the order of these external array */ \ 292 /* types is relied upon in */ \ 293 /* Object::IsExternalArray(). */ \ 294 V(EXTERNAL_BYTE_ARRAY_TYPE) \ 295 V(EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE) \ 296 V(EXTERNAL_SHORT_ARRAY_TYPE) \ 297 V(EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE) \ 298 V(EXTERNAL_INT_ARRAY_TYPE) \ 299 V(EXTERNAL_UNSIGNED_INT_ARRAY_TYPE) \ 300 V(EXTERNAL_FLOAT_ARRAY_TYPE) \ 301 V(EXTERNAL_PIXEL_ARRAY_TYPE) \ 302 V(FILLER_TYPE) \ 303 \ 304 V(ACCESSOR_INFO_TYPE) \ 305 V(ACCESS_CHECK_INFO_TYPE) \ 306 V(INTERCEPTOR_INFO_TYPE) \ 307 V(CALL_HANDLER_INFO_TYPE) \ 308 V(FUNCTION_TEMPLATE_INFO_TYPE) \ 309 V(OBJECT_TEMPLATE_INFO_TYPE) \ 310 V(SIGNATURE_INFO_TYPE) \ 311 V(TYPE_SWITCH_INFO_TYPE) \ 312 V(SCRIPT_TYPE) \ 313 V(CODE_CACHE_TYPE) \ 314 \ 315 V(FIXED_ARRAY_TYPE) \ 316 V(SHARED_FUNCTION_INFO_TYPE) \ 317 \ 318 V(JS_MESSAGE_OBJECT_TYPE) \ 319 \ 320 V(JS_VALUE_TYPE) \ 321 V(JS_OBJECT_TYPE) \ 322 V(JS_CONTEXT_EXTENSION_OBJECT_TYPE) \ 323 V(JS_GLOBAL_OBJECT_TYPE) \ 324 V(JS_BUILTINS_OBJECT_TYPE) \ 325 V(JS_GLOBAL_PROXY_TYPE) \ 326 V(JS_ARRAY_TYPE) \ 327 V(JS_REGEXP_TYPE) \ 328 \ 329 V(JS_FUNCTION_TYPE) \ 330 331 #ifdef ENABLE_DEBUGGER_SUPPORT 332 #define INSTANCE_TYPE_LIST_DEBUGGER(V) \ 333 V(DEBUG_INFO_TYPE) \ 334 V(BREAK_POINT_INFO_TYPE) 335 #else 336 #define INSTANCE_TYPE_LIST_DEBUGGER(V) 337 #endif 338 339 #define INSTANCE_TYPE_LIST(V) \ 340 INSTANCE_TYPE_LIST_ALL(V) \ 341 INSTANCE_TYPE_LIST_DEBUGGER(V) 342 343 344 // Since string types are not consecutive, this macro is used to 345 // iterate over them. 346 #define STRING_TYPE_LIST(V) \ 347 V(SYMBOL_TYPE, \ 348 kVariableSizeSentinel, \ 349 symbol, \ 350 Symbol) \ 351 V(ASCII_SYMBOL_TYPE, \ 352 kVariableSizeSentinel, \ 353 ascii_symbol, \ 354 AsciiSymbol) \ 355 V(CONS_SYMBOL_TYPE, \ 356 ConsString::kSize, \ 357 cons_symbol, \ 358 ConsSymbol) \ 359 V(CONS_ASCII_SYMBOL_TYPE, \ 360 ConsString::kSize, \ 361 cons_ascii_symbol, \ 362 ConsAsciiSymbol) \ 363 V(EXTERNAL_SYMBOL_TYPE, \ 364 ExternalTwoByteString::kSize, \ 365 external_symbol, \ 366 ExternalSymbol) \ 367 V(EXTERNAL_SYMBOL_WITH_ASCII_DATA_TYPE, \ 368 ExternalTwoByteString::kSize, \ 369 external_symbol_with_ascii_data, \ 370 ExternalSymbolWithAsciiData) \ 371 V(EXTERNAL_ASCII_SYMBOL_TYPE, \ 372 ExternalAsciiString::kSize, \ 373 external_ascii_symbol, \ 374 ExternalAsciiSymbol) \ 375 V(STRING_TYPE, \ 376 kVariableSizeSentinel, \ 377 string, \ 378 String) \ 379 V(ASCII_STRING_TYPE, \ 380 kVariableSizeSentinel, \ 381 ascii_string, \ 382 AsciiString) \ 383 V(CONS_STRING_TYPE, \ 384 ConsString::kSize, \ 385 cons_string, \ 386 ConsString) \ 387 V(CONS_ASCII_STRING_TYPE, \ 388 ConsString::kSize, \ 389 cons_ascii_string, \ 390 ConsAsciiString) \ 391 V(EXTERNAL_STRING_TYPE, \ 392 ExternalTwoByteString::kSize, \ 393 external_string, \ 394 ExternalString) \ 395 V(EXTERNAL_STRING_WITH_ASCII_DATA_TYPE, \ 396 ExternalTwoByteString::kSize, \ 397 external_string_with_ascii_data, \ 398 ExternalStringWithAsciiData) \ 399 V(EXTERNAL_ASCII_STRING_TYPE, \ 400 ExternalAsciiString::kSize, \ 401 external_ascii_string, \ 402 ExternalAsciiString) 403 404 // A struct is a simple object a set of object-valued fields. Including an 405 // object type in this causes the compiler to generate most of the boilerplate 406 // code for the class including allocation and garbage collection routines, 407 // casts and predicates. All you need to define is the class, methods and 408 // object verification routines. Easy, no? 409 // 410 // Note that for subtle reasons related to the ordering or numerical values of 411 // type tags, elements in this list have to be added to the INSTANCE_TYPE_LIST 412 // manually. 413 #define STRUCT_LIST_ALL(V) \ 414 V(ACCESSOR_INFO, AccessorInfo, accessor_info) \ 415 V(ACCESS_CHECK_INFO, AccessCheckInfo, access_check_info) \ 416 V(INTERCEPTOR_INFO, InterceptorInfo, interceptor_info) \ 417 V(CALL_HANDLER_INFO, CallHandlerInfo, call_handler_info) \ 418 V(FUNCTION_TEMPLATE_INFO, FunctionTemplateInfo, function_template_info) \ 419 V(OBJECT_TEMPLATE_INFO, ObjectTemplateInfo, object_template_info) \ 420 V(SIGNATURE_INFO, SignatureInfo, signature_info) \ 421 V(TYPE_SWITCH_INFO, TypeSwitchInfo, type_switch_info) \ 422 V(SCRIPT, Script, script) \ 423 V(CODE_CACHE, CodeCache, code_cache) 424 425 #ifdef ENABLE_DEBUGGER_SUPPORT 426 #define STRUCT_LIST_DEBUGGER(V) \ 427 V(DEBUG_INFO, DebugInfo, debug_info) \ 428 V(BREAK_POINT_INFO, BreakPointInfo, break_point_info) 429 #else 430 #define STRUCT_LIST_DEBUGGER(V) 431 #endif 432 433 #define STRUCT_LIST(V) \ 434 STRUCT_LIST_ALL(V) \ 435 STRUCT_LIST_DEBUGGER(V) 436 437 // We use the full 8 bits of the instance_type field to encode heap object 438 // instance types. The high-order bit (bit 7) is set if the object is not a 439 // string, and cleared if it is a string. 440 const uint32_t kIsNotStringMask = 0x80; 441 const uint32_t kStringTag = 0x0; 442 const uint32_t kNotStringTag = 0x80; 443 444 // Bit 6 indicates that the object is a symbol (if set) or not (if cleared). 445 // There are not enough types that the non-string types (with bit 7 set) can 446 // have bit 6 set too. 447 const uint32_t kIsSymbolMask = 0x40; 448 const uint32_t kNotSymbolTag = 0x0; 449 const uint32_t kSymbolTag = 0x40; 450 451 // If bit 7 is clear then bit 2 indicates whether the string consists of 452 // two-byte characters or one-byte characters. 453 const uint32_t kStringEncodingMask = 0x4; 454 const uint32_t kTwoByteStringTag = 0x0; 455 const uint32_t kAsciiStringTag = 0x4; 456 457 // If bit 7 is clear, the low-order 2 bits indicate the representation 458 // of the string. 459 const uint32_t kStringRepresentationMask = 0x03; 460 enum StringRepresentationTag { 461 kSeqStringTag = 0x0, 462 kConsStringTag = 0x1, 463 kExternalStringTag = 0x2 464 }; 465 const uint32_t kIsConsStringMask = 0x1; 466 467 // If bit 7 is clear, then bit 3 indicates whether this two-byte 468 // string actually contains ascii data. 469 const uint32_t kAsciiDataHintMask = 0x08; 470 const uint32_t kAsciiDataHintTag = 0x08; 471 472 473 // A ConsString with an empty string as the right side is a candidate 474 // for being shortcut by the garbage collector unless it is a 475 // symbol. It's not common to have non-flat symbols, so we do not 476 // shortcut them thereby avoiding turning symbols into strings. See 477 // heap.cc and mark-compact.cc. 478 const uint32_t kShortcutTypeMask = 479 kIsNotStringMask | 480 kIsSymbolMask | 481 kStringRepresentationMask; 482 const uint32_t kShortcutTypeTag = kConsStringTag; 483 484 485 enum InstanceType { 486 // String types. 487 // FIRST_STRING_TYPE 488 SYMBOL_TYPE = kTwoByteStringTag | kSymbolTag | kSeqStringTag, 489 ASCII_SYMBOL_TYPE = kAsciiStringTag | kSymbolTag | kSeqStringTag, 490 CONS_SYMBOL_TYPE = kTwoByteStringTag | kSymbolTag | kConsStringTag, 491 CONS_ASCII_SYMBOL_TYPE = kAsciiStringTag | kSymbolTag | kConsStringTag, 492 EXTERNAL_SYMBOL_TYPE = kTwoByteStringTag | kSymbolTag | kExternalStringTag, 493 EXTERNAL_SYMBOL_WITH_ASCII_DATA_TYPE = 494 kTwoByteStringTag | kSymbolTag | kExternalStringTag | kAsciiDataHintTag, 495 EXTERNAL_ASCII_SYMBOL_TYPE = 496 kAsciiStringTag | kSymbolTag | kExternalStringTag, 497 STRING_TYPE = kTwoByteStringTag | kSeqStringTag, 498 ASCII_STRING_TYPE = kAsciiStringTag | kSeqStringTag, 499 CONS_STRING_TYPE = kTwoByteStringTag | kConsStringTag, 500 CONS_ASCII_STRING_TYPE = kAsciiStringTag | kConsStringTag, 501 EXTERNAL_STRING_TYPE = kTwoByteStringTag | kExternalStringTag, 502 EXTERNAL_STRING_WITH_ASCII_DATA_TYPE = 503 kTwoByteStringTag | kExternalStringTag | kAsciiDataHintTag, 504 // LAST_STRING_TYPE 505 EXTERNAL_ASCII_STRING_TYPE = kAsciiStringTag | kExternalStringTag, 506 PRIVATE_EXTERNAL_ASCII_STRING_TYPE = EXTERNAL_ASCII_STRING_TYPE, 507 508 // Objects allocated in their own spaces (never in new space). 509 MAP_TYPE = kNotStringTag, // FIRST_NONSTRING_TYPE 510 CODE_TYPE, 511 ODDBALL_TYPE, 512 JS_GLOBAL_PROPERTY_CELL_TYPE, 513 514 // "Data", objects that cannot contain non-map-word pointers to heap 515 // objects. 516 HEAP_NUMBER_TYPE, 517 PROXY_TYPE, 518 BYTE_ARRAY_TYPE, 519 EXTERNAL_BYTE_ARRAY_TYPE, // FIRST_EXTERNAL_ARRAY_TYPE 520 EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE, 521 EXTERNAL_SHORT_ARRAY_TYPE, 522 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE, 523 EXTERNAL_INT_ARRAY_TYPE, 524 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE, 525 EXTERNAL_FLOAT_ARRAY_TYPE, 526 EXTERNAL_PIXEL_ARRAY_TYPE, // LAST_EXTERNAL_ARRAY_TYPE 527 FILLER_TYPE, // LAST_DATA_TYPE 528 529 // Structs. 530 ACCESSOR_INFO_TYPE, 531 ACCESS_CHECK_INFO_TYPE, 532 INTERCEPTOR_INFO_TYPE, 533 CALL_HANDLER_INFO_TYPE, 534 FUNCTION_TEMPLATE_INFO_TYPE, 535 OBJECT_TEMPLATE_INFO_TYPE, 536 SIGNATURE_INFO_TYPE, 537 TYPE_SWITCH_INFO_TYPE, 538 SCRIPT_TYPE, 539 CODE_CACHE_TYPE, 540 // The following two instance types are only used when ENABLE_DEBUGGER_SUPPORT 541 // is defined. However as include/v8.h contain some of the instance type 542 // constants always having them avoids them getting different numbers 543 // depending on whether ENABLE_DEBUGGER_SUPPORT is defined or not. 544 DEBUG_INFO_TYPE, 545 BREAK_POINT_INFO_TYPE, 546 547 FIXED_ARRAY_TYPE, 548 SHARED_FUNCTION_INFO_TYPE, 549 550 JS_MESSAGE_OBJECT_TYPE, 551 552 JS_VALUE_TYPE, // FIRST_JS_OBJECT_TYPE 553 JS_OBJECT_TYPE, 554 JS_CONTEXT_EXTENSION_OBJECT_TYPE, 555 JS_GLOBAL_OBJECT_TYPE, 556 JS_BUILTINS_OBJECT_TYPE, 557 JS_GLOBAL_PROXY_TYPE, 558 JS_ARRAY_TYPE, 559 560 JS_REGEXP_TYPE, // LAST_JS_OBJECT_TYPE, FIRST_FUNCTION_CLASS_TYPE 561 562 JS_FUNCTION_TYPE, 563 564 // Pseudo-types 565 FIRST_TYPE = 0x0, 566 LAST_TYPE = JS_FUNCTION_TYPE, 567 INVALID_TYPE = FIRST_TYPE - 1, 568 FIRST_NONSTRING_TYPE = MAP_TYPE, 569 FIRST_STRING_TYPE = FIRST_TYPE, 570 LAST_STRING_TYPE = FIRST_NONSTRING_TYPE - 1, 571 // Boundaries for testing for an external array. 572 FIRST_EXTERNAL_ARRAY_TYPE = EXTERNAL_BYTE_ARRAY_TYPE, 573 LAST_EXTERNAL_ARRAY_TYPE = EXTERNAL_PIXEL_ARRAY_TYPE, 574 // Boundary for promotion to old data space/old pointer space. 575 LAST_DATA_TYPE = FILLER_TYPE, 576 // Boundaries for testing the type is a JavaScript "object". Note that 577 // function objects are not counted as objects, even though they are 578 // implemented as such; only values whose typeof is "object" are included. 579 FIRST_JS_OBJECT_TYPE = JS_VALUE_TYPE, 580 LAST_JS_OBJECT_TYPE = JS_REGEXP_TYPE, 581 // RegExp objects have [[Class]] "function" because they are callable. 582 // All types from this type and above are objects with [[Class]] "function". 583 FIRST_FUNCTION_CLASS_TYPE = JS_REGEXP_TYPE 584 }; 585 586 static const int kExternalArrayTypeCount = LAST_EXTERNAL_ARRAY_TYPE - 587 FIRST_EXTERNAL_ARRAY_TYPE + 1; 588 589 STATIC_CHECK(JS_OBJECT_TYPE == Internals::kJSObjectType); 590 STATIC_CHECK(FIRST_NONSTRING_TYPE == Internals::kFirstNonstringType); 591 STATIC_CHECK(PROXY_TYPE == Internals::kProxyType); 592 593 594 enum CompareResult { 595 LESS = -1, 596 EQUAL = 0, 597 GREATER = 1, 598 599 NOT_EQUAL = GREATER 600 }; 601 602 603 #define DECL_BOOLEAN_ACCESSORS(name) \ 604 inline bool name(); \ 605 inline void set_##name(bool value); \ 606 607 608 #define DECL_ACCESSORS(name, type) \ 609 inline type* name(); \ 610 inline void set_##name(type* value, \ 611 WriteBarrierMode mode = UPDATE_WRITE_BARRIER); \ 612 613 614 class StringStream; 615 class ObjectVisitor; 616 class Failure; 617 618 struct ValueInfo : public Malloced { 619 ValueInfo() : type(FIRST_TYPE), ptr(NULL), str(NULL), number(0) { } 620 InstanceType type; 621 Object* ptr; 622 const char* str; 623 double number; 624 }; 625 626 627 // A template-ized version of the IsXXX functions. 628 template <class C> static inline bool Is(Object* obj); 629 630 631 class MaybeObject BASE_EMBEDDED { 632 public: 633 inline bool IsFailure(); 634 inline bool IsRetryAfterGC(); 635 inline bool IsOutOfMemory(); 636 inline bool IsException(); 637 INLINE(bool IsTheHole()); 638 inline bool ToObject(Object** obj) { 639 if (IsFailure()) return false; 640 *obj = reinterpret_cast<Object*>(this); 641 return true; 642 } 643 inline Failure* ToFailureUnchecked() { 644 ASSERT(IsFailure()); 645 return reinterpret_cast<Failure*>(this); 646 } 647 inline Object* ToObjectUnchecked() { 648 ASSERT(!IsFailure()); 649 return reinterpret_cast<Object*>(this); 650 } 651 inline Object* ToObjectChecked() { 652 CHECK(!IsFailure()); 653 return reinterpret_cast<Object*>(this); 654 } 655 656 template<typename T> 657 inline bool To(T** obj) { 658 if (IsFailure()) return false; 659 *obj = T::cast(reinterpret_cast<Object*>(this)); 660 return true; 661 } 662 663 #ifdef OBJECT_PRINT 664 // Prints this object with details. 665 inline void Print() { 666 Print(stdout); 667 }; 668 inline void PrintLn() { 669 PrintLn(stdout); 670 } 671 void Print(FILE* out); 672 void PrintLn(FILE* out); 673 #endif 674 #ifdef DEBUG 675 // Verifies the object. 676 void Verify(); 677 #endif 678 }; 679 680 681 #define OBJECT_TYPE_LIST(V) \ 682 V(Smi) \ 683 V(HeapObject) \ 684 V(Number) \ 685 686 #define HEAP_OBJECT_TYPE_LIST(V) \ 687 V(HeapNumber) \ 688 V(String) \ 689 V(Symbol) \ 690 V(SeqString) \ 691 V(ExternalString) \ 692 V(ConsString) \ 693 V(ExternalTwoByteString) \ 694 V(ExternalAsciiString) \ 695 V(SeqTwoByteString) \ 696 V(SeqAsciiString) \ 697 \ 698 V(ExternalArray) \ 699 V(ExternalByteArray) \ 700 V(ExternalUnsignedByteArray) \ 701 V(ExternalShortArray) \ 702 V(ExternalUnsignedShortArray) \ 703 V(ExternalIntArray) \ 704 V(ExternalUnsignedIntArray) \ 705 V(ExternalFloatArray) \ 706 V(ExternalPixelArray) \ 707 V(ByteArray) \ 708 V(JSObject) \ 709 V(JSContextExtensionObject) \ 710 V(Map) \ 711 V(DescriptorArray) \ 712 V(DeoptimizationInputData) \ 713 V(DeoptimizationOutputData) \ 714 V(FixedArray) \ 715 V(Context) \ 716 V(CatchContext) \ 717 V(GlobalContext) \ 718 V(JSFunction) \ 719 V(Code) \ 720 V(Oddball) \ 721 V(SharedFunctionInfo) \ 722 V(JSValue) \ 723 V(JSMessageObject) \ 724 V(StringWrapper) \ 725 V(Proxy) \ 726 V(Boolean) \ 727 V(JSArray) \ 728 V(JSRegExp) \ 729 V(HashTable) \ 730 V(Dictionary) \ 731 V(SymbolTable) \ 732 V(JSFunctionResultCache) \ 733 V(NormalizedMapCache) \ 734 V(CompilationCacheTable) \ 735 V(CodeCacheHashTable) \ 736 V(MapCache) \ 737 V(Primitive) \ 738 V(GlobalObject) \ 739 V(JSGlobalObject) \ 740 V(JSBuiltinsObject) \ 741 V(JSGlobalProxy) \ 742 V(UndetectableObject) \ 743 V(AccessCheckNeeded) \ 744 V(JSGlobalPropertyCell) \ 745 746 // Object is the abstract superclass for all classes in the 747 // object hierarchy. 748 // Object does not use any virtual functions to avoid the 749 // allocation of the C++ vtable. 750 // Since Smi and Failure are subclasses of Object no 751 // data members can be present in Object. 752 class Object : public MaybeObject { 753 public: 754 // Type testing. 755 #define IS_TYPE_FUNCTION_DECL(type_) inline bool Is##type_(); 756 OBJECT_TYPE_LIST(IS_TYPE_FUNCTION_DECL) 757 HEAP_OBJECT_TYPE_LIST(IS_TYPE_FUNCTION_DECL) 758 #undef IS_TYPE_FUNCTION_DECL 759 760 // Returns true if this object is an instance of the specified 761 // function template. 762 inline bool IsInstanceOf(FunctionTemplateInfo* type); 763 764 inline bool IsStruct(); 765 #define DECLARE_STRUCT_PREDICATE(NAME, Name, name) inline bool Is##Name(); 766 STRUCT_LIST(DECLARE_STRUCT_PREDICATE) 767 #undef DECLARE_STRUCT_PREDICATE 768 769 // Oddball testing. 770 INLINE(bool IsUndefined()); 771 INLINE(bool IsNull()); 772 INLINE(bool IsTheHole()); // Shadows MaybeObject's implementation. 773 INLINE(bool IsTrue()); 774 INLINE(bool IsFalse()); 775 inline bool IsArgumentsMarker(); 776 777 // Extract the number. 778 inline double Number(); 779 780 inline bool HasSpecificClassOf(String* name); 781 782 MUST_USE_RESULT MaybeObject* ToObject(); // ECMA-262 9.9. 783 Object* ToBoolean(); // ECMA-262 9.2. 784 785 // Convert to a JSObject if needed. 786 // global_context is used when creating wrapper object. 787 MUST_USE_RESULT MaybeObject* ToObject(Context* global_context); 788 789 // Converts this to a Smi if possible. 790 // Failure is returned otherwise. 791 MUST_USE_RESULT inline MaybeObject* ToSmi(); 792 793 void Lookup(String* name, LookupResult* result); 794 795 // Property access. 796 MUST_USE_RESULT inline MaybeObject* GetProperty(String* key); 797 MUST_USE_RESULT inline MaybeObject* GetProperty( 798 String* key, 799 PropertyAttributes* attributes); 800 MUST_USE_RESULT MaybeObject* GetPropertyWithReceiver( 801 Object* receiver, 802 String* key, 803 PropertyAttributes* attributes); 804 MUST_USE_RESULT MaybeObject* GetProperty(Object* receiver, 805 LookupResult* result, 806 String* key, 807 PropertyAttributes* attributes); 808 MUST_USE_RESULT MaybeObject* GetPropertyWithCallback(Object* receiver, 809 Object* structure, 810 String* name, 811 Object* holder); 812 MUST_USE_RESULT MaybeObject* GetPropertyWithDefinedGetter(Object* receiver, 813 JSFunction* getter); 814 815 inline MaybeObject* GetElement(uint32_t index); 816 // For use when we know that no exception can be thrown. 817 inline Object* GetElementNoExceptionThrown(uint32_t index); 818 MaybeObject* GetElementWithReceiver(Object* receiver, uint32_t index); 819 820 // Return the object's prototype (might be Heap::null_value()). 821 Object* GetPrototype(); 822 823 // Tries to convert an object to an array index. Returns true and sets 824 // the output parameter if it succeeds. 825 inline bool ToArrayIndex(uint32_t* index); 826 827 // Returns true if this is a JSValue containing a string and the index is 828 // < the length of the string. Used to implement [] on strings. 829 inline bool IsStringObjectWithCharacterAt(uint32_t index); 830 831 #ifdef DEBUG 832 // Verify a pointer is a valid object pointer. 833 static void VerifyPointer(Object* p); 834 #endif 835 836 // Prints this object without details. 837 inline void ShortPrint() { 838 ShortPrint(stdout); 839 } 840 void ShortPrint(FILE* out); 841 842 // Prints this object without details to a message accumulator. 843 void ShortPrint(StringStream* accumulator); 844 845 // Casting: This cast is only needed to satisfy macros in objects-inl.h. 846 static Object* cast(Object* value) { return value; } 847 848 // Layout description. 849 static const int kHeaderSize = 0; // Object does not take up any space. 850 851 private: 852 DISALLOW_IMPLICIT_CONSTRUCTORS(Object); 853 }; 854 855 856 // Smi represents integer Numbers that can be stored in 31 bits. 857 // Smis are immediate which means they are NOT allocated in the heap. 858 // The this pointer has the following format: [31 bit signed int] 0 859 // For long smis it has the following format: 860 // [32 bit signed int] [31 bits zero padding] 0 861 // Smi stands for small integer. 862 class Smi: public Object { 863 public: 864 // Returns the integer value. 865 inline int value(); 866 867 // Convert a value to a Smi object. 868 static inline Smi* FromInt(int value); 869 870 static inline Smi* FromIntptr(intptr_t value); 871 872 // Returns whether value can be represented in a Smi. 873 static inline bool IsValid(intptr_t value); 874 875 // Casting. 876 static inline Smi* cast(Object* object); 877 878 // Dispatched behavior. 879 inline void SmiPrint() { 880 SmiPrint(stdout); 881 } 882 void SmiPrint(FILE* out); 883 void SmiPrint(StringStream* accumulator); 884 #ifdef DEBUG 885 void SmiVerify(); 886 #endif 887 888 static const int kMinValue = (-1 << (kSmiValueSize - 1)); 889 static const int kMaxValue = -(kMinValue + 1); 890 891 private: 892 DISALLOW_IMPLICIT_CONSTRUCTORS(Smi); 893 }; 894 895 896 // Failure is used for reporting out of memory situations and 897 // propagating exceptions through the runtime system. Failure objects 898 // are transient and cannot occur as part of the object graph. 899 // 900 // Failures are a single word, encoded as follows: 901 // +-------------------------+---+--+--+ 902 // |.........unused..........|sss|tt|11| 903 // +-------------------------+---+--+--+ 904 // 7 6 4 32 10 905 // 906 // 907 // The low two bits, 0-1, are the failure tag, 11. The next two bits, 908 // 2-3, are a failure type tag 'tt' with possible values: 909 // 00 RETRY_AFTER_GC 910 // 01 EXCEPTION 911 // 10 INTERNAL_ERROR 912 // 11 OUT_OF_MEMORY_EXCEPTION 913 // 914 // The next three bits, 4-6, are an allocation space tag 'sss'. The 915 // allocation space tag is 000 for all failure types except 916 // RETRY_AFTER_GC. For RETRY_AFTER_GC, the possible values are the 917 // allocation spaces (the encoding is found in globals.h). 918 919 // Failure type tag info. 920 const int kFailureTypeTagSize = 2; 921 const int kFailureTypeTagMask = (1 << kFailureTypeTagSize) - 1; 922 923 class Failure: public MaybeObject { 924 public: 925 // RuntimeStubs assumes EXCEPTION = 1 in the compiler-generated code. 926 enum Type { 927 RETRY_AFTER_GC = 0, 928 EXCEPTION = 1, // Returning this marker tells the real exception 929 // is in Isolate::pending_exception. 930 INTERNAL_ERROR = 2, 931 OUT_OF_MEMORY_EXCEPTION = 3 932 }; 933 934 inline Type type() const; 935 936 // Returns the space that needs to be collected for RetryAfterGC failures. 937 inline AllocationSpace allocation_space() const; 938 939 inline bool IsInternalError() const; 940 inline bool IsOutOfMemoryException() const; 941 942 static inline Failure* RetryAfterGC(AllocationSpace space); 943 static inline Failure* RetryAfterGC(); // NEW_SPACE 944 static inline Failure* Exception(); 945 static inline Failure* InternalError(); 946 static inline Failure* OutOfMemoryException(); 947 // Casting. 948 static inline Failure* cast(MaybeObject* object); 949 950 // Dispatched behavior. 951 inline void FailurePrint() { 952 FailurePrint(stdout); 953 } 954 void FailurePrint(FILE* out); 955 void FailurePrint(StringStream* accumulator); 956 #ifdef DEBUG 957 void FailureVerify(); 958 #endif 959 960 private: 961 inline intptr_t value() const; 962 static inline Failure* Construct(Type type, intptr_t value = 0); 963 964 DISALLOW_IMPLICIT_CONSTRUCTORS(Failure); 965 }; 966 967 968 // Heap objects typically have a map pointer in their first word. However, 969 // during GC other data (eg, mark bits, forwarding addresses) is sometimes 970 // encoded in the first word. The class MapWord is an abstraction of the 971 // value in a heap object's first word. 972 class MapWord BASE_EMBEDDED { 973 public: 974 // Normal state: the map word contains a map pointer. 975 976 // Create a map word from a map pointer. 977 static inline MapWord FromMap(Map* map); 978 979 // View this map word as a map pointer. 980 inline Map* ToMap(); 981 982 983 // Scavenge collection: the map word of live objects in the from space 984 // contains a forwarding address (a heap object pointer in the to space). 985 986 // True if this map word is a forwarding address for a scavenge 987 // collection. Only valid during a scavenge collection (specifically, 988 // when all map words are heap object pointers, ie. not during a full GC). 989 inline bool IsForwardingAddress(); 990 991 // Create a map word from a forwarding address. 992 static inline MapWord FromForwardingAddress(HeapObject* object); 993 994 // View this map word as a forwarding address. 995 inline HeapObject* ToForwardingAddress(); 996 997 // Marking phase of full collection: the map word of live objects is 998 // marked, and may be marked as overflowed (eg, the object is live, its 999 // children have not been visited, and it does not fit in the marking 1000 // stack). 1001 1002 // True if this map word's mark bit is set. 1003 inline bool IsMarked(); 1004 1005 // Return this map word but with its mark bit set. 1006 inline void SetMark(); 1007 1008 // Return this map word but with its mark bit cleared. 1009 inline void ClearMark(); 1010 1011 // True if this map word's overflow bit is set. 1012 inline bool IsOverflowed(); 1013 1014 // Return this map word but with its overflow bit set. 1015 inline void SetOverflow(); 1016 1017 // Return this map word but with its overflow bit cleared. 1018 inline void ClearOverflow(); 1019 1020 1021 // Compacting phase of a full compacting collection: the map word of live 1022 // objects contains an encoding of the original map address along with the 1023 // forwarding address (represented as an offset from the first live object 1024 // in the same page as the (old) object address). 1025 1026 // Create a map word from a map address and a forwarding address offset. 1027 static inline MapWord EncodeAddress(Address map_address, int offset); 1028 1029 // Return the map address encoded in this map word. 1030 inline Address DecodeMapAddress(MapSpace* map_space); 1031 1032 // Return the forwarding offset encoded in this map word. 1033 inline int DecodeOffset(); 1034 1035 1036 // During serialization: the map word is used to hold an encoded 1037 // address, and possibly a mark bit (set and cleared with SetMark 1038 // and ClearMark). 1039 1040 // Create a map word from an encoded address. 1041 static inline MapWord FromEncodedAddress(Address address); 1042 1043 inline Address ToEncodedAddress(); 1044 1045 // Bits used by the marking phase of the garbage collector. 1046 // 1047 // The first word of a heap object is normally a map pointer. The last two 1048 // bits are tagged as '01' (kHeapObjectTag). We reuse the last two bits to 1049 // mark an object as live and/or overflowed: 1050 // last bit = 0, marked as alive 1051 // second bit = 1, overflowed 1052 // An object is only marked as overflowed when it is marked as live while 1053 // the marking stack is overflowed. 1054 static const int kMarkingBit = 0; // marking bit 1055 static const int kMarkingMask = (1 << kMarkingBit); // marking mask 1056 static const int kOverflowBit = 1; // overflow bit 1057 static const int kOverflowMask = (1 << kOverflowBit); // overflow mask 1058 1059 // Forwarding pointers and map pointer encoding. On 32 bit all the bits are 1060 // used. 1061 // +-----------------+------------------+-----------------+ 1062 // |forwarding offset|page offset of map|page index of map| 1063 // +-----------------+------------------+-----------------+ 1064 // ^ ^ ^ 1065 // | | | 1066 // | | kMapPageIndexBits 1067 // | kMapPageOffsetBits 1068 // kForwardingOffsetBits 1069 static const int kMapPageOffsetBits = kPageSizeBits - kMapAlignmentBits; 1070 static const int kForwardingOffsetBits = kPageSizeBits - kObjectAlignmentBits; 1071 #ifdef V8_HOST_ARCH_64_BIT 1072 static const int kMapPageIndexBits = 16; 1073 #else 1074 // Use all the 32-bits to encode on a 32-bit platform. 1075 static const int kMapPageIndexBits = 1076 32 - (kMapPageOffsetBits + kForwardingOffsetBits); 1077 #endif 1078 1079 static const int kMapPageIndexShift = 0; 1080 static const int kMapPageOffsetShift = 1081 kMapPageIndexShift + kMapPageIndexBits; 1082 static const int kForwardingOffsetShift = 1083 kMapPageOffsetShift + kMapPageOffsetBits; 1084 1085 // Bit masks covering the different parts the encoding. 1086 static const uintptr_t kMapPageIndexMask = 1087 (1 << kMapPageOffsetShift) - 1; 1088 static const uintptr_t kMapPageOffsetMask = 1089 ((1 << kForwardingOffsetShift) - 1) & ~kMapPageIndexMask; 1090 static const uintptr_t kForwardingOffsetMask = 1091 ~(kMapPageIndexMask | kMapPageOffsetMask); 1092 1093 private: 1094 // HeapObject calls the private constructor and directly reads the value. 1095 friend class HeapObject; 1096 1097 explicit MapWord(uintptr_t value) : value_(value) {} 1098 1099 uintptr_t value_; 1100 }; 1101 1102 1103 // HeapObject is the superclass for all classes describing heap allocated 1104 // objects. 1105 class HeapObject: public Object { 1106 public: 1107 // [map]: Contains a map which contains the object's reflective 1108 // information. 1109 inline Map* map(); 1110 inline void set_map(Map* value); 1111 1112 // During garbage collection, the map word of a heap object does not 1113 // necessarily contain a map pointer. 1114 inline MapWord map_word(); 1115 inline void set_map_word(MapWord map_word); 1116 1117 // The Heap the object was allocated in. Used also to access Isolate. 1118 // This method can not be used during GC, it ASSERTs this. 1119 inline Heap* GetHeap(); 1120 // Convenience method to get current isolate. This method can be 1121 // accessed only when its result is the same as 1122 // Isolate::Current(), it ASSERTs this. See also comment for GetHeap. 1123 inline Isolate* GetIsolate(); 1124 1125 // Converts an address to a HeapObject pointer. 1126 static inline HeapObject* FromAddress(Address address); 1127 1128 // Returns the address of this HeapObject. 1129 inline Address address(); 1130 1131 // Iterates over pointers contained in the object (including the Map) 1132 void Iterate(ObjectVisitor* v); 1133 1134 // Iterates over all pointers contained in the object except the 1135 // first map pointer. The object type is given in the first 1136 // parameter. This function does not access the map pointer in the 1137 // object, and so is safe to call while the map pointer is modified. 1138 void IterateBody(InstanceType type, int object_size, ObjectVisitor* v); 1139 1140 // Returns the heap object's size in bytes 1141 inline int Size(); 1142 1143 // Given a heap object's map pointer, returns the heap size in bytes 1144 // Useful when the map pointer field is used for other purposes. 1145 // GC internal. 1146 inline int SizeFromMap(Map* map); 1147 1148 // Support for the marking heap objects during the marking phase of GC. 1149 // True if the object is marked live. 1150 inline bool IsMarked(); 1151 1152 // Mutate this object's map pointer to indicate that the object is live. 1153 inline void SetMark(); 1154 1155 // Mutate this object's map pointer to remove the indication that the 1156 // object is live (ie, partially restore the map pointer). 1157 inline void ClearMark(); 1158 1159 // True if this object is marked as overflowed. Overflowed objects have 1160 // been reached and marked during marking of the heap, but their children 1161 // have not necessarily been marked and they have not been pushed on the 1162 // marking stack. 1163 inline bool IsOverflowed(); 1164 1165 // Mutate this object's map pointer to indicate that the object is 1166 // overflowed. 1167 inline void SetOverflow(); 1168 1169 // Mutate this object's map pointer to remove the indication that the 1170 // object is overflowed (ie, partially restore the map pointer). 1171 inline void ClearOverflow(); 1172 1173 // Returns the field at offset in obj, as a read/write Object* reference. 1174 // Does no checking, and is safe to use during GC, while maps are invalid. 1175 // Does not invoke write barrier, so should only be assigned to 1176 // during marking GC. 1177 static inline Object** RawField(HeapObject* obj, int offset); 1178 1179 // Casting. 1180 static inline HeapObject* cast(Object* obj); 1181 1182 // Return the write barrier mode for this. Callers of this function 1183 // must be able to present a reference to an AssertNoAllocation 1184 // object as a sign that they are not going to use this function 1185 // from code that allocates and thus invalidates the returned write 1186 // barrier mode. 1187 inline WriteBarrierMode GetWriteBarrierMode(const AssertNoAllocation&); 1188 1189 // Dispatched behavior. 1190 void HeapObjectShortPrint(StringStream* accumulator); 1191 #ifdef OBJECT_PRINT 1192 inline void HeapObjectPrint() { 1193 HeapObjectPrint(stdout); 1194 } 1195 void HeapObjectPrint(FILE* out); 1196 #endif 1197 #ifdef DEBUG 1198 void HeapObjectVerify(); 1199 inline void VerifyObjectField(int offset); 1200 inline void VerifySmiField(int offset); 1201 #endif 1202 1203 #ifdef OBJECT_PRINT 1204 void PrintHeader(FILE* out, const char* id); 1205 #endif 1206 1207 #ifdef DEBUG 1208 // Verify a pointer is a valid HeapObject pointer that points to object 1209 // areas in the heap. 1210 static void VerifyHeapPointer(Object* p); 1211 #endif 1212 1213 // Layout description. 1214 // First field in a heap object is map. 1215 static const int kMapOffset = Object::kHeaderSize; 1216 static const int kHeaderSize = kMapOffset + kPointerSize; 1217 1218 STATIC_CHECK(kMapOffset == Internals::kHeapObjectMapOffset); 1219 1220 protected: 1221 // helpers for calling an ObjectVisitor to iterate over pointers in the 1222 // half-open range [start, end) specified as integer offsets 1223 inline void IteratePointers(ObjectVisitor* v, int start, int end); 1224 // as above, for the single element at "offset" 1225 inline void IteratePointer(ObjectVisitor* v, int offset); 1226 1227 private: 1228 DISALLOW_IMPLICIT_CONSTRUCTORS(HeapObject); 1229 }; 1230 1231 1232 #define SLOT_ADDR(obj, offset) \ 1233 reinterpret_cast<Object**>((obj)->address() + offset) 1234 1235 // This class describes a body of an object of a fixed size 1236 // in which all pointer fields are located in the [start_offset, end_offset) 1237 // interval. 1238 template<int start_offset, int end_offset, int size> 1239 class FixedBodyDescriptor { 1240 public: 1241 static const int kStartOffset = start_offset; 1242 static const int kEndOffset = end_offset; 1243 static const int kSize = size; 1244 1245 static inline void IterateBody(HeapObject* obj, ObjectVisitor* v); 1246 1247 template<typename StaticVisitor> 1248 static inline void IterateBody(HeapObject* obj) { 1249 StaticVisitor::VisitPointers(SLOT_ADDR(obj, start_offset), 1250 SLOT_ADDR(obj, end_offset)); 1251 } 1252 }; 1253 1254 1255 // This class describes a body of an object of a variable size 1256 // in which all pointer fields are located in the [start_offset, object_size) 1257 // interval. 1258 template<int start_offset> 1259 class FlexibleBodyDescriptor { 1260 public: 1261 static const int kStartOffset = start_offset; 1262 1263 static inline void IterateBody(HeapObject* obj, 1264 int object_size, 1265 ObjectVisitor* v); 1266 1267 template<typename StaticVisitor> 1268 static inline void IterateBody(HeapObject* obj, int object_size) { 1269 StaticVisitor::VisitPointers(SLOT_ADDR(obj, start_offset), 1270 SLOT_ADDR(obj, object_size)); 1271 } 1272 }; 1273 1274 #undef SLOT_ADDR 1275 1276 1277 // The HeapNumber class describes heap allocated numbers that cannot be 1278 // represented in a Smi (small integer) 1279 class HeapNumber: public HeapObject { 1280 public: 1281 // [value]: number value. 1282 inline double value(); 1283 inline void set_value(double value); 1284 1285 // Casting. 1286 static inline HeapNumber* cast(Object* obj); 1287 1288 // Dispatched behavior. 1289 Object* HeapNumberToBoolean(); 1290 inline void HeapNumberPrint() { 1291 HeapNumberPrint(stdout); 1292 } 1293 void HeapNumberPrint(FILE* out); 1294 void HeapNumberPrint(StringStream* accumulator); 1295 #ifdef DEBUG 1296 void HeapNumberVerify(); 1297 #endif 1298 1299 inline int get_exponent(); 1300 inline int get_sign(); 1301 1302 // Layout description. 1303 static const int kValueOffset = HeapObject::kHeaderSize; 1304 // IEEE doubles are two 32 bit words. The first is just mantissa, the second 1305 // is a mixture of sign, exponent and mantissa. Our current platforms are all 1306 // little endian apart from non-EABI arm which is little endian with big 1307 // endian floating point word ordering! 1308 static const int kMantissaOffset = kValueOffset; 1309 static const int kExponentOffset = kValueOffset + 4; 1310 1311 static const int kSize = kValueOffset + kDoubleSize; 1312 static const uint32_t kSignMask = 0x80000000u; 1313 static const uint32_t kExponentMask = 0x7ff00000u; 1314 static const uint32_t kMantissaMask = 0xfffffu; 1315 static const int kMantissaBits = 52; 1316 static const int kExponentBits = 11; 1317 static const int kExponentBias = 1023; 1318 static const int kExponentShift = 20; 1319 static const int kMantissaBitsInTopWord = 20; 1320 static const int kNonMantissaBitsInTopWord = 12; 1321 1322 private: 1323 DISALLOW_IMPLICIT_CONSTRUCTORS(HeapNumber); 1324 }; 1325 1326 1327 // The JSObject describes real heap allocated JavaScript objects with 1328 // properties. 1329 // Note that the map of JSObject changes during execution to enable inline 1330 // caching. 1331 class JSObject: public HeapObject { 1332 public: 1333 enum DeleteMode { 1334 NORMAL_DELETION, 1335 STRICT_DELETION, 1336 FORCE_DELETION 1337 }; 1338 1339 enum ElementsKind { 1340 // The only "fast" kind. 1341 FAST_ELEMENTS, 1342 // All the kinds below are "slow". 1343 DICTIONARY_ELEMENTS, 1344 EXTERNAL_BYTE_ELEMENTS, 1345 EXTERNAL_UNSIGNED_BYTE_ELEMENTS, 1346 EXTERNAL_SHORT_ELEMENTS, 1347 EXTERNAL_UNSIGNED_SHORT_ELEMENTS, 1348 EXTERNAL_INT_ELEMENTS, 1349 EXTERNAL_UNSIGNED_INT_ELEMENTS, 1350 EXTERNAL_FLOAT_ELEMENTS, 1351 EXTERNAL_PIXEL_ELEMENTS 1352 }; 1353 1354 // [properties]: Backing storage for properties. 1355 // properties is a FixedArray in the fast case and a Dictionary in the 1356 // slow case. 1357 DECL_ACCESSORS(properties, FixedArray) // Get and set fast properties. 1358 inline void initialize_properties(); 1359 inline bool HasFastProperties(); 1360 inline StringDictionary* property_dictionary(); // Gets slow properties. 1361 1362 // [elements]: The elements (properties with names that are integers). 1363 // 1364 // Elements can be in two general modes: fast and slow. Each mode 1365 // corrensponds to a set of object representations of elements that 1366 // have something in common. 1367 // 1368 // In the fast mode elements is a FixedArray and so each element can 1369 // be quickly accessed. This fact is used in the generated code. The 1370 // elements array can have one of the two maps in this mode: 1371 // fixed_array_map or fixed_cow_array_map (for copy-on-write 1372 // arrays). In the latter case the elements array may be shared by a 1373 // few objects and so before writing to any element the array must 1374 // be copied. Use EnsureWritableFastElements in this case. 1375 // 1376 // In the slow mode elements is either a NumberDictionary or an ExternalArray. 1377 DECL_ACCESSORS(elements, HeapObject) 1378 inline void initialize_elements(); 1379 MUST_USE_RESULT inline MaybeObject* ResetElements(); 1380 inline ElementsKind GetElementsKind(); 1381 inline bool HasFastElements(); 1382 inline bool HasDictionaryElements(); 1383 inline bool HasExternalPixelElements(); 1384 inline bool HasExternalArrayElements(); 1385 inline bool HasExternalByteElements(); 1386 inline bool HasExternalUnsignedByteElements(); 1387 inline bool HasExternalShortElements(); 1388 inline bool HasExternalUnsignedShortElements(); 1389 inline bool HasExternalIntElements(); 1390 inline bool HasExternalUnsignedIntElements(); 1391 inline bool HasExternalFloatElements(); 1392 inline bool AllowsSetElementsLength(); 1393 inline NumberDictionary* element_dictionary(); // Gets slow elements. 1394 // Requires: this->HasFastElements(). 1395 MUST_USE_RESULT inline MaybeObject* EnsureWritableFastElements(); 1396 1397 // Collects elements starting at index 0. 1398 // Undefined values are placed after non-undefined values. 1399 // Returns the number of non-undefined values. 1400 MUST_USE_RESULT MaybeObject* PrepareElementsForSort(uint32_t limit); 1401 // As PrepareElementsForSort, but only on objects where elements is 1402 // a dictionary, and it will stay a dictionary. 1403 MUST_USE_RESULT MaybeObject* PrepareSlowElementsForSort(uint32_t limit); 1404 1405 MUST_USE_RESULT MaybeObject* SetProperty(String* key, 1406 Object* value, 1407 PropertyAttributes attributes, 1408 StrictModeFlag strict_mode); 1409 MUST_USE_RESULT MaybeObject* SetProperty(LookupResult* result, 1410 String* key, 1411 Object* value, 1412 PropertyAttributes attributes, 1413 StrictModeFlag strict_mode); 1414 MUST_USE_RESULT MaybeObject* SetPropertyWithFailedAccessCheck( 1415 LookupResult* result, 1416 String* name, 1417 Object* value, 1418 bool check_prototype); 1419 MUST_USE_RESULT MaybeObject* SetPropertyWithCallback(Object* structure, 1420 String* name, 1421 Object* value, 1422 JSObject* holder); 1423 MUST_USE_RESULT MaybeObject* SetPropertyWithDefinedSetter(JSFunction* setter, 1424 Object* value); 1425 MUST_USE_RESULT MaybeObject* SetPropertyWithInterceptor( 1426 String* name, 1427 Object* value, 1428 PropertyAttributes attributes, 1429 StrictModeFlag strict_mode); 1430 MUST_USE_RESULT MaybeObject* SetPropertyPostInterceptor( 1431 String* name, 1432 Object* value, 1433 PropertyAttributes attributes, 1434 StrictModeFlag strict_mode); 1435 MUST_USE_RESULT MaybeObject* SetLocalPropertyIgnoreAttributes( 1436 String* key, 1437 Object* value, 1438 PropertyAttributes attributes); 1439 1440 // Retrieve a value in a normalized object given a lookup result. 1441 // Handles the special representation of JS global objects. 1442 Object* GetNormalizedProperty(LookupResult* result); 1443 1444 // Sets the property value in a normalized object given a lookup result. 1445 // Handles the special representation of JS global objects. 1446 Object* SetNormalizedProperty(LookupResult* result, Object* value); 1447 1448 // Sets the property value in a normalized object given (key, value, details). 1449 // Handles the special representation of JS global objects. 1450 MUST_USE_RESULT MaybeObject* SetNormalizedProperty(String* name, 1451 Object* value, 1452 PropertyDetails details); 1453 1454 // Deletes the named property in a normalized object. 1455 MUST_USE_RESULT MaybeObject* DeleteNormalizedProperty(String* name, 1456 DeleteMode mode); 1457 1458 // Returns the class name ([[Class]] property in the specification). 1459 String* class_name(); 1460 1461 // Returns the constructor name (the name (possibly, inferred name) of the 1462 // function that was used to instantiate the object). 1463 String* constructor_name(); 1464 1465 // Retrieve interceptors. 1466 InterceptorInfo* GetNamedInterceptor(); 1467 InterceptorInfo* GetIndexedInterceptor(); 1468 1469 inline PropertyAttributes GetPropertyAttribute(String* name); 1470 PropertyAttributes GetPropertyAttributeWithReceiver(JSObject* receiver, 1471 String* name); 1472 PropertyAttributes GetLocalPropertyAttribute(String* name); 1473 1474 MUST_USE_RESULT MaybeObject* DefineAccessor(String* name, 1475 bool is_getter, 1476 Object* fun, 1477 PropertyAttributes attributes); 1478 Object* LookupAccessor(String* name, bool is_getter); 1479 1480 MUST_USE_RESULT MaybeObject* DefineAccessor(AccessorInfo* info); 1481 1482 // Used from Object::GetProperty(). 1483 MaybeObject* GetPropertyWithFailedAccessCheck( 1484 Object* receiver, 1485 LookupResult* result, 1486 String* name, 1487 PropertyAttributes* attributes); 1488 MaybeObject* GetPropertyWithInterceptor( 1489 JSObject* receiver, 1490 String* name, 1491 PropertyAttributes* attributes); 1492 MaybeObject* GetPropertyPostInterceptor( 1493 JSObject* receiver, 1494 String* name, 1495 PropertyAttributes* attributes); 1496 MaybeObject* GetLocalPropertyPostInterceptor(JSObject* receiver, 1497 String* name, 1498 PropertyAttributes* attributes); 1499 1500 // Returns true if this is an instance of an api function and has 1501 // been modified since it was created. May give false positives. 1502 bool IsDirty(); 1503 1504 bool HasProperty(String* name) { 1505 return GetPropertyAttribute(name) != ABSENT; 1506 } 1507 1508 // Can cause a GC if it hits an interceptor. 1509 bool HasLocalProperty(String* name) { 1510 return GetLocalPropertyAttribute(name) != ABSENT; 1511 } 1512 1513 // If the receiver is a JSGlobalProxy this method will return its prototype, 1514 // otherwise the result is the receiver itself. 1515 inline Object* BypassGlobalProxy(); 1516 1517 // Accessors for hidden properties object. 1518 // 1519 // Hidden properties are not local properties of the object itself. 1520 // Instead they are stored on an auxiliary JSObject stored as a local 1521 // property with a special name Heap::hidden_symbol(). But if the 1522 // receiver is a JSGlobalProxy then the auxiliary object is a property 1523 // of its prototype. 1524 // 1525 // Has/Get/SetHiddenPropertiesObject methods don't allow the holder to be 1526 // a JSGlobalProxy. Use BypassGlobalProxy method above to get to the real 1527 // holder. 1528 // 1529 // These accessors do not touch interceptors or accessors. 1530 inline bool HasHiddenPropertiesObject(); 1531 inline Object* GetHiddenPropertiesObject(); 1532 MUST_USE_RESULT inline MaybeObject* SetHiddenPropertiesObject( 1533 Object* hidden_obj); 1534 1535 MUST_USE_RESULT MaybeObject* DeleteProperty(String* name, DeleteMode mode); 1536 MUST_USE_RESULT MaybeObject* DeleteElement(uint32_t index, DeleteMode mode); 1537 1538 // Tests for the fast common case for property enumeration. 1539 bool IsSimpleEnum(); 1540 1541 // Do we want to keep the elements in fast case when increasing the 1542 // capacity? 1543 bool ShouldConvertToSlowElements(int new_capacity); 1544 // Returns true if the backing storage for the slow-case elements of 1545 // this object takes up nearly as much space as a fast-case backing 1546 // storage would. In that case the JSObject should have fast 1547 // elements. 1548 bool ShouldConvertToFastElements(); 1549 1550 // Return the object's prototype (might be Heap::null_value()). 1551 inline Object* GetPrototype(); 1552 1553 // Set the object's prototype (only JSObject and null are allowed). 1554 MUST_USE_RESULT MaybeObject* SetPrototype(Object* value, 1555 bool skip_hidden_prototypes); 1556 1557 // Tells whether the index'th element is present. 1558 inline bool HasElement(uint32_t index); 1559 bool HasElementWithReceiver(JSObject* receiver, uint32_t index); 1560 1561 // Computes the new capacity when expanding the elements of a JSObject. 1562 static int NewElementsCapacity(int old_capacity) { 1563 // (old_capacity + 50%) + 16 1564 return old_capacity + (old_capacity >> 1) + 16; 1565 } 1566 1567 // Tells whether the index'th element is present and how it is stored. 1568 enum LocalElementType { 1569 // There is no element with given index. 1570 UNDEFINED_ELEMENT, 1571 1572 // Element with given index is handled by interceptor. 1573 INTERCEPTED_ELEMENT, 1574 1575 // Element with given index is character in string. 1576 STRING_CHARACTER_ELEMENT, 1577 1578 // Element with given index is stored in fast backing store. 1579 FAST_ELEMENT, 1580 1581 // Element with given index is stored in slow backing store. 1582 DICTIONARY_ELEMENT 1583 }; 1584 1585 LocalElementType HasLocalElement(uint32_t index); 1586 1587 bool HasElementWithInterceptor(JSObject* receiver, uint32_t index); 1588 bool HasElementPostInterceptor(JSObject* receiver, uint32_t index); 1589 1590 MUST_USE_RESULT MaybeObject* SetFastElement(uint32_t index, 1591 Object* value, 1592 StrictModeFlag strict_mode, 1593 bool check_prototype = true); 1594 1595 // Set the index'th array element. 1596 // A Failure object is returned if GC is needed. 1597 MUST_USE_RESULT MaybeObject* SetElement(uint32_t index, 1598 Object* value, 1599 StrictModeFlag strict_mode, 1600 bool check_prototype = true); 1601 1602 // Returns the index'th element. 1603 // The undefined object if index is out of bounds. 1604 MaybeObject* GetElementWithReceiver(Object* receiver, uint32_t index); 1605 MaybeObject* GetElementWithInterceptor(Object* receiver, uint32_t index); 1606 1607 // Get external element value at index if there is one and undefined 1608 // otherwise. Can return a failure if allocation of a heap number 1609 // failed. 1610 MaybeObject* GetExternalElement(uint32_t index); 1611 1612 MUST_USE_RESULT MaybeObject* SetFastElementsCapacityAndLength(int capacity, 1613 int length); 1614 MUST_USE_RESULT MaybeObject* SetSlowElements(Object* length); 1615 1616 // Lookup interceptors are used for handling properties controlled by host 1617 // objects. 1618 inline bool HasNamedInterceptor(); 1619 inline bool HasIndexedInterceptor(); 1620 1621 // Support functions for v8 api (needed for correct interceptor behavior). 1622 bool HasRealNamedProperty(String* key); 1623 bool HasRealElementProperty(uint32_t index); 1624 bool HasRealNamedCallbackProperty(String* key); 1625 1626 // Initializes the array to a certain length 1627 MUST_USE_RESULT MaybeObject* SetElementsLength(Object* length); 1628 1629 // Get the header size for a JSObject. Used to compute the index of 1630 // internal fields as well as the number of internal fields. 1631 inline int GetHeaderSize(); 1632 1633 inline int GetInternalFieldCount(); 1634 inline int GetInternalFieldOffset(int index); 1635 inline Object* GetInternalField(int index); 1636 inline void SetInternalField(int index, Object* value); 1637 1638 // Lookup a property. If found, the result is valid and has 1639 // detailed information. 1640 void LocalLookup(String* name, LookupResult* result); 1641 void Lookup(String* name, LookupResult* result); 1642 1643 // The following lookup functions skip interceptors. 1644 void LocalLookupRealNamedProperty(String* name, LookupResult* result); 1645 void LookupRealNamedProperty(String* name, LookupResult* result); 1646 void LookupRealNamedPropertyInPrototypes(String* name, LookupResult* result); 1647 void LookupCallbackSetterInPrototypes(String* name, LookupResult* result); 1648 MUST_USE_RESULT MaybeObject* SetElementWithCallbackSetterInPrototypes( 1649 uint32_t index, Object* value, bool* found); 1650 void LookupCallback(String* name, LookupResult* result); 1651 1652 // Returns the number of properties on this object filtering out properties 1653 // with the specified attributes (ignoring interceptors). 1654 int NumberOfLocalProperties(PropertyAttributes filter); 1655 // Returns the number of enumerable properties (ignoring interceptors). 1656 int NumberOfEnumProperties(); 1657 // Fill in details for properties into storage starting at the specified 1658 // index. 1659 void GetLocalPropertyNames(FixedArray* storage, int index); 1660 1661 // Returns the number of properties on this object filtering out properties 1662 // with the specified attributes (ignoring interceptors). 1663 int NumberOfLocalElements(PropertyAttributes filter); 1664 // Returns the number of enumerable elements (ignoring interceptors). 1665 int NumberOfEnumElements(); 1666 // Returns the number of elements on this object filtering out elements 1667 // with the specified attributes (ignoring interceptors). 1668 int GetLocalElementKeys(FixedArray* storage, PropertyAttributes filter); 1669 // Count and fill in the enumerable elements into storage. 1670 // (storage->length() == NumberOfEnumElements()). 1671 // If storage is NULL, will count the elements without adding 1672 // them to any storage. 1673 // Returns the number of enumerable elements. 1674 int GetEnumElementKeys(FixedArray* storage); 1675 1676 // Add a property to a fast-case object using a map transition to 1677 // new_map. 1678 MUST_USE_RESULT MaybeObject* AddFastPropertyUsingMap(Map* new_map, 1679 String* name, 1680 Object* value); 1681 1682 // Add a constant function property to a fast-case object. 1683 // This leaves a CONSTANT_TRANSITION in the old map, and 1684 // if it is called on a second object with this map, a 1685 // normal property is added instead, with a map transition. 1686 // This avoids the creation of many maps with the same constant 1687 // function, all orphaned. 1688 MUST_USE_RESULT MaybeObject* AddConstantFunctionProperty( 1689 String* name, 1690 JSFunction* function, 1691 PropertyAttributes attributes); 1692 1693 MUST_USE_RESULT MaybeObject* ReplaceSlowProperty( 1694 String* name, 1695 Object* value, 1696 PropertyAttributes attributes); 1697 1698 // Converts a descriptor of any other type to a real field, 1699 // backed by the properties array. Descriptors of visible 1700 // types, such as CONSTANT_FUNCTION, keep their enumeration order. 1701 // Converts the descriptor on the original object's map to a 1702 // map transition, and the the new field is on the object's new map. 1703 MUST_USE_RESULT MaybeObject* ConvertDescriptorToFieldAndMapTransition( 1704 String* name, 1705 Object* new_value, 1706 PropertyAttributes attributes); 1707 1708 // Converts a descriptor of any other type to a real field, 1709 // backed by the properties array. Descriptors of visible 1710 // types, such as CONSTANT_FUNCTION, keep their enumeration order. 1711 MUST_USE_RESULT MaybeObject* ConvertDescriptorToField( 1712 String* name, 1713 Object* new_value, 1714 PropertyAttributes attributes); 1715 1716 // Add a property to a fast-case object. 1717 MUST_USE_RESULT MaybeObject* AddFastProperty(String* name, 1718 Object* value, 1719 PropertyAttributes attributes); 1720 1721 // Add a property to a slow-case object. 1722 MUST_USE_RESULT MaybeObject* AddSlowProperty(String* name, 1723 Object* value, 1724 PropertyAttributes attributes); 1725 1726 // Add a property to an object. 1727 MUST_USE_RESULT MaybeObject* AddProperty(String* name, 1728 Object* value, 1729 PropertyAttributes attributes, 1730 StrictModeFlag strict_mode); 1731 1732 // Convert the object to use the canonical dictionary 1733 // representation. If the object is expected to have additional properties 1734 // added this number can be indicated to have the backing store allocated to 1735 // an initial capacity for holding these properties. 1736 MUST_USE_RESULT MaybeObject* NormalizeProperties( 1737 PropertyNormalizationMode mode, 1738 int expected_additional_properties); 1739 MUST_USE_RESULT MaybeObject* NormalizeElements(); 1740 1741 MUST_USE_RESULT MaybeObject* UpdateMapCodeCache(String* name, Code* code); 1742 1743 // Transform slow named properties to fast variants. 1744 // Returns failure if allocation failed. 1745 MUST_USE_RESULT MaybeObject* TransformToFastProperties( 1746 int unused_property_fields); 1747 1748 // Access fast-case object properties at index. 1749 inline Object* FastPropertyAt(int index); 1750 inline Object* FastPropertyAtPut(int index, Object* value); 1751 1752 // Access to in object properties. 1753 inline int GetInObjectPropertyOffset(int index); 1754 inline Object* InObjectPropertyAt(int index); 1755 inline Object* InObjectPropertyAtPut(int index, 1756 Object* value, 1757 WriteBarrierMode mode 1758 = UPDATE_WRITE_BARRIER); 1759 1760 // initializes the body after properties slot, properties slot is 1761 // initialized by set_properties 1762 // Note: this call does not update write barrier, it is caller's 1763 // reponsibility to ensure that *v* can be collected without WB here. 1764 inline void InitializeBody(int object_size, Object* value); 1765 1766 // Check whether this object references another object 1767 bool ReferencesObject(Object* obj); 1768 1769 // Casting. 1770 static inline JSObject* cast(Object* obj); 1771 1772 // Disalow further properties to be added to the object. 1773 MUST_USE_RESULT MaybeObject* PreventExtensions(); 1774 1775 1776 // Dispatched behavior. 1777 void JSObjectShortPrint(StringStream* accumulator); 1778 #ifdef OBJECT_PRINT 1779 inline void JSObjectPrint() { 1780 JSObjectPrint(stdout); 1781 } 1782 void JSObjectPrint(FILE* out); 1783 #endif 1784 #ifdef DEBUG 1785 void JSObjectVerify(); 1786 #endif 1787 #ifdef OBJECT_PRINT 1788 inline void PrintProperties() { 1789 PrintProperties(stdout); 1790 } 1791 void PrintProperties(FILE* out); 1792 1793 inline void PrintElements() { 1794 PrintElements(stdout); 1795 } 1796 void PrintElements(FILE* out); 1797 #endif 1798 1799 #ifdef DEBUG 1800 // Structure for collecting spill information about JSObjects. 1801 class SpillInformation { 1802 public: 1803 void Clear(); 1804 void Print(); 1805 int number_of_objects_; 1806 int number_of_objects_with_fast_properties_; 1807 int number_of_objects_with_fast_elements_; 1808 int number_of_fast_used_fields_; 1809 int number_of_fast_unused_fields_; 1810 int number_of_slow_used_properties_; 1811 int number_of_slow_unused_properties_; 1812 int number_of_fast_used_elements_; 1813 int number_of_fast_unused_elements_; 1814 int number_of_slow_used_elements_; 1815 int number_of_slow_unused_elements_; 1816 }; 1817 1818 void IncrementSpillStatistics(SpillInformation* info); 1819 #endif 1820 Object* SlowReverseLookup(Object* value); 1821 1822 // Maximal number of fast properties for the JSObject. Used to 1823 // restrict the number of map transitions to avoid an explosion in 1824 // the number of maps for objects used as dictionaries. 1825 inline int MaxFastProperties(); 1826 1827 // Maximal number of elements (numbered 0 .. kMaxElementCount - 1). 1828 // Also maximal value of JSArray's length property. 1829 static const uint32_t kMaxElementCount = 0xffffffffu; 1830 1831 static const uint32_t kMaxGap = 1024; 1832 static const int kMaxFastElementsLength = 5000; 1833 static const int kInitialMaxFastElementArray = 100000; 1834 static const int kMaxFastProperties = 12; 1835 static const int kMaxInstanceSize = 255 * kPointerSize; 1836 // When extending the backing storage for property values, we increase 1837 // its size by more than the 1 entry necessary, so sequentially adding fields 1838 // to the same object requires fewer allocations and copies. 1839 static const int kFieldsAdded = 3; 1840 1841 // Layout description. 1842 static const int kPropertiesOffset = HeapObject::kHeaderSize; 1843 static const int kElementsOffset = kPropertiesOffset + kPointerSize; 1844 static const int kHeaderSize = kElementsOffset + kPointerSize; 1845 1846 STATIC_CHECK(kHeaderSize == Internals::kJSObjectHeaderSize); 1847 1848 class BodyDescriptor : public FlexibleBodyDescriptor<kPropertiesOffset> { 1849 public: 1850 static inline int SizeOf(Map* map, HeapObject* object); 1851 }; 1852 1853 private: 1854 MUST_USE_RESULT MaybeObject* GetElementWithCallback(Object* receiver, 1855 Object* structure, 1856 uint32_t index, 1857 Object* holder); 1858 MaybeObject* SetElementWithCallback(Object* structure, 1859 uint32_t index, 1860 Object* value, 1861 JSObject* holder); 1862 MUST_USE_RESULT MaybeObject* SetElementWithInterceptor( 1863 uint32_t index, 1864 Object* value, 1865 StrictModeFlag strict_mode, 1866 bool check_prototype); 1867 MUST_USE_RESULT MaybeObject* SetElementWithoutInterceptor( 1868 uint32_t index, 1869 Object* value, 1870 StrictModeFlag strict_mode, 1871 bool check_prototype); 1872 1873 MaybeObject* GetElementPostInterceptor(Object* receiver, uint32_t index); 1874 1875 MUST_USE_RESULT MaybeObject* DeletePropertyPostInterceptor(String* name, 1876 DeleteMode mode); 1877 MUST_USE_RESULT MaybeObject* DeletePropertyWithInterceptor(String* name); 1878 1879 MUST_USE_RESULT MaybeObject* DeleteElementPostInterceptor(uint32_t index, 1880 DeleteMode mode); 1881 MUST_USE_RESULT MaybeObject* DeleteElementWithInterceptor(uint32_t index); 1882 1883 PropertyAttributes GetPropertyAttributePostInterceptor(JSObject* receiver, 1884 String* name, 1885 bool continue_search); 1886 PropertyAttributes GetPropertyAttributeWithInterceptor(JSObject* receiver, 1887 String* name, 1888 bool continue_search); 1889 PropertyAttributes GetPropertyAttributeWithFailedAccessCheck( 1890 Object* receiver, 1891 LookupResult* result, 1892 String* name, 1893 bool continue_search); 1894 PropertyAttributes GetPropertyAttribute(JSObject* receiver, 1895 LookupResult* result, 1896 String* name, 1897 bool continue_search); 1898 1899 // Returns true if most of the elements backing storage is used. 1900 bool HasDenseElements(); 1901 1902 bool CanSetCallback(String* name); 1903 MUST_USE_RESULT MaybeObject* SetElementCallback( 1904 uint32_t index, 1905 Object* structure, 1906 PropertyAttributes attributes); 1907 MUST_USE_RESULT MaybeObject* SetPropertyCallback( 1908 String* name, 1909 Object* structure, 1910 PropertyAttributes attributes); 1911 MUST_USE_RESULT MaybeObject* DefineGetterSetter( 1912 String* name, 1913 PropertyAttributes attributes); 1914 1915 void LookupInDescriptor(String* name, LookupResult* result); 1916 1917 DISALLOW_IMPLICIT_CONSTRUCTORS(JSObject); 1918 }; 1919 1920 1921 // FixedArray describes fixed-sized arrays with element type Object*. 1922 class FixedArray: public HeapObject { 1923 public: 1924 // [length]: length of the array. 1925 inline int length(); 1926 inline void set_length(int value); 1927 1928 // Setter and getter for elements. 1929 inline Object* get(int index); 1930 // Setter that uses write barrier. 1931 inline void set(int index, Object* value); 1932 1933 // Setter that doesn't need write barrier). 1934 inline void set(int index, Smi* value); 1935 // Setter with explicit barrier mode. 1936 inline void set(int index, Object* value, WriteBarrierMode mode); 1937 1938 // Setters for frequently used oddballs located in old space. 1939 inline void set_undefined(int index); 1940 // TODO(isolates): duplicate. 1941 inline void set_undefined(Heap* heap, int index); 1942 inline void set_null(int index); 1943 // TODO(isolates): duplicate. 1944 inline void set_null(Heap* heap, int index); 1945 inline void set_the_hole(int index); 1946 1947 // Setters with less debug checks for the GC to use. 1948 inline void set_unchecked(int index, Smi* value); 1949 inline void set_null_unchecked(Heap* heap, int index); 1950 inline void set_unchecked(Heap* heap, int index, Object* value, 1951 WriteBarrierMode mode); 1952 1953 // Gives access to raw memory which stores the array's data. 1954 inline Object** data_start(); 1955 1956 // Copy operations. 1957 MUST_USE_RESULT inline MaybeObject* Copy(); 1958 MUST_USE_RESULT MaybeObject* CopySize(int new_length); 1959 1960 // Add the elements of a JSArray to this FixedArray. 1961 MUST_USE_RESULT MaybeObject* AddKeysFromJSArray(JSArray* array); 1962 1963 // Compute the union of this and other. 1964 MUST_USE_RESULT MaybeObject* UnionOfKeys(FixedArray* other); 1965 1966 // Copy a sub array from the receiver to dest. 1967 void CopyTo(int pos, FixedArray* dest, int dest_pos, int len); 1968 1969 // Garbage collection support. 1970 static int SizeFor(int length) { return kHeaderSize + length * kPointerSize; } 1971 1972 // Code Generation support. 1973 static int OffsetOfElementAt(int index) { return SizeFor(index); } 1974 1975 // Casting. 1976 static inline FixedArray* cast(Object* obj); 1977 1978 // Layout description. 1979 // Length is smi tagged when it is stored. 1980 static const int kLengthOffset = HeapObject::kHeaderSize; 1981 static const int kHeaderSize = kLengthOffset + kPointerSize; 1982 1983 // Maximal allowed size, in bytes, of a single FixedArray. 1984 // Prevents overflowing size computations, as well as extreme memory 1985 // consumption. 1986 static const int kMaxSize = 512 * MB; 1987 // Maximally allowed length of a FixedArray. 1988 static const int kMaxLength = (kMaxSize - kHeaderSize) / kPointerSize; 1989 1990 // Dispatched behavior. 1991 #ifdef OBJECT_PRINT 1992 inline void FixedArrayPrint() { 1993 FixedArrayPrint(stdout); 1994 } 1995 void FixedArrayPrint(FILE* out); 1996 #endif 1997 #ifdef DEBUG 1998 void FixedArrayVerify(); 1999 // Checks if two FixedArrays have identical contents. 2000 bool IsEqualTo(FixedArray* other); 2001 #endif 2002 2003 // Swap two elements in a pair of arrays. If this array and the 2004 // numbers array are the same object, the elements are only swapped 2005 // once. 2006 void SwapPairs(FixedArray* numbers, int i, int j); 2007 2008 // Sort prefix of this array and the numbers array as pairs wrt. the 2009 // numbers. If the numbers array and the this array are the same 2010 // object, the prefix of this array is sorted. 2011 void SortPairs(FixedArray* numbers, uint32_t len); 2012 2013 class BodyDescriptor : public FlexibleBodyDescriptor<kHeaderSize> { 2014 public: 2015 static inline int SizeOf(Map* map, HeapObject* object) { 2016 return SizeFor(reinterpret_cast<FixedArray*>(object)->length()); 2017 } 2018 }; 2019 2020 protected: 2021 // Set operation on FixedArray without using write barriers. Can 2022 // only be used for storing old space objects or smis. 2023 static inline void fast_set(FixedArray* array, int index, Object* value); 2024 2025 private: 2026 DISALLOW_IMPLICIT_CONSTRUCTORS(FixedArray); 2027 }; 2028 2029 2030 // DescriptorArrays are fixed arrays used to hold instance descriptors. 2031 // The format of the these objects is: 2032 // [0]: point to a fixed array with (value, detail) pairs. 2033 // [1]: next enumeration index (Smi), or pointer to small fixed array: 2034 // [0]: next enumeration index (Smi) 2035 // [1]: pointer to fixed array with enum cache 2036 // [2]: first key 2037 // [length() - 1]: last key 2038 // 2039 class DescriptorArray: public FixedArray { 2040 public: 2041 // Is this the singleton empty_descriptor_array? 2042 inline bool IsEmpty(); 2043 2044 // Returns the number of descriptors in the array. 2045 int number_of_descriptors() { 2046 ASSERT(length() > kFirstIndex || IsEmpty()); 2047 int len = length(); 2048 return len <= kFirstIndex ? 0 : len - kFirstIndex; 2049 } 2050 2051 int NextEnumerationIndex() { 2052 if (IsEmpty()) return PropertyDetails::kInitialIndex; 2053 Object* obj = get(kEnumerationIndexIndex); 2054 if (obj->IsSmi()) { 2055 return Smi::cast(obj)->value(); 2056 } else { 2057 Object* index = FixedArray::cast(obj)->get(kEnumCacheBridgeEnumIndex); 2058 return Smi::cast(index)->value(); 2059 } 2060 } 2061 2062 // Set next enumeration index and flush any enum cache. 2063 void SetNextEnumerationIndex(int value) { 2064 if (!IsEmpty()) { 2065 fast_set(this, kEnumerationIndexIndex, Smi::FromInt(value)); 2066 } 2067 } 2068 bool HasEnumCache() { 2069 return !IsEmpty() && !get(kEnumerationIndexIndex)->IsSmi(); 2070 } 2071 2072 Object* GetEnumCache() { 2073 ASSERT(HasEnumCache()); 2074 FixedArray* bridge = FixedArray::cast(get(kEnumerationIndexIndex)); 2075 return bridge->get(kEnumCacheBridgeCacheIndex); 2076 } 2077 2078 // Initialize or change the enum cache, 2079 // using the supplied storage for the small "bridge". 2080 void SetEnumCache(FixedArray* bridge_storage, FixedArray* new_cache); 2081 2082 // Accessors for fetching instance descriptor at descriptor number. 2083 inline String* GetKey(int descriptor_number); 2084 inline Object* GetValue(int descriptor_number); 2085 inline Smi* GetDetails(int descriptor_number); 2086 inline PropertyType GetType(int descriptor_number); 2087 inline int GetFieldIndex(int descriptor_number); 2088 inline JSFunction* GetConstantFunction(int descriptor_number); 2089 inline Object* GetCallbacksObject(int descriptor_number); 2090 inline AccessorDescriptor* GetCallbacks(int descriptor_number); 2091 inline bool IsProperty(int descriptor_number); 2092 inline bool IsTransition(int descriptor_number); 2093 inline bool IsNullDescriptor(int descriptor_number); 2094 inline bool IsDontEnum(int descriptor_number); 2095 2096 // Accessor for complete descriptor. 2097 inline void Get(int descriptor_number, Descriptor* desc); 2098 inline void Set(int descriptor_number, Descriptor* desc); 2099 2100 // Transfer complete descriptor from another descriptor array to 2101 // this one. 2102 inline void CopyFrom(int index, DescriptorArray* src, int src_index); 2103 2104 // Copy the descriptor array, insert a new descriptor and optionally 2105 // remove map transitions. If the descriptor is already present, it is 2106 // replaced. If a replaced descriptor is a real property (not a transition 2107 // or null), its enumeration index is kept as is. 2108 // If adding a real property, map transitions must be removed. If adding 2109 // a transition, they must not be removed. All null descriptors are removed. 2110 MUST_USE_RESULT MaybeObject* CopyInsert(Descriptor* descriptor, 2111 TransitionFlag transition_flag); 2112 2113 // Remove all transitions. Return a copy of the array with all transitions 2114 // removed, or a Failure object if the new array could not be allocated. 2115 MUST_USE_RESULT MaybeObject* RemoveTransitions(); 2116 2117 // Sort the instance descriptors by the hash codes of their keys. 2118 // Does not check for duplicates. 2119 void SortUnchecked(); 2120 2121 // Sort the instance descriptors by the hash codes of their keys. 2122 // Checks the result for duplicates. 2123 void Sort(); 2124 2125 // Search the instance descriptors for given name. 2126 inline int Search(String* name); 2127 2128 // As the above, but uses DescriptorLookupCache and updates it when 2129 // necessary. 2130 inline int SearchWithCache(String* name); 2131 2132 // Tells whether the name is present int the array. 2133 bool Contains(String* name) { return kNotFound != Search(name); } 2134 2135 // Perform a binary search in the instance descriptors represented 2136 // by this fixed array. low and high are descriptor indices. If there 2137 // are three instance descriptors in this array it should be called 2138 // with low=0 and high=2. 2139 int BinarySearch(String* name, int low, int high); 2140 2141 // Perform a linear search in the instance descriptors represented 2142 // by this fixed array. len is the number of descriptor indices that are 2143 // valid. Does not require the descriptors to be sorted. 2144 int LinearSearch(String* name, int len); 2145 2146 // Allocates a DescriptorArray, but returns the singleton 2147 // empty descriptor array object if number_of_descriptors is 0. 2148 MUST_USE_RESULT static MaybeObject* Allocate(int number_of_descriptors); 2149 2150 // Casting. 2151 static inline DescriptorArray* cast(Object* obj); 2152 2153 // Constant for denoting key was not found. 2154 static const int kNotFound = -1; 2155 2156 static const int kContentArrayIndex = 0; 2157 static const int kEnumerationIndexIndex = 1; 2158 static const int kFirstIndex = 2; 2159 2160 // The length of the "bridge" to the enum cache. 2161 static const int kEnumCacheBridgeLength = 2; 2162 static const int kEnumCacheBridgeEnumIndex = 0; 2163 static const int kEnumCacheBridgeCacheIndex = 1; 2164 2165 // Layout description. 2166 static const int kContentArrayOffset = FixedArray::kHeaderSize; 2167 static const int kEnumerationIndexOffset = kContentArrayOffset + kPointerSize; 2168 static const int kFirstOffset = kEnumerationIndexOffset + kPointerSize; 2169 2170 // Layout description for the bridge array. 2171 static const int kEnumCacheBridgeEnumOffset = FixedArray::kHeaderSize; 2172 static const int kEnumCacheBridgeCacheOffset = 2173 kEnumCacheBridgeEnumOffset + kPointerSize; 2174 2175 #ifdef OBJECT_PRINT 2176 // Print all the descriptors. 2177 inline void PrintDescriptors() { 2178 PrintDescriptors(stdout); 2179 } 2180 void PrintDescriptors(FILE* out); 2181 #endif 2182 2183 #ifdef DEBUG 2184 // Is the descriptor array sorted and without duplicates? 2185 bool IsSortedNoDuplicates(); 2186 2187 // Are two DescriptorArrays equal? 2188 bool IsEqualTo(DescriptorArray* other); 2189 #endif 2190 2191 // The maximum number of descriptors we want in a descriptor array (should 2192 // fit in a page). 2193 static const int kMaxNumberOfDescriptors = 1024 + 512; 2194 2195 private: 2196 // Conversion from descriptor number to array indices. 2197 static int ToKeyIndex(int descriptor_number) { 2198 return descriptor_number+kFirstIndex; 2199 } 2200 2201 static int ToDetailsIndex(int descriptor_number) { 2202 return (descriptor_number << 1) + 1; 2203 } 2204 2205 static int ToValueIndex(int descriptor_number) { 2206 return descriptor_number << 1; 2207 } 2208 2209 bool is_null_descriptor(int descriptor_number) { 2210 return PropertyDetails(GetDetails(descriptor_number)).type() == 2211 NULL_DESCRIPTOR; 2212 } 2213 // Swap operation on FixedArray without using write barriers. 2214 static inline void fast_swap(FixedArray* array, int first, int second); 2215 2216 // Swap descriptor first and second. 2217 inline void Swap(int first, int second); 2218 2219 FixedArray* GetContentArray() { 2220 return FixedArray::cast(get(kContentArrayIndex)); 2221 } 2222 DISALLOW_IMPLICIT_CONSTRUCTORS(DescriptorArray); 2223 }; 2224 2225 2226 // HashTable is a subclass of FixedArray that implements a hash table 2227 // that uses open addressing and quadratic probing. 2228 // 2229 // In order for the quadratic probing to work, elements that have not 2230 // yet been used and elements that have been deleted are 2231 // distinguished. Probing continues when deleted elements are 2232 // encountered and stops when unused elements are encountered. 2233 // 2234 // - Elements with key == undefined have not been used yet. 2235 // - Elements with key == null have been deleted. 2236 // 2237 // The hash table class is parameterized with a Shape and a Key. 2238 // Shape must be a class with the following interface: 2239 // class ExampleShape { 2240 // public: 2241 // // Tells whether key matches other. 2242 // static bool IsMatch(Key key, Object* other); 2243 // // Returns the hash value for key. 2244 // static uint32_t Hash(Key key); 2245 // // Returns the hash value for object. 2246 // static uint32_t HashForObject(Key key, Object* object); 2247 // // Convert key to an object. 2248 // static inline Object* AsObject(Key key); 2249 // // The prefix size indicates number of elements in the beginning 2250 // // of the backing storage. 2251 // static const int kPrefixSize = ..; 2252 // // The Element size indicates number of elements per entry. 2253 // static const int kEntrySize = ..; 2254 // }; 2255 // The prefix size indicates an amount of memory in the 2256 // beginning of the backing storage that can be used for non-element 2257 // information by subclasses. 2258 2259 template<typename Shape, typename Key> 2260 class HashTable: public FixedArray { 2261 public: 2262 // Returns the number of elements in the hash table. 2263 int NumberOfElements() { 2264 return Smi::cast(get(kNumberOfElementsIndex))->value(); 2265 } 2266 2267 // Returns the number of deleted elements in the hash table. 2268 int NumberOfDeletedElements() { 2269 return Smi::cast(get(kNumberOfDeletedElementsIndex))->value(); 2270 } 2271 2272 // Returns the capacity of the hash table. 2273 int Capacity() { 2274 return Smi::cast(get(kCapacityIndex))->value(); 2275 } 2276 2277 // ElementAdded should be called whenever an element is added to a 2278 // hash table. 2279 void ElementAdded() { SetNumberOfElements(NumberOfElements() + 1); } 2280 2281 // ElementRemoved should be called whenever an element is removed from 2282 // a hash table. 2283 void ElementRemoved() { 2284 SetNumberOfElements(NumberOfElements() - 1); 2285 SetNumberOfDeletedElements(NumberOfDeletedElements() + 1); 2286 } 2287 void ElementsRemoved(int n) { 2288 SetNumberOfElements(NumberOfElements() - n); 2289 SetNumberOfDeletedElements(NumberOfDeletedElements() + n); 2290 } 2291 2292 // Returns a new HashTable object. Might return Failure. 2293 MUST_USE_RESULT static MaybeObject* Allocate( 2294 int at_least_space_for, 2295 PretenureFlag pretenure = NOT_TENURED); 2296 2297 // Returns the key at entry. 2298 Object* KeyAt(int entry) { return get(EntryToIndex(entry)); } 2299 2300 // Tells whether k is a real key. Null and undefined are not allowed 2301 // as keys and can be used to indicate missing or deleted elements. 2302 bool IsKey(Object* k) { 2303 return !k->IsNull() && !k->IsUndefined(); 2304 } 2305 2306 // Garbage collection support. 2307 void IteratePrefix(ObjectVisitor* visitor); 2308 void IterateElements(ObjectVisitor* visitor); 2309 2310 // Casting. 2311 static inline HashTable* cast(Object* obj); 2312 2313 // Compute the probe offset (quadratic probing). 2314 INLINE(static uint32_t GetProbeOffset(uint32_t n)) { 2315 return (n + n * n) >> 1; 2316 } 2317 2318 static const int kNumberOfElementsIndex = 0; 2319 static const int kNumberOfDeletedElementsIndex = 1; 2320 static const int kCapacityIndex = 2; 2321 static const int kPrefixStartIndex = 3; 2322 static const int kElementsStartIndex = 2323 kPrefixStartIndex + Shape::kPrefixSize; 2324 static const int kEntrySize = Shape::kEntrySize; 2325 static const int kElementsStartOffset = 2326 kHeaderSize + kElementsStartIndex * kPointerSize; 2327 static const int kCapacityOffset = 2328 kHeaderSize + kCapacityIndex * kPointerSize; 2329 2330 // Constant used for denoting a absent entry. 2331 static const int kNotFound = -1; 2332 2333 // Maximal capacity of HashTable. Based on maximal length of underlying 2334 // FixedArray. Staying below kMaxCapacity also ensures that EntryToIndex 2335 // cannot overflow. 2336 static const int kMaxCapacity = 2337 (FixedArray::kMaxLength - kElementsStartOffset) / kEntrySize; 2338 2339 // Find entry for key otherwise return kNotFound. 2340 inline int FindEntry(Key key); 2341 int FindEntry(Isolate* isolate, Key key); 2342 2343 protected: 2344 2345 // Find the entry at which to insert element with the given key that 2346 // has the given hash value. 2347 uint32_t FindInsertionEntry(uint32_t hash); 2348 2349 // Returns the index for an entry (of the key) 2350 static inline int EntryToIndex(int entry) { 2351 return (entry * kEntrySize) + kElementsStartIndex; 2352 } 2353 2354 // Update the number of elements in the hash table. 2355 void SetNumberOfElements(int nof) { 2356 fast_set(this, kNumberOfElementsIndex, Smi::FromInt(nof)); 2357 } 2358 2359 // Update the number of deleted elements in the hash table. 2360 void SetNumberOfDeletedElements(int nod) { 2361 fast_set(this, kNumberOfDeletedElementsIndex, Smi::FromInt(nod)); 2362 } 2363 2364 // Sets the capacity of the hash table. 2365 void SetCapacity(int capacity) { 2366 // To scale a computed hash code to fit within the hash table, we 2367 // use bit-wise AND with a mask, so the capacity must be positive 2368 // and non-zero. 2369 ASSERT(capacity > 0); 2370 ASSERT(capacity <= kMaxCapacity); 2371 fast_set(this, kCapacityIndex, Smi::FromInt(capacity)); 2372 } 2373 2374 2375 // Returns probe entry. 2376 static uint32_t GetProbe(uint32_t hash, uint32_t number, uint32_t size) { 2377 ASSERT(IsPowerOf2(size)); 2378 return (hash + GetProbeOffset(number)) & (size - 1); 2379 } 2380 2381 static uint32_t FirstProbe(uint32_t hash, uint32_t size) { 2382 return hash & (size - 1); 2383 } 2384 2385 static uint32_t NextProbe(uint32_t last, uint32_t number, uint32_t size) { 2386 return (last + number) & (size - 1); 2387 } 2388 2389 // Ensure enough space for n additional elements. 2390 MUST_USE_RESULT MaybeObject* EnsureCapacity(int n, Key key); 2391 }; 2392 2393 2394 2395 // HashTableKey is an abstract superclass for virtual key behavior. 2396 class HashTableKey { 2397 public: 2398 // Returns whether the other object matches this key. 2399 virtual bool IsMatch(Object* other) = 0; 2400 // Returns the hash value for this key. 2401 virtual uint32_t Hash() = 0; 2402 // Returns the hash value for object. 2403 virtual uint32_t HashForObject(Object* key) = 0; 2404 // Returns the key object for storing into the hash table. 2405 // If allocations fails a failure object is returned. 2406 MUST_USE_RESULT virtual MaybeObject* AsObject() = 0; 2407 // Required. 2408 virtual ~HashTableKey() {} 2409 }; 2410 2411 class SymbolTableShape { 2412 public: 2413 static inline bool IsMatch(HashTableKey* key, Object* value) { 2414 return key->IsMatch(value); 2415 } 2416 static inline uint32_t Hash(HashTableKey* key) { 2417 return key->Hash(); 2418 } 2419 static inline uint32_t HashForObject(HashTableKey* key, Object* object) { 2420 return key->HashForObject(object); 2421 } 2422 MUST_USE_RESULT static inline MaybeObject* AsObject(HashTableKey* key) { 2423 return key->AsObject(); 2424 } 2425 2426 static const int kPrefixSize = 0; 2427 static const int kEntrySize = 1; 2428 }; 2429 2430 // SymbolTable. 2431 // 2432 // No special elements in the prefix and the element size is 1 2433 // because only the symbol itself (the key) needs to be stored. 2434 class SymbolTable: public HashTable<SymbolTableShape, HashTableKey*> { 2435 public: 2436 // Find symbol in the symbol table. If it is not there yet, it is 2437 // added. The return value is the symbol table which might have 2438 // been enlarged. If the return value is not a failure, the symbol 2439 // pointer *s is set to the symbol found. 2440 MUST_USE_RESULT MaybeObject* LookupSymbol(Vector<const char> str, Object** s); 2441 MUST_USE_RESULT MaybeObject* LookupAsciiSymbol(Vector<const char> str, 2442 Object** s); 2443 MUST_USE_RESULT MaybeObject* LookupTwoByteSymbol(Vector<const uc16> str, 2444 Object** s); 2445 MUST_USE_RESULT MaybeObject* LookupString(String* key, Object** s); 2446 2447 // Looks up a symbol that is equal to the given string and returns 2448 // true if it is found, assigning the symbol to the given output 2449 // parameter. 2450 bool LookupSymbolIfExists(String* str, String** symbol); 2451 bool LookupTwoCharsSymbolIfExists(uint32_t c1, uint32_t c2, String** symbol); 2452 2453 // Casting. 2454 static inline SymbolTable* cast(Object* obj); 2455 2456 private: 2457 MUST_USE_RESULT MaybeObject* LookupKey(HashTableKey* key, Object** s); 2458 2459 DISALLOW_IMPLICIT_CONSTRUCTORS(SymbolTable); 2460 }; 2461 2462 2463 class MapCacheShape { 2464 public: 2465 static inline bool IsMatch(HashTableKey* key, Object* value) { 2466 return key->IsMatch(value); 2467 } 2468 static inline uint32_t Hash(HashTableKey* key) { 2469 return key->Hash(); 2470 } 2471 2472 static inline uint32_t HashForObject(HashTableKey* key, Object* object) { 2473 return key->HashForObject(object); 2474 } 2475 2476 MUST_USE_RESULT static inline MaybeObject* AsObject(HashTableKey* key) { 2477 return key->AsObject(); 2478 } 2479 2480 static const int kPrefixSize = 0; 2481 static const int kEntrySize = 2; 2482 }; 2483 2484 2485 // MapCache. 2486 // 2487 // Maps keys that are a fixed array of symbols to a map. 2488 // Used for canonicalize maps for object literals. 2489 class MapCache: public HashTable<MapCacheShape, HashTableKey*> { 2490 public: 2491 // Find cached value for a string key, otherwise return null. 2492 Object* Lookup(FixedArray* key); 2493 MUST_USE_RESULT MaybeObject* Put(FixedArray* key, Map* value); 2494 static inline MapCache* cast(Object* obj); 2495 2496 private: 2497 DISALLOW_IMPLICIT_CONSTRUCTORS(MapCache); 2498 }; 2499 2500 2501 template <typename Shape, typename Key> 2502 class Dictionary: public HashTable<Shape, Key> { 2503 public: 2504 2505 static inline Dictionary<Shape, Key>* cast(Object* obj) { 2506 return reinterpret_cast<Dictionary<Shape, Key>*>(obj); 2507 } 2508 2509 // Returns the value at entry. 2510 Object* ValueAt(int entry) { 2511 return this->get(HashTable<Shape, Key>::EntryToIndex(entry)+1); 2512 } 2513 2514 // Set the value for entry. 2515 // Returns false if the put wasn't performed due to property being read only. 2516 // Returns true on successful put. 2517 bool ValueAtPut(int entry, Object* value) { 2518 // Check that this value can actually be written. 2519 PropertyDetails details = DetailsAt(entry); 2520 // If a value has not been initilized we allow writing to it even if 2521 // it is read only (a declared const that has not been initialized). 2522 if (details.IsReadOnly() && !ValueAt(entry)->IsTheHole()) { 2523 return false; 2524 } 2525 this->set(HashTable<Shape, Key>::EntryToIndex(entry) + 1, value); 2526 return true; 2527 } 2528 2529 // Returns the property details for the property at entry. 2530 PropertyDetails DetailsAt(int entry) { 2531 ASSERT(entry >= 0); // Not found is -1, which is not caught by get(). 2532 return PropertyDetails( 2533 Smi::cast(this->get(HashTable<Shape, Key>::EntryToIndex(entry) + 2))); 2534 } 2535 2536 // Set the details for entry. 2537 void DetailsAtPut(int entry, PropertyDetails value) { 2538 this->set(HashTable<Shape, Key>::EntryToIndex(entry) + 2, value.AsSmi()); 2539 } 2540 2541 // Sorting support 2542 void CopyValuesTo(FixedArray* elements); 2543 2544 // Delete a property from the dictionary. 2545 Object* DeleteProperty(int entry, JSObject::DeleteMode mode); 2546 2547 // Returns the number of elements in the dictionary filtering out properties 2548 // with the specified attributes. 2549 int NumberOfElementsFilterAttributes(PropertyAttributes filter); 2550 2551 // Returns the number of enumerable elements in the dictionary. 2552 int NumberOfEnumElements(); 2553 2554 // Copies keys to preallocated fixed array. 2555 void CopyKeysTo(FixedArray* storage, PropertyAttributes filter); 2556 // Fill in details for properties into storage. 2557 void CopyKeysTo(FixedArray* storage, int index); 2558 2559 // Accessors for next enumeration index. 2560 void SetNextEnumerationIndex(int index) { 2561 this->fast_set(this, kNextEnumerationIndexIndex, Smi::FromInt(index)); 2562 } 2563 2564 int NextEnumerationIndex() { 2565 return Smi::cast(FixedArray::get(kNextEnumerationIndexIndex))->value(); 2566 } 2567 2568 // Returns a new array for dictionary usage. Might return Failure. 2569 MUST_USE_RESULT static MaybeObject* Allocate(int at_least_space_for); 2570 2571 // Ensure enough space for n additional elements. 2572 MUST_USE_RESULT MaybeObject* EnsureCapacity(int n, Key key); 2573 2574 #ifdef OBJECT_PRINT 2575 inline void Print() { 2576 Print(stdout); 2577 } 2578 void Print(FILE* out); 2579 #endif 2580 // Returns the key (slow). 2581 Object* SlowReverseLookup(Object* value); 2582 2583 // Sets the entry to (key, value) pair. 2584 inline void SetEntry(int entry, 2585 Object* key, 2586 Object* value); 2587 inline void SetEntry(int entry, 2588 Object* key, 2589 Object* value, 2590 PropertyDetails details); 2591 2592 MUST_USE_RESULT MaybeObject* Add(Key key, 2593 Object* value, 2594 PropertyDetails details); 2595 2596 protected: 2597 // Generic at put operation. 2598 MUST_USE_RESULT MaybeObject* AtPut(Key key, Object* value); 2599 2600 // Add entry to dictionary. 2601 MUST_USE_RESULT MaybeObject* AddEntry(Key key, 2602 Object* value, 2603 PropertyDetails details, 2604 uint32_t hash); 2605 2606 // Generate new enumeration indices to avoid enumeration index overflow. 2607 MUST_USE_RESULT MaybeObject* GenerateNewEnumerationIndices(); 2608 static const int kMaxNumberKeyIndex = 2609 HashTable<Shape, Key>::kPrefixStartIndex; 2610 static const int kNextEnumerationIndexIndex = kMaxNumberKeyIndex + 1; 2611 }; 2612 2613 2614 class StringDictionaryShape { 2615 public: 2616 static inline bool IsMatch(String* key, Object* other); 2617 static inline uint32_t Hash(String* key); 2618 static inline uint32_t HashForObject(String* key, Object* object); 2619 MUST_USE_RESULT static inline MaybeObject* AsObject(String* key); 2620 static const int kPrefixSize = 2; 2621 static const int kEntrySize = 3; 2622 static const bool kIsEnumerable = true; 2623 }; 2624 2625 2626 class StringDictionary: public Dictionary<StringDictionaryShape, String*> { 2627 public: 2628 static inline StringDictionary* cast(Object* obj) { 2629 ASSERT(obj->IsDictionary()); 2630 return reinterpret_cast<StringDictionary*>(obj); 2631 } 2632 2633 // Copies enumerable keys to preallocated fixed array. 2634 void CopyEnumKeysTo(FixedArray* storage, FixedArray* sort_array); 2635 2636 // For transforming properties of a JSObject. 2637 MUST_USE_RESULT MaybeObject* TransformPropertiesToFastFor( 2638 JSObject* obj, 2639 int unused_property_fields); 2640 2641 // Find entry for key otherwise return kNotFound. Optimzed version of 2642 // HashTable::FindEntry. 2643 int FindEntry(String* key); 2644 }; 2645 2646 2647 class NumberDictionaryShape { 2648 public: 2649 static inline bool IsMatch(uint32_t key, Object* other); 2650 static inline uint32_t Hash(uint32_t key); 2651 static inline uint32_t HashForObject(uint32_t key, Object* object); 2652 MUST_USE_RESULT static inline MaybeObject* AsObject(uint32_t key); 2653 static const int kPrefixSize = 2; 2654 static const int kEntrySize = 3; 2655 static const bool kIsEnumerable = false; 2656 }; 2657 2658 2659 class NumberDictionary: public Dictionary<NumberDictionaryShape, uint32_t> { 2660 public: 2661 static NumberDictionary* cast(Object* obj) { 2662 ASSERT(obj->IsDictionary()); 2663 return reinterpret_cast<NumberDictionary*>(obj); 2664 } 2665 2666 // Type specific at put (default NONE attributes is used when adding). 2667 MUST_USE_RESULT MaybeObject* AtNumberPut(uint32_t key, Object* value); 2668 MUST_USE_RESULT MaybeObject* AddNumberEntry(uint32_t key, 2669 Object* value, 2670 PropertyDetails details); 2671 2672 // Set an existing entry or add a new one if needed. 2673 MUST_USE_RESULT MaybeObject* Set(uint32_t key, 2674 Object* value, 2675 PropertyDetails details); 2676 2677 void UpdateMaxNumberKey(uint32_t key); 2678 2679 // If slow elements are required we will never go back to fast-case 2680 // for the elements kept in this dictionary. We require slow 2681 // elements if an element has been added at an index larger than 2682 // kRequiresSlowElementsLimit or set_requires_slow_elements() has been called 2683 // when defining a getter or setter with a number key. 2684 inline bool requires_slow_elements(); 2685 inline void set_requires_slow_elements(); 2686 2687 // Get the value of the max number key that has been added to this 2688 // dictionary. max_number_key can only be called if 2689 // requires_slow_elements returns false. 2690 inline uint32_t max_number_key(); 2691 2692 // Remove all entries were key is a number and (from <= key && key < to). 2693 void RemoveNumberEntries(uint32_t from, uint32_t to); 2694 2695 // Bit masks. 2696 static const int kRequiresSlowElementsMask = 1; 2697 static const int kRequiresSlowElementsTagSize = 1; 2698 static const uint32_t kRequiresSlowElementsLimit = (1 << 29) - 1; 2699 }; 2700 2701 2702 // JSFunctionResultCache caches results of some JSFunction invocation. 2703 // It is a fixed array with fixed structure: 2704 // [0]: factory function 2705 // [1]: finger index 2706 // [2]: current cache size 2707 // [3]: dummy field. 2708 // The rest of array are key/value pairs. 2709 class JSFunctionResultCache: public FixedArray { 2710 public: 2711 static const int kFactoryIndex = 0; 2712 static const int kFingerIndex = kFactoryIndex + 1; 2713 static const int kCacheSizeIndex = kFingerIndex + 1; 2714 static const int kDummyIndex = kCacheSizeIndex + 1; 2715 static const int kEntriesIndex = kDummyIndex + 1; 2716 2717 static const int kEntrySize = 2; // key + value 2718 2719 static const int kFactoryOffset = kHeaderSize; 2720 static const int kFingerOffset = kFactoryOffset + kPointerSize; 2721 static const int kCacheSizeOffset = kFingerOffset + kPointerSize; 2722 2723 inline void MakeZeroSize(); 2724 inline void Clear(); 2725 2726 inline int size(); 2727 inline void set_size(int size); 2728 inline int finger_index(); 2729 inline void set_finger_index(int finger_index); 2730 2731 // Casting 2732 static inline JSFunctionResultCache* cast(Object* obj); 2733 2734 #ifdef DEBUG 2735 void JSFunctionResultCacheVerify(); 2736 #endif 2737 }; 2738 2739 2740 // The cache for maps used by normalized (dictionary mode) objects. 2741 // Such maps do not have property descriptors, so a typical program 2742 // needs very limited number of distinct normalized maps. 2743 class NormalizedMapCache: public FixedArray { 2744 public: 2745 static const int kEntries = 64; 2746 2747 MUST_USE_RESULT MaybeObject* Get(JSObject* object, 2748 PropertyNormalizationMode mode); 2749 2750 void Clear(); 2751 2752 // Casting 2753 static inline NormalizedMapCache* cast(Object* obj); 2754 2755 #ifdef DEBUG 2756 void NormalizedMapCacheVerify(); 2757 #endif 2758 2759 private: 2760 static int Hash(Map* fast); 2761 2762 static bool CheckHit(Map* slow, Map* fast, PropertyNormalizationMode mode); 2763 }; 2764 2765 2766 // ByteArray represents fixed sized byte arrays. Used by the outside world, 2767 // such as PCRE, and also by the memory allocator and garbage collector to 2768 // fill in free blocks in the heap. 2769 class ByteArray: public HeapObject { 2770 public: 2771 // [length]: length of the array. 2772 inline int length(); 2773 inline void set_length(int value); 2774 2775 // Setter and getter. 2776 inline byte get(int index); 2777 inline void set(int index, byte value); 2778 2779 // Treat contents as an int array. 2780 inline int get_int(int index); 2781 2782 static int SizeFor(int length) { 2783 return OBJECT_POINTER_ALIGN(kHeaderSize + length); 2784 } 2785 // We use byte arrays for free blocks in the heap. Given a desired size in 2786 // bytes that is a multiple of the word size and big enough to hold a byte 2787 // array, this function returns the number of elements a byte array should 2788 // have. 2789 static int LengthFor(int size_in_bytes) { 2790 ASSERT(IsAligned(size_in_bytes, kPointerSize)); 2791 ASSERT(size_in_bytes >= kHeaderSize); 2792 return size_in_bytes - kHeaderSize; 2793 } 2794 2795 // Returns data start address. 2796 inline Address GetDataStartAddress(); 2797 2798 // Returns a pointer to the ByteArray object for a given data start address. 2799 static inline ByteArray* FromDataStartAddress(Address address); 2800 2801 // Casting. 2802 static inline ByteArray* cast(Object* obj); 2803 2804 // Dispatched behavior. 2805 inline int ByteArraySize() { 2806 return SizeFor(this->length()); 2807 } 2808 #ifdef OBJECT_PRINT 2809 inline void ByteArrayPrint() { 2810 ByteArrayPrint(stdout); 2811 } 2812 void ByteArrayPrint(FILE* out); 2813 #endif 2814 #ifdef DEBUG 2815 void ByteArrayVerify(); 2816 #endif 2817 2818 // Layout description. 2819 // Length is smi tagged when it is stored. 2820 static const int kLengthOffset = HeapObject::kHeaderSize; 2821 static const int kHeaderSize = kLengthOffset + kPointerSize; 2822 2823 static const int kAlignedSize = OBJECT_POINTER_ALIGN(kHeaderSize); 2824 2825 // Maximal memory consumption for a single ByteArray. 2826 static const int kMaxSize = 512 * MB; 2827 // Maximal length of a single ByteArray. 2828 static const int kMaxLength = kMaxSize - kHeaderSize; 2829 2830 private: 2831 DISALLOW_IMPLICIT_CONSTRUCTORS(ByteArray); 2832 }; 2833 2834 2835 // An ExternalArray represents a fixed-size array of primitive values 2836 // which live outside the JavaScript heap. Its subclasses are used to 2837 // implement the CanvasArray types being defined in the WebGL 2838 // specification. As of this writing the first public draft is not yet 2839 // available, but Khronos members can access the draft at: 2840 // https://cvs.khronos.org/svn/repos/3dweb/trunk/doc/spec/WebGL-spec.html 2841 // 2842 // The semantics of these arrays differ from CanvasPixelArray. 2843 // Out-of-range values passed to the setter are converted via a C 2844 // cast, not clamping. Out-of-range indices cause exceptions to be 2845 // raised rather than being silently ignored. 2846 class ExternalArray: public HeapObject { 2847 public: 2848 // [length]: length of the array. 2849 inline int length(); 2850 inline void set_length(int value); 2851 2852 // [external_pointer]: The pointer to the external memory area backing this 2853 // external array. 2854 DECL_ACCESSORS(external_pointer, void) // Pointer to the data store. 2855 2856 // Casting. 2857 static inline ExternalArray* cast(Object* obj); 2858 2859 // Maximal acceptable length for an external array. 2860 static const int kMaxLength = 0x3fffffff; 2861 2862 // ExternalArray headers are not quadword aligned. 2863 static const int kLengthOffset = HeapObject::kHeaderSize; 2864 static const int kExternalPointerOffset = 2865 POINTER_SIZE_ALIGN(kLengthOffset + kIntSize); 2866 static const int kHeaderSize = kExternalPointerOffset + kPointerSize; 2867 static const int kAlignedSize = OBJECT_POINTER_ALIGN(kHeaderSize); 2868 2869 private: 2870 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalArray); 2871 }; 2872 2873 2874 // A ExternalPixelArray represents a fixed-size byte array with special 2875 // semantics used for implementing the CanvasPixelArray object. Please see the 2876 // specification at: 2877 2878 // http://www.whatwg.org/specs/web-apps/current-work/ 2879 // multipage/the-canvas-element.html#canvaspixelarray 2880 // In particular, write access clamps the value written to 0 or 255 if the 2881 // value written is outside this range. 2882 class ExternalPixelArray: public ExternalArray { 2883 public: 2884 inline uint8_t* external_pixel_pointer(); 2885 2886 // Setter and getter. 2887 inline uint8_t get(int index); 2888 inline void set(int index, uint8_t value); 2889 2890 // This accessor applies the correct conversion from Smi, HeapNumber and 2891 // undefined and clamps the converted value between 0 and 255. 2892 Object* SetValue(uint32_t index, Object* value); 2893 2894 // Casting. 2895 static inline ExternalPixelArray* cast(Object* obj); 2896 2897 #ifdef OBJECT_PRINT 2898 inline void ExternalPixelArrayPrint() { 2899 ExternalPixelArrayPrint(stdout); 2900 } 2901 void ExternalPixelArrayPrint(FILE* out); 2902 #endif 2903 #ifdef DEBUG 2904 void ExternalPixelArrayVerify(); 2905 #endif // DEBUG 2906 2907 private: 2908 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalPixelArray); 2909 }; 2910 2911 2912 class ExternalByteArray: public ExternalArray { 2913 public: 2914 // Setter and getter. 2915 inline int8_t get(int index); 2916 inline void set(int index, int8_t value); 2917 2918 // This accessor applies the correct conversion from Smi, HeapNumber 2919 // and undefined. 2920 MaybeObject* SetValue(uint32_t index, Object* value); 2921 2922 // Casting. 2923 static inline ExternalByteArray* cast(Object* obj); 2924 2925 #ifdef OBJECT_PRINT 2926 inline void ExternalByteArrayPrint() { 2927 ExternalByteArrayPrint(stdout); 2928 } 2929 void ExternalByteArrayPrint(FILE* out); 2930 #endif 2931 #ifdef DEBUG 2932 void ExternalByteArrayVerify(); 2933 #endif // DEBUG 2934 2935 private: 2936 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalByteArray); 2937 }; 2938 2939 2940 class ExternalUnsignedByteArray: public ExternalArray { 2941 public: 2942 // Setter and getter. 2943 inline uint8_t get(int index); 2944 inline void set(int index, uint8_t value); 2945 2946 // This accessor applies the correct conversion from Smi, HeapNumber 2947 // and undefined. 2948 MaybeObject* SetValue(uint32_t index, Object* value); 2949 2950 // Casting. 2951 static inline ExternalUnsignedByteArray* cast(Object* obj); 2952 2953 #ifdef OBJECT_PRINT 2954 inline void ExternalUnsignedByteArrayPrint() { 2955 ExternalUnsignedByteArrayPrint(stdout); 2956 } 2957 void ExternalUnsignedByteArrayPrint(FILE* out); 2958 #endif 2959 #ifdef DEBUG 2960 void ExternalUnsignedByteArrayVerify(); 2961 #endif // DEBUG 2962 2963 private: 2964 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalUnsignedByteArray); 2965 }; 2966 2967 2968 class ExternalShortArray: public ExternalArray { 2969 public: 2970 // Setter and getter. 2971 inline int16_t get(int index); 2972 inline void set(int index, int16_t value); 2973 2974 // This accessor applies the correct conversion from Smi, HeapNumber 2975 // and undefined. 2976 MaybeObject* SetValue(uint32_t index, Object* value); 2977 2978 // Casting. 2979 static inline ExternalShortArray* cast(Object* obj); 2980 2981 #ifdef OBJECT_PRINT 2982 inline void ExternalShortArrayPrint() { 2983 ExternalShortArrayPrint(stdout); 2984 } 2985 void ExternalShortArrayPrint(FILE* out); 2986 #endif 2987 #ifdef DEBUG 2988 void ExternalShortArrayVerify(); 2989 #endif // DEBUG 2990 2991 private: 2992 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalShortArray); 2993 }; 2994 2995 2996 class ExternalUnsignedShortArray: public ExternalArray { 2997 public: 2998 // Setter and getter. 2999 inline uint16_t get(int index); 3000 inline void set(int index, uint16_t value); 3001 3002 // This accessor applies the correct conversion from Smi, HeapNumber 3003 // and undefined. 3004 MaybeObject* SetValue(uint32_t index, Object* value); 3005 3006 // Casting. 3007 static inline ExternalUnsignedShortArray* cast(Object* obj); 3008 3009 #ifdef OBJECT_PRINT 3010 inline void ExternalUnsignedShortArrayPrint() { 3011 ExternalUnsignedShortArrayPrint(stdout); 3012 } 3013 void ExternalUnsignedShortArrayPrint(FILE* out); 3014 #endif 3015 #ifdef DEBUG 3016 void ExternalUnsignedShortArrayVerify(); 3017 #endif // DEBUG 3018 3019 private: 3020 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalUnsignedShortArray); 3021 }; 3022 3023 3024 class ExternalIntArray: public ExternalArray { 3025 public: 3026 // Setter and getter. 3027 inline int32_t get(int index); 3028 inline void set(int index, int32_t value); 3029 3030 // This accessor applies the correct conversion from Smi, HeapNumber 3031 // and undefined. 3032 MaybeObject* SetValue(uint32_t index, Object* value); 3033 3034 // Casting. 3035 static inline ExternalIntArray* cast(Object* obj); 3036 3037 #ifdef OBJECT_PRINT 3038 inline void ExternalIntArrayPrint() { 3039 ExternalIntArrayPrint(stdout); 3040 } 3041 void ExternalIntArrayPrint(FILE* out); 3042 #endif 3043 #ifdef DEBUG 3044 void ExternalIntArrayVerify(); 3045 #endif // DEBUG 3046 3047 private: 3048 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalIntArray); 3049 }; 3050 3051 3052 class ExternalUnsignedIntArray: public ExternalArray { 3053 public: 3054 // Setter and getter. 3055 inline uint32_t get(int index); 3056 inline void set(int index, uint32_t value); 3057 3058 // This accessor applies the correct conversion from Smi, HeapNumber 3059 // and undefined. 3060 MaybeObject* SetValue(uint32_t index, Object* value); 3061 3062 // Casting. 3063 static inline ExternalUnsignedIntArray* cast(Object* obj); 3064 3065 #ifdef OBJECT_PRINT 3066 inline void ExternalUnsignedIntArrayPrint() { 3067 ExternalUnsignedIntArrayPrint(stdout); 3068 } 3069 void ExternalUnsignedIntArrayPrint(FILE* out); 3070 #endif 3071 #ifdef DEBUG 3072 void ExternalUnsignedIntArrayVerify(); 3073 #endif // DEBUG 3074 3075 private: 3076 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalUnsignedIntArray); 3077 }; 3078 3079 3080 class ExternalFloatArray: public ExternalArray { 3081 public: 3082 // Setter and getter. 3083 inline float get(int index); 3084 inline void set(int index, float value); 3085 3086 // This accessor applies the correct conversion from Smi, HeapNumber 3087 // and undefined. 3088 MaybeObject* SetValue(uint32_t index, Object* value); 3089 3090 // Casting. 3091 static inline ExternalFloatArray* cast(Object* obj); 3092 3093 #ifdef OBJECT_PRINT 3094 inline void ExternalFloatArrayPrint() { 3095 ExternalFloatArrayPrint(stdout); 3096 } 3097 void ExternalFloatArrayPrint(FILE* out); 3098 #endif 3099 #ifdef DEBUG 3100 void ExternalFloatArrayVerify(); 3101 #endif // DEBUG 3102 3103 private: 3104 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalFloatArray); 3105 }; 3106 3107 3108 // DeoptimizationInputData is a fixed array used to hold the deoptimization 3109 // data for code generated by the Hydrogen/Lithium compiler. It also 3110 // contains information about functions that were inlined. If N different 3111 // functions were inlined then first N elements of the literal array will 3112 // contain these functions. 3113 // 3114 // It can be empty. 3115 class DeoptimizationInputData: public FixedArray { 3116 public: 3117 // Layout description. Indices in the array. 3118 static const int kTranslationByteArrayIndex = 0; 3119 static const int kInlinedFunctionCountIndex = 1; 3120 static const int kLiteralArrayIndex = 2; 3121 static const int kOsrAstIdIndex = 3; 3122 static const int kOsrPcOffsetIndex = 4; 3123 static const int kFirstDeoptEntryIndex = 5; 3124 3125 // Offsets of deopt entry elements relative to the start of the entry. 3126 static const int kAstIdOffset = 0; 3127 static const int kTranslationIndexOffset = 1; 3128 static const int kArgumentsStackHeightOffset = 2; 3129 static const int kDeoptEntrySize = 3; 3130 3131 // Simple element accessors. 3132 #define DEFINE_ELEMENT_ACCESSORS(name, type) \ 3133 type* name() { \ 3134 return type::cast(get(k##name##Index)); \ 3135 } \ 3136 void Set##name(type* value) { \ 3137 set(k##name##Index, value); \ 3138 } 3139 3140 DEFINE_ELEMENT_ACCESSORS(TranslationByteArray, ByteArray) 3141 DEFINE_ELEMENT_ACCESSORS(InlinedFunctionCount, Smi) 3142 DEFINE_ELEMENT_ACCESSORS(LiteralArray, FixedArray) 3143 DEFINE_ELEMENT_ACCESSORS(OsrAstId, Smi) 3144 DEFINE_ELEMENT_ACCESSORS(OsrPcOffset, Smi) 3145 3146 // Unchecked accessor to be used during GC. 3147 FixedArray* UncheckedLiteralArray() { 3148 return reinterpret_cast<FixedArray*>(get(kLiteralArrayIndex)); 3149 } 3150 3151 #undef DEFINE_ELEMENT_ACCESSORS 3152 3153 // Accessors for elements of the ith deoptimization entry. 3154 #define DEFINE_ENTRY_ACCESSORS(name, type) \ 3155 type* name(int i) { \ 3156 return type::cast(get(IndexForEntry(i) + k##name##Offset)); \ 3157 } \ 3158 void Set##name(int i, type* value) { \ 3159 set(IndexForEntry(i) + k##name##Offset, value); \ 3160 } 3161 3162 DEFINE_ENTRY_ACCESSORS(AstId, Smi) 3163 DEFINE_ENTRY_ACCESSORS(TranslationIndex, Smi) 3164 DEFINE_ENTRY_ACCESSORS(ArgumentsStackHeight, Smi) 3165 3166 #undef DEFINE_ENTRY_ACCESSORS 3167 3168 int DeoptCount() { 3169 return (length() - kFirstDeoptEntryIndex) / kDeoptEntrySize; 3170 } 3171 3172 // Allocates a DeoptimizationInputData. 3173 MUST_USE_RESULT static MaybeObject* Allocate(int deopt_entry_count, 3174 PretenureFlag pretenure); 3175 3176 // Casting. 3177 static inline DeoptimizationInputData* cast(Object* obj); 3178 3179 #ifdef OBJECT_PRINT 3180 void DeoptimizationInputDataPrint(FILE* out); 3181 #endif 3182 3183 private: 3184 static int IndexForEntry(int i) { 3185 return kFirstDeoptEntryIndex + (i * kDeoptEntrySize); 3186 } 3187 3188 static int LengthFor(int entry_count) { 3189 return IndexForEntry(entry_count); 3190 } 3191 }; 3192 3193 3194 // DeoptimizationOutputData is a fixed array used to hold the deoptimization 3195 // data for code generated by the full compiler. 3196 // The format of the these objects is 3197 // [i * 2]: Ast ID for ith deoptimization. 3198 // [i * 2 + 1]: PC and state of ith deoptimization 3199 class DeoptimizationOutputData: public FixedArray { 3200 public: 3201 int DeoptPoints() { return length() / 2; } 3202 Smi* AstId(int index) { return Smi::cast(get(index * 2)); } 3203 void SetAstId(int index, Smi* id) { set(index * 2, id); } 3204 Smi* PcAndState(int index) { return Smi::cast(get(1 + index * 2)); } 3205 void SetPcAndState(int index, Smi* offset) { set(1 + index * 2, offset); } 3206 3207 static int LengthOfFixedArray(int deopt_points) { 3208 return deopt_points * 2; 3209 } 3210 3211 // Allocates a DeoptimizationOutputData. 3212 MUST_USE_RESULT static MaybeObject* Allocate(int number_of_deopt_points, 3213 PretenureFlag pretenure); 3214 3215 // Casting. 3216 static inline DeoptimizationOutputData* cast(Object* obj); 3217 3218 #ifdef OBJECT_PRINT 3219 void DeoptimizationOutputDataPrint(FILE* out); 3220 #endif 3221 }; 3222 3223 3224 class SafepointEntry; 3225 3226 3227 // Code describes objects with on-the-fly generated machine code. 3228 class Code: public HeapObject { 3229 public: 3230 // Opaque data type for encapsulating code flags like kind, inline 3231 // cache state, and arguments count. 3232 // FLAGS_MIN_VALUE and FLAGS_MAX_VALUE are specified to ensure that 3233 // enumeration type has correct value range (see Issue 830 for more details). 3234 enum Flags { 3235 FLAGS_MIN_VALUE = kMinInt, 3236 FLAGS_MAX_VALUE = kMaxInt 3237 }; 3238 3239 enum Kind { 3240 FUNCTION, 3241 OPTIMIZED_FUNCTION, 3242 STUB, 3243 BUILTIN, 3244 LOAD_IC, 3245 KEYED_LOAD_IC, 3246 KEYED_EXTERNAL_ARRAY_LOAD_IC, 3247 CALL_IC, 3248 KEYED_CALL_IC, 3249 STORE_IC, 3250 KEYED_STORE_IC, 3251 KEYED_EXTERNAL_ARRAY_STORE_IC, 3252 TYPE_RECORDING_BINARY_OP_IC, 3253 COMPARE_IC, 3254 // No more than 16 kinds. The value currently encoded in four bits in 3255 // Flags. 3256 3257 // Pseudo-kinds. 3258 REGEXP = BUILTIN, 3259 FIRST_IC_KIND = LOAD_IC, 3260 LAST_IC_KIND = COMPARE_IC 3261 }; 3262 3263 enum { 3264 NUMBER_OF_KINDS = LAST_IC_KIND + 1 3265 }; 3266 3267 typedef int ExtraICState; 3268 3269 static const ExtraICState kNoExtraICState = 0; 3270 3271 #ifdef ENABLE_DISASSEMBLER 3272 // Printing 3273 static const char* Kind2String(Kind kind); 3274 static const char* ICState2String(InlineCacheState state); 3275 static const char* PropertyType2String(PropertyType type); 3276 static void PrintExtraICState(FILE* out, Kind kind, ExtraICState extra); 3277 inline void Disassemble(const char* name) { 3278 Disassemble(name, stdout); 3279 } 3280 void Disassemble(const char* name, FILE* out); 3281 #endif // ENABLE_DISASSEMBLER 3282 3283 // [instruction_size]: Size of the native instructions 3284 inline int instruction_size(); 3285 inline void set_instruction_size(int value); 3286 3287 // [relocation_info]: Code relocation information 3288 DECL_ACCESSORS(relocation_info, ByteArray) 3289 void InvalidateRelocation(); 3290 3291 // [deoptimization_data]: Array containing data for deopt. 3292 DECL_ACCESSORS(deoptimization_data, FixedArray) 3293 3294 // Unchecked accessors to be used during GC. 3295 inline ByteArray* unchecked_relocation_info(); 3296 inline FixedArray* unchecked_deoptimization_data(); 3297 3298 inline int relocation_size(); 3299 3300 // [flags]: Various code flags. 3301 inline Flags flags(); 3302 inline void set_flags(Flags flags); 3303 3304 // [flags]: Access to specific code flags. 3305 inline Kind kind(); 3306 inline InlineCacheState ic_state(); // Only valid for IC stubs. 3307 inline ExtraICState extra_ic_state(); // Only valid for IC stubs. 3308 inline InLoopFlag ic_in_loop(); // Only valid for IC stubs. 3309 inline PropertyType type(); // Only valid for monomorphic IC stubs. 3310 inline int arguments_count(); // Only valid for call IC stubs. 3311 3312 // Testers for IC stub kinds. 3313 inline bool is_inline_cache_stub(); 3314 inline bool is_load_stub() { return kind() == LOAD_IC; } 3315 inline bool is_keyed_load_stub() { return kind() == KEYED_LOAD_IC; } 3316 inline bool is_store_stub() { return kind() == STORE_IC; } 3317 inline bool is_keyed_store_stub() { return kind() == KEYED_STORE_IC; } 3318 inline bool is_call_stub() { return kind() == CALL_IC; } 3319 inline bool is_keyed_call_stub() { return kind() == KEYED_CALL_IC; } 3320 inline bool is_type_recording_binary_op_stub() { 3321 return kind() == TYPE_RECORDING_BINARY_OP_IC; 3322 } 3323 inline bool is_compare_ic_stub() { return kind() == COMPARE_IC; } 3324 inline bool is_external_array_load_stub() { 3325 return kind() == KEYED_EXTERNAL_ARRAY_LOAD_IC; 3326 } 3327 inline bool is_external_array_store_stub() { 3328 return kind() == KEYED_EXTERNAL_ARRAY_STORE_IC; 3329 } 3330 3331 // [major_key]: For kind STUB or BINARY_OP_IC, the major key. 3332 inline int major_key(); 3333 inline void set_major_key(int value); 3334 3335 // [optimizable]: For FUNCTION kind, tells if it is optimizable. 3336 inline bool optimizable(); 3337 inline void set_optimizable(bool value); 3338 3339 // [has_deoptimization_support]: For FUNCTION kind, tells if it has 3340 // deoptimization support. 3341 inline bool has_deoptimization_support(); 3342 inline void set_has_deoptimization_support(bool value); 3343 3344 // [allow_osr_at_loop_nesting_level]: For FUNCTION kind, tells for 3345 // how long the function has been marked for OSR and therefore which 3346 // level of loop nesting we are willing to do on-stack replacement 3347 // for. 3348 inline void set_allow_osr_at_loop_nesting_level(int level); 3349 inline int allow_osr_at_loop_nesting_level(); 3350 3351 // [stack_slots]: For kind OPTIMIZED_FUNCTION, the number of stack slots 3352 // reserved in the code prologue. 3353 inline unsigned stack_slots(); 3354 inline void set_stack_slots(unsigned slots); 3355 3356 // [safepoint_table_start]: For kind OPTIMIZED_CODE, the offset in 3357 // the instruction stream where the safepoint table starts. 3358 inline unsigned safepoint_table_offset(); 3359 inline void set_safepoint_table_offset(unsigned offset); 3360 3361 // [stack_check_table_start]: For kind FUNCTION, the offset in the 3362 // instruction stream where the stack check table starts. 3363 inline unsigned stack_check_table_offset(); 3364 inline void set_stack_check_table_offset(unsigned offset); 3365 3366 // [check type]: For kind CALL_IC, tells how to check if the 3367 // receiver is valid for the given call. 3368 inline CheckType check_type(); 3369 inline void set_check_type(CheckType value); 3370 3371 // [external array type]: For kind KEYED_EXTERNAL_ARRAY_LOAD_IC and 3372 // KEYED_EXTERNAL_ARRAY_STORE_IC, identifies the type of external 3373 // array that the code stub is specialized for. 3374 inline ExternalArrayType external_array_type(); 3375 inline void set_external_array_type(ExternalArrayType value); 3376 3377 // [type-recording binary op type]: For all TYPE_RECORDING_BINARY_OP_IC. 3378 inline byte type_recording_binary_op_type(); 3379 inline void set_type_recording_binary_op_type(byte value); 3380 inline byte type_recording_binary_op_result_type(); 3381 inline void set_type_recording_binary_op_result_type(byte value); 3382 3383 // [compare state]: For kind compare IC stubs, tells what state the 3384 // stub is in. 3385 inline byte compare_state(); 3386 inline void set_compare_state(byte value); 3387 3388 // Get the safepoint entry for the given pc. 3389 SafepointEntry GetSafepointEntry(Address pc); 3390 3391 // Mark this code object as not having a stack check table. Assumes kind 3392 // is FUNCTION. 3393 void SetNoStackCheckTable(); 3394 3395 // Find the first map in an IC stub. 3396 Map* FindFirstMap(); 3397 3398 // Flags operations. 3399 static inline Flags ComputeFlags( 3400 Kind kind, 3401 InLoopFlag in_loop = NOT_IN_LOOP, 3402 InlineCacheState ic_state = UNINITIALIZED, 3403 ExtraICState extra_ic_state = kNoExtraICState, 3404 PropertyType type = NORMAL, 3405 int argc = -1, 3406 InlineCacheHolderFlag holder = OWN_MAP); 3407 3408 static inline Flags ComputeMonomorphicFlags( 3409 Kind kind, 3410 PropertyType type, 3411 ExtraICState extra_ic_state = kNoExtraICState, 3412 InlineCacheHolderFlag holder = OWN_MAP, 3413 InLoopFlag in_loop = NOT_IN_LOOP, 3414 int argc = -1); 3415 3416 static inline Kind ExtractKindFromFlags(Flags flags); 3417 static inline InlineCacheState ExtractICStateFromFlags(Flags flags); 3418 static inline ExtraICState ExtractExtraICStateFromFlags(Flags flags); 3419 static inline InLoopFlag ExtractICInLoopFromFlags(Flags flags); 3420 static inline PropertyType ExtractTypeFromFlags(Flags flags); 3421 static inline int ExtractArgumentsCountFromFlags(Flags flags); 3422 static inline InlineCacheHolderFlag ExtractCacheHolderFromFlags(Flags flags); 3423 static inline Flags RemoveTypeFromFlags(Flags flags); 3424 3425 // Convert a target address into a code object. 3426 static inline Code* GetCodeFromTargetAddress(Address address); 3427 3428 // Convert an entry address into an object. 3429 static inline Object* GetObjectFromEntryAddress(Address location_of_address); 3430 3431 // Returns the address of the first instruction. 3432 inline byte* instruction_start(); 3433 3434 // Returns the address right after the last instruction. 3435 inline byte* instruction_end(); 3436 3437 // Returns the size of the instructions, padding, and relocation information. 3438 inline int body_size(); 3439 3440 // Returns the address of the first relocation info (read backwards!). 3441 inline byte* relocation_start(); 3442 3443 // Code entry point. 3444 inline byte* entry(); 3445 3446 // Returns true if pc is inside this object's instructions. 3447 inline bool contains(byte* pc); 3448 3449 // Relocate the code by delta bytes. Called to signal that this code 3450 // object has been moved by delta bytes. 3451 void Relocate(intptr_t delta); 3452 3453 // Migrate code described by desc. 3454 void CopyFrom(const CodeDesc& desc); 3455 3456 // Returns the object size for a given body (used for allocation). 3457 static int SizeFor(int body_size) { 3458 ASSERT_SIZE_TAG_ALIGNED(body_size); 3459 return RoundUp(kHeaderSize + body_size, kCodeAlignment); 3460 } 3461 3462 // Calculate the size of the code object to report for log events. This takes 3463 // the layout of the code object into account. 3464 int ExecutableSize() { 3465 // Check that the assumptions about the layout of the code object holds. 3466 ASSERT_EQ(static_cast<int>(instruction_start() - address()), 3467 Code::kHeaderSize); 3468 return instruction_size() + Code::kHeaderSize; 3469 } 3470 3471 // Locating source position. 3472 int SourcePosition(Address pc); 3473 int SourceStatementPosition(Address pc); 3474 3475 // Casting. 3476 static inline Code* cast(Object* obj); 3477 3478 // Dispatched behavior. 3479 int CodeSize() { return SizeFor(body_size()); } 3480 inline void CodeIterateBody(ObjectVisitor* v); 3481 3482 template<typename StaticVisitor> 3483 inline void CodeIterateBody(Heap* heap); 3484 #ifdef OBJECT_PRINT 3485 inline void CodePrint() { 3486 CodePrint(stdout); 3487 } 3488 void CodePrint(FILE* out); 3489 #endif 3490 #ifdef DEBUG 3491 void CodeVerify(); 3492 #endif 3493 3494 // Returns the isolate/heap this code object belongs to. 3495 inline Isolate* isolate(); 3496 inline Heap* heap(); 3497 3498 // Max loop nesting marker used to postpose OSR. We don't take loop 3499 // nesting that is deeper than 5 levels into account. 3500 static const int kMaxLoopNestingMarker = 6; 3501 3502 // Layout description. 3503 static const int kInstructionSizeOffset = HeapObject::kHeaderSize; 3504 static const int kRelocationInfoOffset = kInstructionSizeOffset + kIntSize; 3505 static const int kDeoptimizationDataOffset = 3506 kRelocationInfoOffset + kPointerSize; 3507 static const int kFlagsOffset = kDeoptimizationDataOffset + kPointerSize; 3508 static const int kKindSpecificFlagsOffset = kFlagsOffset + kIntSize; 3509 3510 static const int kKindSpecificFlagsSize = 2 * kIntSize; 3511 3512 static const int kHeaderPaddingStart = kKindSpecificFlagsOffset + 3513 kKindSpecificFlagsSize; 3514 3515 // Add padding to align the instruction start following right after 3516 // the Code object header. 3517 static const int kHeaderSize = 3518 (kHeaderPaddingStart + kCodeAlignmentMask) & ~kCodeAlignmentMask; 3519 3520 // Byte offsets within kKindSpecificFlagsOffset. 3521 static const int kStubMajorKeyOffset = kKindSpecificFlagsOffset; 3522 static const int kOptimizableOffset = kKindSpecificFlagsOffset; 3523 static const int kStackSlotsOffset = kKindSpecificFlagsOffset; 3524 static const int kCheckTypeOffset = kKindSpecificFlagsOffset; 3525 static const int kExternalArrayTypeOffset = kKindSpecificFlagsOffset; 3526 3527 static const int kCompareStateOffset = kStubMajorKeyOffset + 1; 3528 static const int kBinaryOpTypeOffset = kStubMajorKeyOffset + 1; 3529 static const int kHasDeoptimizationSupportOffset = kOptimizableOffset + 1; 3530 3531 static const int kBinaryOpReturnTypeOffset = kBinaryOpTypeOffset + 1; 3532 static const int kAllowOSRAtLoopNestingLevelOffset = 3533 kHasDeoptimizationSupportOffset + 1; 3534 3535 static const int kSafepointTableOffsetOffset = kStackSlotsOffset + kIntSize; 3536 static const int kStackCheckTableOffsetOffset = kStackSlotsOffset + kIntSize; 3537 3538 // Flags layout. 3539 static const int kFlagsICStateShift = 0; 3540 static const int kFlagsICInLoopShift = 3; 3541 static const int kFlagsTypeShift = 4; 3542 static const int kFlagsKindShift = 8; 3543 static const int kFlagsICHolderShift = 12; 3544 static const int kFlagsExtraICStateShift = 13; 3545 static const int kFlagsArgumentsCountShift = 15; 3546 3547 static const int kFlagsICStateMask = 0x00000007; // 00000000111 3548 static const int kFlagsICInLoopMask = 0x00000008; // 00000001000 3549 static const int kFlagsTypeMask = 0x000000F0; // 00001110000 3550 static const int kFlagsKindMask = 0x00000F00; // 11110000000 3551 static const int kFlagsCacheInPrototypeMapMask = 0x00001000; 3552 static const int kFlagsExtraICStateMask = 0x00006000; 3553 static const int kFlagsArgumentsCountMask = 0xFFFF8000; 3554 3555 static const int kFlagsNotUsedInLookup = 3556 (kFlagsICInLoopMask | kFlagsTypeMask | kFlagsCacheInPrototypeMapMask); 3557 3558 private: 3559 DISALLOW_IMPLICIT_CONSTRUCTORS(Code); 3560 }; 3561 3562 3563 // All heap objects have a Map that describes their structure. 3564 // A Map contains information about: 3565 // - Size information about the object 3566 // - How to iterate over an object (for garbage collection) 3567 class Map: public HeapObject { 3568 public: 3569 // Instance size. 3570 // Size in bytes or kVariableSizeSentinel if instances do not have 3571 // a fixed size. 3572 inline int instance_size(); 3573 inline void set_instance_size(int value); 3574 3575 // Count of properties allocated in the object. 3576 inline int inobject_properties(); 3577 inline void set_inobject_properties(int value); 3578 3579 // Count of property fields pre-allocated in the object when first allocated. 3580 inline int pre_allocated_property_fields(); 3581 inline void set_pre_allocated_property_fields(int value); 3582 3583 // Instance type. 3584 inline InstanceType instance_type(); 3585 inline void set_instance_type(InstanceType value); 3586 3587 // Tells how many unused property fields are available in the 3588 // instance (only used for JSObject in fast mode). 3589 inline int unused_property_fields(); 3590 inline void set_unused_property_fields(int value); 3591 3592 // Bit field. 3593 inline byte bit_field(); 3594 inline void set_bit_field(byte value); 3595 3596 // Bit field 2. 3597 inline byte bit_field2(); 3598 inline void set_bit_field2(byte value); 3599 3600 // Tells whether the object in the prototype property will be used 3601 // for instances created from this function. If the prototype 3602 // property is set to a value that is not a JSObject, the prototype 3603 // property will not be used to create instances of the function. 3604 // See ECMA-262, 13.2.2. 3605 inline void set_non_instance_prototype(bool value); 3606 inline bool has_non_instance_prototype(); 3607 3608 // Tells whether function has special prototype property. If not, prototype 3609 // property will not be created when accessed (will return undefined), 3610 // and construction from this function will not be allowed. 3611 inline void set_function_with_prototype(bool value); 3612 inline bool function_with_prototype(); 3613 3614 // Tells whether the instance with this map should be ignored by the 3615 // __proto__ accessor. 3616 inline void set_is_hidden_prototype() { 3617 set_bit_field(bit_field() | (1 << kIsHiddenPrototype)); 3618 } 3619 3620 inline bool is_hidden_prototype() { 3621 return ((1 << kIsHiddenPrototype) & bit_field()) != 0; 3622 } 3623 3624 // Records and queries whether the instance has a named interceptor. 3625 inline void set_has_named_interceptor() { 3626 set_bit_field(bit_field() | (1 << kHasNamedInterceptor)); 3627 } 3628 3629 inline bool has_named_interceptor() { 3630 return ((1 << kHasNamedInterceptor) & bit_field()) != 0; 3631 } 3632 3633 // Records and queries whether the instance has an indexed interceptor. 3634 inline void set_has_indexed_interceptor() { 3635 set_bit_field(bit_field() | (1 << kHasIndexedInterceptor)); 3636 } 3637 3638 inline bool has_indexed_interceptor() { 3639 return ((1 << kHasIndexedInterceptor) & bit_field()) != 0; 3640 } 3641 3642 // Tells whether the instance is undetectable. 3643 // An undetectable object is a special class of JSObject: 'typeof' operator 3644 // returns undefined, ToBoolean returns false. Otherwise it behaves like 3645 // a normal JS object. It is useful for implementing undetectable 3646 // document.all in Firefox & Safari. 3647 // See https://bugzilla.mozilla.org/show_bug.cgi?id=248549. 3648 inline void set_is_undetectable() { 3649 set_bit_field(bit_field() | (1 << kIsUndetectable)); 3650 } 3651 3652 inline bool is_undetectable() { 3653 return ((1 << kIsUndetectable) & bit_field()) != 0; 3654 } 3655 3656 // Tells whether the instance has a call-as-function handler. 3657 inline void set_has_instance_call_handler() { 3658 set_bit_field(bit_field() | (1 << kHasInstanceCallHandler)); 3659 } 3660 3661 inline bool has_instance_call_handler() { 3662 return ((1 << kHasInstanceCallHandler) & bit_field()) != 0; 3663 } 3664 3665 inline void set_is_extensible(bool value); 3666 inline bool is_extensible(); 3667 3668 // Tells whether the instance has fast elements. 3669 // Equivalent to instance->GetElementsKind() == FAST_ELEMENTS. 3670 inline void set_has_fast_elements(bool value) { 3671 if (value) { 3672 set_bit_field2(bit_field2() | (1 << kHasFastElements)); 3673 } else { 3674 set_bit_field2(bit_field2() & ~(1 << kHasFastElements)); 3675 } 3676 } 3677 3678 inline bool has_fast_elements() { 3679 return ((1 << kHasFastElements) & bit_field2()) != 0; 3680 } 3681 3682 // Tells whether an instance has pixel array elements. 3683 inline void set_has_external_array_elements(bool value) { 3684 if (value) { 3685 set_bit_field2(bit_field2() | (1 << kHasExternalArrayElements)); 3686 } else { 3687 set_bit_field2(bit_field2() & ~(1 << kHasExternalArrayElements)); 3688 } 3689 } 3690 3691 inline bool has_external_array_elements() { 3692 return ((1 << kHasExternalArrayElements) & bit_field2()) != 0; 3693 } 3694 3695 // Tells whether the map is attached to SharedFunctionInfo 3696 // (for inobject slack tracking). 3697 inline void set_attached_to_shared_function_info(bool value); 3698 3699 inline bool attached_to_shared_function_info(); 3700 3701 // Tells whether the map is shared between objects that may have different 3702 // behavior. If true, the map should never be modified, instead a clone 3703 // should be created and modified. 3704 inline void set_is_shared(bool value); 3705 3706 inline bool is_shared(); 3707 3708 // Tells whether the instance needs security checks when accessing its 3709 // properties. 3710 inline void set_is_access_check_needed(bool access_check_needed); 3711 inline bool is_access_check_needed(); 3712 3713 // [prototype]: implicit prototype object. 3714 DECL_ACCESSORS(prototype, Object) 3715 3716 // [constructor]: points back to the function responsible for this map. 3717 DECL_ACCESSORS(constructor, Object) 3718 3719 inline JSFunction* unchecked_constructor(); 3720 3721 // [instance descriptors]: describes the object. 3722 DECL_ACCESSORS(instance_descriptors, DescriptorArray) 3723 3724 // [stub cache]: contains stubs compiled for this map. 3725 DECL_ACCESSORS(code_cache, Object) 3726 3727 // [prototype transitions]: cache of prototype transitions. 3728 // Prototype transition is a transition that happens 3729 // when we change object's prototype to a new one. 3730 // Cache format: 3731 // 0: finger - index of the first free cell in the cache 3732 // 1 + 2 * i: prototype 3733 // 2 + 2 * i: target map 3734 DECL_ACCESSORS(prototype_transitions, FixedArray) 3735 inline FixedArray* unchecked_prototype_transitions(); 3736 3737 // Lookup in the map's instance descriptors and fill out the result 3738 // with the given holder if the name is found. The holder may be 3739 // NULL when this function is used from the compiler. 3740 void LookupInDescriptors(JSObject* holder, 3741 String* name, 3742 LookupResult* result); 3743 3744 MUST_USE_RESULT MaybeObject* CopyDropDescriptors(); 3745 3746 MUST_USE_RESULT MaybeObject* CopyNormalized(PropertyNormalizationMode mode, 3747 NormalizedMapSharingMode sharing); 3748 3749 // Returns a copy of the map, with all transitions dropped from the 3750 // instance descriptors. 3751 MUST_USE_RESULT MaybeObject* CopyDropTransitions(); 3752 3753 // Returns this map if it has the fast elements bit set, otherwise 3754 // returns a copy of the map, with all transitions dropped from the 3755 // descriptors and the fast elements bit set. 3756 MUST_USE_RESULT inline MaybeObject* GetFastElementsMap(); 3757 3758 // Returns this map if it has the fast elements bit cleared, 3759 // otherwise returns a copy of the map, with all transitions dropped 3760 // from the descriptors and the fast elements bit cleared. 3761 MUST_USE_RESULT inline MaybeObject* GetSlowElementsMap(); 3762 3763 // Returns a new map with all transitions dropped from the descriptors and the 3764 // external array elements bit set. 3765 MUST_USE_RESULT MaybeObject* GetExternalArrayElementsMap( 3766 ExternalArrayType array_type, 3767 bool safe_to_add_transition); 3768 3769 // Returns the property index for name (only valid for FAST MODE). 3770 int PropertyIndexFor(String* name); 3771 3772 // Returns the next free property index (only valid for FAST MODE). 3773 int NextFreePropertyIndex(); 3774 3775 // Returns the number of properties described in instance_descriptors. 3776 int NumberOfDescribedProperties(); 3777 3778 // Casting. 3779 static inline Map* cast(Object* obj); 3780 3781 // Locate an accessor in the instance descriptor. 3782 AccessorDescriptor* FindAccessor(String* name); 3783 3784 // Code cache operations. 3785 3786 // Clears the code cache. 3787 inline void ClearCodeCache(Heap* heap); 3788 3789 // Update code cache. 3790 MUST_USE_RESULT MaybeObject* UpdateCodeCache(String* name, Code* code); 3791 3792 // Returns the found code or undefined if absent. 3793 Object* FindInCodeCache(String* name, Code::Flags flags); 3794 3795 // Returns the non-negative index of the code object if it is in the 3796 // cache and -1 otherwise. 3797 int IndexInCodeCache(Object* name, Code* code); 3798 3799 // Removes a code object from the code cache at the given index. 3800 void RemoveFromCodeCache(String* name, Code* code, int index); 3801 3802 // For every transition in this map, makes the transition's 3803 // target's prototype pointer point back to this map. 3804 // This is undone in MarkCompactCollector::ClearNonLiveTransitions(). 3805 void CreateBackPointers(); 3806 3807 // Set all map transitions from this map to dead maps to null. 3808 // Also, restore the original prototype on the targets of these 3809 // transitions, so that we do not process this map again while 3810 // following back pointers. 3811 void ClearNonLiveTransitions(Heap* heap, Object* real_prototype); 3812 3813 // Dispatched behavior. 3814 #ifdef OBJECT_PRINT 3815 inline void MapPrint() { 3816 MapPrint(stdout); 3817 } 3818 void MapPrint(FILE* out); 3819 #endif 3820 #ifdef DEBUG 3821 void MapVerify(); 3822 void SharedMapVerify(); 3823 #endif 3824 3825 inline int visitor_id(); 3826 inline void set_visitor_id(int visitor_id); 3827 3828 // Returns the isolate/heap this map belongs to. 3829 inline Isolate* isolate(); 3830 inline Heap* heap(); 3831 3832 typedef void (*TraverseCallback)(Map* map, void* data); 3833 3834 void TraverseTransitionTree(TraverseCallback callback, void* data); 3835 3836 static const int kMaxCachedPrototypeTransitions = 256; 3837 3838 Object* GetPrototypeTransition(Object* prototype); 3839 3840 MaybeObject* PutPrototypeTransition(Object* prototype, Map* map); 3841 3842 static const int kMaxPreAllocatedPropertyFields = 255; 3843 3844 // Layout description. 3845 static const int kInstanceSizesOffset = HeapObject::kHeaderSize; 3846 static const int kInstanceAttributesOffset = kInstanceSizesOffset + kIntSize; 3847 static const int kPrototypeOffset = kInstanceAttributesOffset + kIntSize; 3848 static const int kConstructorOffset = kPrototypeOffset + kPointerSize; 3849 static const int kInstanceDescriptorsOffset = 3850 kConstructorOffset + kPointerSize; 3851 static const int kCodeCacheOffset = kInstanceDescriptorsOffset + kPointerSize; 3852 static const int kPrototypeTransitionsOffset = 3853 kCodeCacheOffset + kPointerSize; 3854 static const int kPadStart = kPrototypeTransitionsOffset + kPointerSize; 3855 static const int kSize = MAP_POINTER_ALIGN(kPadStart); 3856 3857 // Layout of pointer fields. Heap iteration code relies on them 3858 // being continiously allocated. 3859 static const int kPointerFieldsBeginOffset = Map::kPrototypeOffset; 3860 static const int kPointerFieldsEndOffset = 3861 Map::kPrototypeTransitionsOffset + kPointerSize; 3862 3863 // Byte offsets within kInstanceSizesOffset. 3864 static const int kInstanceSizeOffset = kInstanceSizesOffset + 0; 3865 static const int kInObjectPropertiesByte = 1; 3866 static const int kInObjectPropertiesOffset = 3867 kInstanceSizesOffset + kInObjectPropertiesByte; 3868 static const int kPreAllocatedPropertyFieldsByte = 2; 3869 static const int kPreAllocatedPropertyFieldsOffset = 3870 kInstanceSizesOffset + kPreAllocatedPropertyFieldsByte; 3871 static const int kVisitorIdByte = 3; 3872 static const int kVisitorIdOffset = kInstanceSizesOffset + kVisitorIdByte; 3873 3874 // Byte offsets within kInstanceAttributesOffset attributes. 3875 static const int kInstanceTypeOffset = kInstanceAttributesOffset + 0; 3876 static const int kUnusedPropertyFieldsOffset = kInstanceAttributesOffset + 1; 3877 static const int kBitFieldOffset = kInstanceAttributesOffset + 2; 3878 static const int kBitField2Offset = kInstanceAttributesOffset + 3; 3879 3880 STATIC_CHECK(kInstanceTypeOffset == Internals::kMapInstanceTypeOffset); 3881 3882 // Bit positions for bit field. 3883 static const int kUnused = 0; // To be used for marking recently used maps. 3884 static const int kHasNonInstancePrototype = 1; 3885 static const int kIsHiddenPrototype = 2; 3886 static const int kHasNamedInterceptor = 3; 3887 static const int kHasIndexedInterceptor = 4; 3888 static const int kIsUndetectable = 5; 3889 static const int kHasInstanceCallHandler = 6; 3890 static const int kIsAccessCheckNeeded = 7; 3891 3892 // Bit positions for bit field 2 3893 static const int kIsExtensible = 0; 3894 static const int kFunctionWithPrototype = 1; 3895 static const int kHasFastElements = 2; 3896 static const int kStringWrapperSafeForDefaultValueOf = 3; 3897 static const int kAttachedToSharedFunctionInfo = 4; 3898 static const int kIsShared = 5; 3899 static const int kHasExternalArrayElements = 6; 3900 3901 // Layout of the default cache. It holds alternating name and code objects. 3902 static const int kCodeCacheEntrySize = 2; 3903 static const int kCodeCacheEntryNameOffset = 0; 3904 static const int kCodeCacheEntryCodeOffset = 1; 3905 3906 typedef FixedBodyDescriptor<kPointerFieldsBeginOffset, 3907 kPointerFieldsEndOffset, 3908 kSize> BodyDescriptor; 3909 3910 private: 3911 DISALLOW_IMPLICIT_CONSTRUCTORS(Map); 3912 }; 3913 3914 3915 // An abstract superclass, a marker class really, for simple structure classes. 3916 // It doesn't carry much functionality but allows struct classes to me 3917 // identified in the type system. 3918 class Struct: public HeapObject { 3919 public: 3920 inline void InitializeBody(int object_size); 3921 static inline Struct* cast(Object* that); 3922 }; 3923 3924 3925 // Script describes a script which has been added to the VM. 3926 class Script: public Struct { 3927 public: 3928 // Script types. 3929 enum Type { 3930 TYPE_NATIVE = 0, 3931 TYPE_EXTENSION = 1, 3932 TYPE_NORMAL = 2 3933 }; 3934 3935 // Script compilation types. 3936 enum CompilationType { 3937 COMPILATION_TYPE_HOST = 0, 3938 COMPILATION_TYPE_EVAL = 1 3939 }; 3940 3941 // [source]: the script source. 3942 DECL_ACCESSORS(source, Object) 3943 3944 // [name]: the script name. 3945 DECL_ACCESSORS(name, Object) 3946 3947 // [id]: the script id. 3948 DECL_ACCESSORS(id, Object) 3949 3950 // [line_offset]: script line offset in resource from where it was extracted. 3951 DECL_ACCESSORS(line_offset, Smi) 3952 3953 // [column_offset]: script column offset in resource from where it was 3954 // extracted. 3955 DECL_ACCESSORS(column_offset, Smi) 3956 3957 // [data]: additional data associated with this script. 3958 DECL_ACCESSORS(data, Object) 3959 3960 // [context_data]: context data for the context this script was compiled in. 3961 DECL_ACCESSORS(context_data, Object) 3962 3963 // [wrapper]: the wrapper cache. 3964 DECL_ACCESSORS(wrapper, Proxy) 3965 3966 // [type]: the script type. 3967 DECL_ACCESSORS(type, Smi) 3968 3969 // [compilation]: how the the script was compiled. 3970 DECL_ACCESSORS(compilation_type, Smi) 3971 3972 // [line_ends]: FixedArray of line ends positions. 3973 DECL_ACCESSORS(line_ends, Object) 3974 3975 // [eval_from_shared]: for eval scripts the shared funcion info for the 3976 // function from which eval was called. 3977 DECL_ACCESSORS(eval_from_shared, Object) 3978 3979 // [eval_from_instructions_offset]: the instruction offset in the code for the 3980 // function from which eval was called where eval was called. 3981 DECL_ACCESSORS(eval_from_instructions_offset, Smi) 3982 3983 static inline Script* cast(Object* obj); 3984 3985 // If script source is an external string, check that the underlying 3986 // resource is accessible. Otherwise, always return true. 3987 inline bool HasValidSource(); 3988 3989 #ifdef OBJECT_PRINT 3990 inline void ScriptPrint() { 3991 ScriptPrint(stdout); 3992 } 3993 void ScriptPrint(FILE* out); 3994 #endif 3995 #ifdef DEBUG 3996 void ScriptVerify(); 3997 #endif 3998 3999 static const int kSourceOffset = HeapObject::kHeaderSize; 4000 static const int kNameOffset = kSourceOffset + kPointerSize; 4001 static const int kLineOffsetOffset = kNameOffset + kPointerSize; 4002 static const int kColumnOffsetOffset = kLineOffsetOffset + kPointerSize; 4003 static const int kDataOffset = kColumnOffsetOffset + kPointerSize; 4004 static const int kContextOffset = kDataOffset + kPointerSize; 4005 static const int kWrapperOffset = kContextOffset + kPointerSize; 4006 static const int kTypeOffset = kWrapperOffset + kPointerSize; 4007 static const int kCompilationTypeOffset = kTypeOffset + kPointerSize; 4008 static const int kLineEndsOffset = kCompilationTypeOffset + kPointerSize; 4009 static const int kIdOffset = kLineEndsOffset + kPointerSize; 4010 static const int kEvalFromSharedOffset = kIdOffset + kPointerSize; 4011 static const int kEvalFrominstructionsOffsetOffset = 4012 kEvalFromSharedOffset + kPointerSize; 4013 static const int kSize = kEvalFrominstructionsOffsetOffset + kPointerSize; 4014 4015 private: 4016 DISALLOW_IMPLICIT_CONSTRUCTORS(Script); 4017 }; 4018 4019 4020 // List of builtin functions we want to identify to improve code 4021 // generation. 4022 // 4023 // Each entry has a name of a global object property holding an object 4024 // optionally followed by ".prototype", a name of a builtin function 4025 // on the object (the one the id is set for), and a label. 4026 // 4027 // Installation of ids for the selected builtin functions is handled 4028 // by the bootstrapper. 4029 // 4030 // NOTE: Order is important: math functions should be at the end of 4031 // the list and MathFloor should be the first math function. 4032 #define FUNCTIONS_WITH_ID_LIST(V) \ 4033 V(Array.prototype, push, ArrayPush) \ 4034 V(Array.prototype, pop, ArrayPop) \ 4035 V(Function.prototype, apply, FunctionApply) \ 4036 V(String.prototype, charCodeAt, StringCharCodeAt) \ 4037 V(String.prototype, charAt, StringCharAt) \ 4038 V(String, fromCharCode, StringFromCharCode) \ 4039 V(Math, floor, MathFloor) \ 4040 V(Math, round, MathRound) \ 4041 V(Math, ceil, MathCeil) \ 4042 V(Math, abs, MathAbs) \ 4043 V(Math, log, MathLog) \ 4044 V(Math, sin, MathSin) \ 4045 V(Math, cos, MathCos) \ 4046 V(Math, tan, MathTan) \ 4047 V(Math, asin, MathASin) \ 4048 V(Math, acos, MathACos) \ 4049 V(Math, atan, MathATan) \ 4050 V(Math, exp, MathExp) \ 4051 V(Math, sqrt, MathSqrt) \ 4052 V(Math, pow, MathPow) 4053 4054 4055 enum BuiltinFunctionId { 4056 #define DECLARE_FUNCTION_ID(ignored1, ignore2, name) \ 4057 k##name, 4058 FUNCTIONS_WITH_ID_LIST(DECLARE_FUNCTION_ID) 4059 #undef DECLARE_FUNCTION_ID 4060 // Fake id for a special case of Math.pow. Note, it continues the 4061 // list of math functions. 4062 kMathPowHalf, 4063 kFirstMathFunctionId = kMathFloor 4064 }; 4065 4066 4067 // SharedFunctionInfo describes the JSFunction information that can be 4068 // shared by multiple instances of the function. 4069 class SharedFunctionInfo: public HeapObject { 4070 public: 4071 // [name]: Function name. 4072 DECL_ACCESSORS(name, Object) 4073 4074 // [code]: Function code. 4075 DECL_ACCESSORS(code, Code) 4076 4077 // [scope_info]: Scope info. 4078 DECL_ACCESSORS(scope_info, SerializedScopeInfo) 4079 4080 // [construct stub]: Code stub for constructing instances of this function. 4081 DECL_ACCESSORS(construct_stub, Code) 4082 4083 inline Code* unchecked_code(); 4084 4085 // Returns if this function has been compiled to native code yet. 4086 inline bool is_compiled(); 4087 4088 // [length]: The function length - usually the number of declared parameters. 4089 // Use up to 2^30 parameters. 4090 inline int length(); 4091 inline void set_length(int value); 4092 4093 // [formal parameter count]: The declared number of parameters. 4094 inline int formal_parameter_count(); 4095 inline void set_formal_parameter_count(int value); 4096 4097 // Set the formal parameter count so the function code will be 4098 // called without using argument adaptor frames. 4099 inline void DontAdaptArguments(); 4100 4101 // [expected_nof_properties]: Expected number of properties for the function. 4102 inline int expected_nof_properties(); 4103 inline void set_expected_nof_properties(int value); 4104 4105 // Inobject slack tracking is the way to reclaim unused inobject space. 4106 // 4107 // The instance size is initially determined by adding some slack to 4108 // expected_nof_properties (to allow for a few extra properties added 4109 // after the constructor). There is no guarantee that the extra space 4110 // will not be wasted. 4111 // 4112 // Here is the algorithm to reclaim the unused inobject space: 4113 // - Detect the first constructor call for this SharedFunctionInfo. 4114 // When it happens enter the "in progress" state: remember the 4115 // constructor's initial_map and install a special construct stub that 4116 // counts constructor calls. 4117 // - While the tracking is in progress create objects filled with 4118 // one_pointer_filler_map instead of undefined_value. This way they can be 4119 // resized quickly and safely. 4120 // - Once enough (kGenerousAllocationCount) objects have been created 4121 // compute the 'slack' (traverse the map transition tree starting from the 4122 // initial_map and find the lowest value of unused_property_fields). 4123 // - Traverse the transition tree again and decrease the instance size 4124 // of every map. Existing objects will resize automatically (they are 4125 // filled with one_pointer_filler_map). All further allocations will 4126 // use the adjusted instance size. 4127 // - Decrease expected_nof_properties so that an allocations made from 4128 // another context will use the adjusted instance size too. 4129 // - Exit "in progress" state by clearing the reference to the initial_map 4130 // and setting the regular construct stub (generic or inline). 4131 // 4132 // The above is the main event sequence. Some special cases are possible 4133 // while the tracking is in progress: 4134 // 4135 // - GC occurs. 4136 // Check if the initial_map is referenced by any live objects (except this 4137 // SharedFunctionInfo). If it is, continue tracking as usual. 4138 // If it is not, clear the reference and reset the tracking state. The 4139 // tracking will be initiated again on the next constructor call. 4140 // 4141 // - The constructor is called from another context. 4142 // Immediately complete the tracking, perform all the necessary changes 4143 // to maps. This is necessary because there is no efficient way to track 4144 // multiple initial_maps. 4145 // Proceed to create an object in the current context (with the adjusted 4146 // size). 4147 // 4148 // - A different constructor function sharing the same SharedFunctionInfo is 4149 // called in the same context. This could be another closure in the same 4150 // context, or the first function could have been disposed. 4151 // This is handled the same way as the previous case. 4152 // 4153 // Important: inobject slack tracking is not attempted during the snapshot 4154 // creation. 4155 4156 static const int kGenerousAllocationCount = 8; 4157 4158 // [construction_count]: Counter for constructor calls made during 4159 // the tracking phase. 4160 inline int construction_count(); 4161 inline void set_construction_count(int value); 4162 4163 // [initial_map]: initial map of the first function called as a constructor. 4164 // Saved for the duration of the tracking phase. 4165 // This is a weak link (GC resets it to undefined_value if no other live 4166 // object reference this map). 4167 DECL_ACCESSORS(initial_map, Object) 4168 4169 // True if the initial_map is not undefined and the countdown stub is 4170 // installed. 4171 inline bool IsInobjectSlackTrackingInProgress(); 4172 4173 // Starts the tracking. 4174 // Stores the initial map and installs the countdown stub. 4175 // IsInobjectSlackTrackingInProgress is normally true after this call, 4176 // except when tracking have not been started (e.g. the map has no unused 4177 // properties or the snapshot is being built). 4178 void StartInobjectSlackTracking(Map* map); 4179 4180 // Completes the tracking. 4181 // IsInobjectSlackTrackingInProgress is false after this call. 4182 void CompleteInobjectSlackTracking(); 4183 4184 // Clears the initial_map before the GC marking phase to ensure the reference 4185 // is weak. IsInobjectSlackTrackingInProgress is false after this call. 4186 void DetachInitialMap(); 4187 4188 // Restores the link to the initial map after the GC marking phase. 4189 // IsInobjectSlackTrackingInProgress is true after this call. 4190 void AttachInitialMap(Map* map); 4191 4192 // False if there are definitely no live objects created from this function. 4193 // True if live objects _may_ exist (existence not guaranteed). 4194 // May go back from true to false after GC. 4195 inline bool live_objects_may_exist(); 4196 4197 inline void set_live_objects_may_exist(bool value); 4198 4199 // [instance class name]: class name for instances. 4200 DECL_ACCESSORS(instance_class_name, Object) 4201 4202 // [function data]: This field holds some additional data for function. 4203 // Currently it either has FunctionTemplateInfo to make benefit the API 4204 // or Smi identifying a builtin function. 4205 // In the long run we don't want all functions to have this field but 4206 // we can fix that when we have a better model for storing hidden data 4207 // on objects. 4208 DECL_ACCESSORS(function_data, Object) 4209 4210 inline bool IsApiFunction(); 4211 inline FunctionTemplateInfo* get_api_func_data(); 4212 inline bool HasBuiltinFunctionId(); 4213 inline BuiltinFunctionId builtin_function_id(); 4214 4215 // [script info]: Script from which the function originates. 4216 DECL_ACCESSORS(script, Object) 4217 4218 // [num_literals]: Number of literals used by this function. 4219 inline int num_literals(); 4220 inline void set_num_literals(int value); 4221 4222 // [start_position_and_type]: Field used to store both the source code 4223 // position, whether or not the function is a function expression, 4224 // and whether or not the function is a toplevel function. The two 4225 // least significants bit indicates whether the function is an 4226 // expression and the rest contains the source code position. 4227 inline int start_position_and_type(); 4228 inline void set_start_position_and_type(int value); 4229 4230 // [debug info]: Debug information. 4231 DECL_ACCESSORS(debug_info, Object) 4232 4233 // [inferred name]: Name inferred from variable or property 4234 // assignment of this function. Used to facilitate debugging and 4235 // profiling of JavaScript code written in OO style, where almost 4236 // all functions are anonymous but are assigned to object 4237 // properties. 4238 DECL_ACCESSORS(inferred_name, String) 4239 4240 // The function's name if it is non-empty, otherwise the inferred name. 4241 String* DebugName(); 4242 4243 // Position of the 'function' token in the script source. 4244 inline int function_token_position(); 4245 inline void set_function_token_position(int function_token_position); 4246 4247 // Position of this function in the script source. 4248 inline int start_position(); 4249 inline void set_start_position(int start_position); 4250 4251 // End position of this function in the script source. 4252 inline int end_position(); 4253 inline void set_end_position(int end_position); 4254 4255 // Is this function a function expression in the source code. 4256 inline bool is_expression(); 4257 inline void set_is_expression(bool value); 4258 4259 // Is this function a top-level function (scripts, evals). 4260 inline bool is_toplevel(); 4261 inline void set_is_toplevel(bool value); 4262 4263 // Bit field containing various information collected by the compiler to 4264 // drive optimization. 4265 inline int compiler_hints(); 4266 inline void set_compiler_hints(int value); 4267 4268 // A counter used to determine when to stress the deoptimizer with a 4269 // deopt. 4270 inline Smi* deopt_counter(); 4271 inline void set_deopt_counter(Smi* counter); 4272 4273 // Add information on assignments of the form this.x = ...; 4274 void SetThisPropertyAssignmentsInfo( 4275 bool has_only_simple_this_property_assignments, 4276 FixedArray* this_property_assignments); 4277 4278 // Clear information on assignments of the form this.x = ...; 4279 void ClearThisPropertyAssignmentsInfo(); 4280 4281 // Indicate that this function only consists of assignments of the form 4282 // this.x = y; where y is either a constant or refers to an argument. 4283 inline bool has_only_simple_this_property_assignments(); 4284 4285 // Indicates if this function can be lazy compiled. 4286 // This is used to determine if we can safely flush code from a function 4287 // when doing GC if we expect that the function will no longer be used. 4288 inline bool allows_lazy_compilation(); 4289 inline void set_allows_lazy_compilation(bool flag); 4290 4291 // Indicates how many full GCs this function has survived with assigned 4292 // code object. Used to determine when it is relatively safe to flush 4293 // this code object and replace it with lazy compilation stub. 4294 // Age is reset when GC notices that the code object is referenced 4295 // from the stack or compilation cache. 4296 inline int code_age(); 4297 inline void set_code_age(int age); 4298 4299 // Indicates whether optimizations have been disabled for this 4300 // shared function info. If a function is repeatedly optimized or if 4301 // we cannot optimize the function we disable optimization to avoid 4302 // spending time attempting to optimize it again. 4303 inline bool optimization_disabled(); 4304 inline void set_optimization_disabled(bool value); 4305 4306 // Indicates whether the function is a strict mode function. 4307 inline bool strict_mode(); 4308 inline void set_strict_mode(bool value); 4309 4310 // Indicates whether or not the code in the shared function support 4311 // deoptimization. 4312 inline bool has_deoptimization_support(); 4313 4314 // Enable deoptimization support through recompiled code. 4315 void EnableDeoptimizationSupport(Code* recompiled); 4316 4317 // Lookup the bailout ID and ASSERT that it exists in the non-optimized 4318 // code, returns whether it asserted (i.e., always true if assertions are 4319 // disabled). 4320 bool VerifyBailoutId(int id); 4321 4322 // Check whether a inlined constructor can be generated with the given 4323 // prototype. 4324 bool CanGenerateInlineConstructor(Object* prototype); 4325 4326 // Prevents further attempts to generate inline constructors. 4327 // To be called if generation failed for any reason. 4328 void ForbidInlineConstructor(); 4329 4330 // For functions which only contains this property assignments this provides 4331 // access to the names for the properties assigned. 4332 DECL_ACCESSORS(this_property_assignments, Object) 4333 inline int this_property_assignments_count(); 4334 inline void set_this_property_assignments_count(int value); 4335 String* GetThisPropertyAssignmentName(int index); 4336 bool IsThisPropertyAssignmentArgument(int index); 4337 int GetThisPropertyAssignmentArgument(int index); 4338 Object* GetThisPropertyAssignmentConstant(int index); 4339 4340 // [source code]: Source code for the function. 4341 bool HasSourceCode(); 4342 Object* GetSourceCode(); 4343 4344 inline int opt_count(); 4345 inline void set_opt_count(int opt_count); 4346 4347 // Source size of this function. 4348 int SourceSize(); 4349 4350 // Calculate the instance size. 4351 int CalculateInstanceSize(); 4352 4353 // Calculate the number of in-object properties. 4354 int CalculateInObjectProperties(); 4355 4356 // Dispatched behavior. 4357 // Set max_length to -1 for unlimited length. 4358 void SourceCodePrint(StringStream* accumulator, int max_length); 4359 #ifdef OBJECT_PRINT 4360 inline void SharedFunctionInfoPrint() { 4361 SharedFunctionInfoPrint(stdout); 4362 } 4363 void SharedFunctionInfoPrint(FILE* out); 4364 #endif 4365 #ifdef DEBUG 4366 void SharedFunctionInfoVerify(); 4367 #endif 4368 4369 // Casting. 4370 static inline SharedFunctionInfo* cast(Object* obj); 4371 4372 // Constants. 4373 static const int kDontAdaptArgumentsSentinel = -1; 4374 4375 // Layout description. 4376 // Pointer fields. 4377 static const int kNameOffset = HeapObject::kHeaderSize; 4378 static const int kCodeOffset = kNameOffset + kPointerSize; 4379 static const int kScopeInfoOffset = kCodeOffset + kPointerSize; 4380 static const int kConstructStubOffset = kScopeInfoOffset + kPointerSize; 4381 static const int kInstanceClassNameOffset = 4382 kConstructStubOffset + kPointerSize; 4383 static const int kFunctionDataOffset = 4384 kInstanceClassNameOffset + kPointerSize; 4385 static const int kScriptOffset = kFunctionDataOffset + kPointerSize; 4386 static const int kDebugInfoOffset = kScriptOffset + kPointerSize; 4387 static const int kInferredNameOffset = kDebugInfoOffset + kPointerSize; 4388 static const int kInitialMapOffset = 4389 kInferredNameOffset + kPointerSize; 4390 static const int kThisPropertyAssignmentsOffset = 4391 kInitialMapOffset + kPointerSize; 4392 static const int kDeoptCounterOffset = 4393 kThisPropertyAssignmentsOffset + kPointerSize; 4394 #if V8_HOST_ARCH_32_BIT 4395 // Smi fields. 4396 static const int kLengthOffset = 4397 kDeoptCounterOffset + kPointerSize; 4398 static const int kFormalParameterCountOffset = kLengthOffset + kPointerSize; 4399 static const int kExpectedNofPropertiesOffset = 4400 kFormalParameterCountOffset + kPointerSize; 4401 static const int kNumLiteralsOffset = 4402 kExpectedNofPropertiesOffset + kPointerSize; 4403 static const int kStartPositionAndTypeOffset = 4404 kNumLiteralsOffset + kPointerSize; 4405 static const int kEndPositionOffset = 4406 kStartPositionAndTypeOffset + kPointerSize; 4407 static const int kFunctionTokenPositionOffset = 4408 kEndPositionOffset + kPointerSize; 4409 static const int kCompilerHintsOffset = 4410 kFunctionTokenPositionOffset + kPointerSize; 4411 static const int kThisPropertyAssignmentsCountOffset = 4412 kCompilerHintsOffset + kPointerSize; 4413 static const int kOptCountOffset = 4414 kThisPropertyAssignmentsCountOffset + kPointerSize; 4415 // Total size. 4416 static const int kSize = kOptCountOffset + kPointerSize; 4417 #else 4418 // The only reason to use smi fields instead of int fields 4419 // is to allow iteration without maps decoding during 4420 // garbage collections. 4421 // To avoid wasting space on 64-bit architectures we use 4422 // the following trick: we group integer fields into pairs 4423 // First integer in each pair is shifted left by 1. 4424 // By doing this we guarantee that LSB of each kPointerSize aligned 4425 // word is not set and thus this word cannot be treated as pointer 4426 // to HeapObject during old space traversal. 4427 static const int kLengthOffset = 4428 kDeoptCounterOffset + kPointerSize; 4429 static const int kFormalParameterCountOffset = 4430 kLengthOffset + kIntSize; 4431 4432 static const int kExpectedNofPropertiesOffset = 4433 kFormalParameterCountOffset + kIntSize; 4434 static const int kNumLiteralsOffset = 4435 kExpectedNofPropertiesOffset + kIntSize; 4436 4437 static const int kEndPositionOffset = 4438 kNumLiteralsOffset + kIntSize; 4439 static const int kStartPositionAndTypeOffset = 4440 kEndPositionOffset + kIntSize; 4441 4442 static const int kFunctionTokenPositionOffset = 4443 kStartPositionAndTypeOffset + kIntSize; 4444 static const int kCompilerHintsOffset = 4445 kFunctionTokenPositionOffset + kIntSize; 4446 4447 static const int kThisPropertyAssignmentsCountOffset = 4448 kCompilerHintsOffset + kIntSize; 4449 static const int kOptCountOffset = 4450 kThisPropertyAssignmentsCountOffset + kIntSize; 4451 4452 // Total size. 4453 static const int kSize = kOptCountOffset + kIntSize; 4454 4455 #endif 4456 4457 // The construction counter for inobject slack tracking is stored in the 4458 // most significant byte of compiler_hints which is otherwise unused. 4459 // Its offset depends on the endian-ness of the architecture. 4460 #if __BYTE_ORDER == __LITTLE_ENDIAN 4461 static const int kConstructionCountOffset = kCompilerHintsOffset + 3; 4462 #elif __BYTE_ORDER == __BIG_ENDIAN 4463 static const int kConstructionCountOffset = kCompilerHintsOffset + 0; 4464 #else 4465 #error Unknown byte ordering 4466 #endif 4467 4468 static const int kAlignedSize = POINTER_SIZE_ALIGN(kSize); 4469 4470 typedef FixedBodyDescriptor<kNameOffset, 4471 kThisPropertyAssignmentsOffset + kPointerSize, 4472 kSize> BodyDescriptor; 4473 4474 // Bit positions in start_position_and_type. 4475 // The source code start position is in the 30 most significant bits of 4476 // the start_position_and_type field. 4477 static const int kIsExpressionBit = 0; 4478 static const int kIsTopLevelBit = 1; 4479 static const int kStartPositionShift = 2; 4480 static const int kStartPositionMask = ~((1 << kStartPositionShift) - 1); 4481 4482 // Bit positions in compiler_hints. 4483 static const int kHasOnlySimpleThisPropertyAssignments = 0; 4484 static const int kAllowLazyCompilation = 1; 4485 static const int kLiveObjectsMayExist = 2; 4486 static const int kCodeAgeShift = 3; 4487 static const int kCodeAgeMask = 0x7; 4488 static const int kOptimizationDisabled = 6; 4489 static const int kStrictModeFunction = 7; 4490 4491 private: 4492 #if V8_HOST_ARCH_32_BIT 4493 // On 32 bit platforms, compiler hints is a smi. 4494 static const int kCompilerHintsSmiTagSize = kSmiTagSize; 4495 static const int kCompilerHintsSize = kPointerSize; 4496 #else 4497 // On 64 bit platforms, compiler hints is not a smi, see comment above. 4498 static const int kCompilerHintsSmiTagSize = 0; 4499 static const int kCompilerHintsSize = kIntSize; 4500 #endif 4501 4502 public: 4503 // Constants for optimizing codegen for strict mode function tests. 4504 // Allows to use byte-widgh instructions. 4505 static const int kStrictModeBitWithinByte = 4506 (kStrictModeFunction + kCompilerHintsSmiTagSize) % kBitsPerByte; 4507 4508 #if __BYTE_ORDER == __LITTLE_ENDIAN 4509 static const int kStrictModeByteOffset = kCompilerHintsOffset + 4510 (kStrictModeFunction + kCompilerHintsSmiTagSize) / kBitsPerByte; 4511 #elif __BYTE_ORDER == __BIG_ENDIAN 4512 static const int kStrictModeByteOffset = kCompilerHintsOffset + 4513 (kCompilerHintsSize - 1) - 4514 ((kStrictModeFunction + kCompilerHintsSmiTagSize) / kBitsPerByte); 4515 #else 4516 #error Unknown byte ordering 4517 #endif 4518 4519 private: 4520 DISALLOW_IMPLICIT_CONSTRUCTORS(SharedFunctionInfo); 4521 }; 4522 4523 4524 // JSFunction describes JavaScript functions. 4525 class JSFunction: public JSObject { 4526 public: 4527 // [prototype_or_initial_map]: 4528 DECL_ACCESSORS(prototype_or_initial_map, Object) 4529 4530 // [shared_function_info]: The information about the function that 4531 // can be shared by instances. 4532 DECL_ACCESSORS(shared, SharedFunctionInfo) 4533 4534 inline SharedFunctionInfo* unchecked_shared(); 4535 4536 // [context]: The context for this function. 4537 inline Context* context(); 4538 inline Object* unchecked_context(); 4539 inline void set_context(Object* context); 4540 4541 // [code]: The generated code object for this function. Executed 4542 // when the function is invoked, e.g. foo() or new foo(). See 4543 // [[Call]] and [[Construct]] description in ECMA-262, section 4544 // 8.6.2, page 27. 4545 inline Code* code(); 4546 inline void set_code(Code* code); 4547 inline void ReplaceCode(Code* code); 4548 4549 inline Code* unchecked_code(); 4550 4551 // Tells whether this function is builtin. 4552 inline bool IsBuiltin(); 4553 4554 // Tells whether or not the function needs arguments adaption. 4555 inline bool NeedsArgumentsAdaption(); 4556 4557 // Tells whether or not this function has been optimized. 4558 inline bool IsOptimized(); 4559 4560 // Tells whether or not this function can be optimized. 4561 inline bool IsOptimizable(); 4562 4563 // Mark this function for lazy recompilation. The function will be 4564 // recompiled the next time it is executed. 4565 void MarkForLazyRecompilation(); 4566 4567 // Tells whether or not the function is already marked for lazy 4568 // recompilation. 4569 inline bool IsMarkedForLazyRecompilation(); 4570 4571 // Compute a hash code for the source code of this function. 4572 uint32_t SourceHash(); 4573 4574 // Check whether or not this function is inlineable. 4575 bool IsInlineable(); 4576 4577 // [literals]: Fixed array holding the materialized literals. 4578 // 4579 // If the function contains object, regexp or array literals, the 4580 // literals array prefix contains the object, regexp, and array 4581 // function to be used when creating these literals. This is 4582 // necessary so that we do not dynamically lookup the object, regexp 4583 // or array functions. Performing a dynamic lookup, we might end up 4584 // using the functions from a new context that we should not have 4585 // access to. 4586 DECL_ACCESSORS(literals, FixedArray) 4587 4588 // The initial map for an object created by this constructor. 4589 inline Map* initial_map(); 4590 inline void set_initial_map(Map* value); 4591 inline bool has_initial_map(); 4592 4593 // Get and set the prototype property on a JSFunction. If the 4594 // function has an initial map the prototype is set on the initial 4595 // map. Otherwise, the prototype is put in the initial map field 4596 // until an initial map is needed. 4597 inline bool has_prototype(); 4598 inline bool has_instance_prototype(); 4599 inline Object* prototype(); 4600 inline Object* instance_prototype(); 4601 Object* SetInstancePrototype(Object* value); 4602 MUST_USE_RESULT MaybeObject* SetPrototype(Object* value); 4603 4604 // After prototype is removed, it will not be created when accessed, and 4605 // [[Construct]] from this function will not be allowed. 4606 Object* RemovePrototype(); 4607 inline bool should_have_prototype(); 4608 4609 // Accessor for this function's initial map's [[class]] 4610 // property. This is primarily used by ECMA native functions. This 4611 // method sets the class_name field of this function's initial map 4612 // to a given value. It creates an initial map if this function does 4613 // not have one. Note that this method does not copy the initial map 4614 // if it has one already, but simply replaces it with the new value. 4615 // Instances created afterwards will have a map whose [[class]] is 4616 // set to 'value', but there is no guarantees on instances created 4617 // before. 4618 Object* SetInstanceClassName(String* name); 4619 4620 // Returns if this function has been compiled to native code yet. 4621 inline bool is_compiled(); 4622 4623 // [next_function_link]: Field for linking functions. This list is treated as 4624 // a weak list by the GC. 4625 DECL_ACCESSORS(next_function_link, Object) 4626 4627 // Prints the name of the function using PrintF. 4628 inline void PrintName() { 4629 PrintName(stdout); 4630 } 4631 void PrintName(FILE* out); 4632 4633 // Casting. 4634 static inline JSFunction* cast(Object* obj); 4635 4636 // Iterates the objects, including code objects indirectly referenced 4637 // through pointers to the first instruction in the code object. 4638 void JSFunctionIterateBody(int object_size, ObjectVisitor* v); 4639 4640 // Dispatched behavior. 4641 #ifdef OBJECT_PRINT 4642 inline void JSFunctionPrint() { 4643 JSFunctionPrint(stdout); 4644 } 4645 void JSFunctionPrint(FILE* out); 4646 #endif 4647 #ifdef DEBUG 4648 void JSFunctionVerify(); 4649 #endif 4650 4651 // Returns the number of allocated literals. 4652 inline int NumberOfLiterals(); 4653 4654 // Retrieve the global context from a function's literal array. 4655 static Context* GlobalContextFromLiterals(FixedArray* literals); 4656 4657 // Layout descriptors. The last property (from kNonWeakFieldsEndOffset to 4658 // kSize) is weak and has special handling during garbage collection. 4659 static const int kCodeEntryOffset = JSObject::kHeaderSize; 4660 static const int kPrototypeOrInitialMapOffset = 4661 kCodeEntryOffset + kPointerSize; 4662 static const int kSharedFunctionInfoOffset = 4663 kPrototypeOrInitialMapOffset + kPointerSize; 4664 static const int kContextOffset = kSharedFunctionInfoOffset + kPointerSize; 4665 static const int kLiteralsOffset = kContextOffset + kPointerSize; 4666 static const int kNonWeakFieldsEndOffset = kLiteralsOffset + kPointerSize; 4667 static const int kNextFunctionLinkOffset = kNonWeakFieldsEndOffset; 4668 static const int kSize = kNextFunctionLinkOffset + kPointerSize; 4669 4670 // Layout of the literals array. 4671 static const int kLiteralsPrefixSize = 1; 4672 static const int kLiteralGlobalContextIndex = 0; 4673 private: 4674 DISALLOW_IMPLICIT_CONSTRUCTORS(JSFunction); 4675 }; 4676 4677 4678 // JSGlobalProxy's prototype must be a JSGlobalObject or null, 4679 // and the prototype is hidden. JSGlobalProxy always delegates 4680 // property accesses to its prototype if the prototype is not null. 4681 // 4682 // A JSGlobalProxy can be reinitialized which will preserve its identity. 4683 // 4684 // Accessing a JSGlobalProxy requires security check. 4685 4686 class JSGlobalProxy : public JSObject { 4687 public: 4688 // [context]: the owner global context of this proxy object. 4689 // It is null value if this object is not used by any context. 4690 DECL_ACCESSORS(context, Object) 4691 4692 // Casting. 4693 static inline JSGlobalProxy* cast(Object* obj); 4694 4695 // Dispatched behavior. 4696 #ifdef OBJECT_PRINT 4697 inline void JSGlobalProxyPrint() { 4698 JSGlobalProxyPrint(stdout); 4699 } 4700 void JSGlobalProxyPrint(FILE* out); 4701 #endif 4702 #ifdef DEBUG 4703 void JSGlobalProxyVerify(); 4704 #endif 4705 4706 // Layout description. 4707 static const int kContextOffset = JSObject::kHeaderSize; 4708 static const int kSize = kContextOffset + kPointerSize; 4709 4710 private: 4711 4712 DISALLOW_IMPLICIT_CONSTRUCTORS(JSGlobalProxy); 4713 }; 4714 4715 4716 // Forward declaration. 4717 class JSBuiltinsObject; 4718 class JSGlobalPropertyCell; 4719 4720 // Common super class for JavaScript global objects and the special 4721 // builtins global objects. 4722 class GlobalObject: public JSObject { 4723 public: 4724 // [builtins]: the object holding the runtime routines written in JS. 4725 DECL_ACCESSORS(builtins, JSBuiltinsObject) 4726 4727 // [global context]: the global context corresponding to this global object. 4728 DECL_ACCESSORS(global_context, Context) 4729 4730 // [global receiver]: the global receiver object of the context 4731 DECL_ACCESSORS(global_receiver, JSObject) 4732 4733 // Retrieve the property cell used to store a property. 4734 JSGlobalPropertyCell* GetPropertyCell(LookupResult* result); 4735 4736 // This is like GetProperty, but is used when you know the lookup won't fail 4737 // by throwing an exception. This is for the debug and builtins global 4738 // objects, where it is known which properties can be expected to be present 4739 // on the object. 4740 Object* GetPropertyNoExceptionThrown(String* key) { 4741 Object* answer = GetProperty(key)->ToObjectUnchecked(); 4742 return answer; 4743 } 4744 4745 // Ensure that the global object has a cell for the given property name. 4746 MUST_USE_RESULT MaybeObject* EnsurePropertyCell(String* name); 4747 4748 // Casting. 4749 static inline GlobalObject* cast(Object* obj); 4750 4751 // Layout description. 4752 static const int kBuiltinsOffset = JSObject::kHeaderSize; 4753 static const int kGlobalContextOffset = kBuiltinsOffset + kPointerSize; 4754 static const int kGlobalReceiverOffset = kGlobalContextOffset + kPointerSize; 4755 static const int kHeaderSize = kGlobalReceiverOffset + kPointerSize; 4756 4757 private: 4758 friend class AGCCVersionRequiresThisClassToHaveAFriendSoHereItIs; 4759 4760 DISALLOW_IMPLICIT_CONSTRUCTORS(GlobalObject); 4761 }; 4762 4763 4764 // JavaScript global object. 4765 class JSGlobalObject: public GlobalObject { 4766 public: 4767 4768 // Casting. 4769 static inline JSGlobalObject* cast(Object* obj); 4770 4771 // Dispatched behavior. 4772 #ifdef OBJECT_PRINT 4773 inline void JSGlobalObjectPrint() { 4774 JSGlobalObjectPrint(stdout); 4775 } 4776 void JSGlobalObjectPrint(FILE* out); 4777 #endif 4778 #ifdef DEBUG 4779 void JSGlobalObjectVerify(); 4780 #endif 4781 4782 // Layout description. 4783 static const int kSize = GlobalObject::kHeaderSize; 4784 4785 private: 4786 DISALLOW_IMPLICIT_CONSTRUCTORS(JSGlobalObject); 4787 }; 4788 4789 4790 // Builtins global object which holds the runtime routines written in 4791 // JavaScript. 4792 class JSBuiltinsObject: public GlobalObject { 4793 public: 4794 // Accessors for the runtime routines written in JavaScript. 4795 inline Object* javascript_builtin(Builtins::JavaScript id); 4796 inline void set_javascript_builtin(Builtins::JavaScript id, Object* value); 4797 4798 // Accessors for code of the runtime routines written in JavaScript. 4799 inline Code* javascript_builtin_code(Builtins::JavaScript id); 4800 inline void set_javascript_builtin_code(Builtins::JavaScript id, Code* value); 4801 4802 // Casting. 4803 static inline JSBuiltinsObject* cast(Object* obj); 4804 4805 // Dispatched behavior. 4806 #ifdef OBJECT_PRINT 4807 inline void JSBuiltinsObjectPrint() { 4808 JSBuiltinsObjectPrint(stdout); 4809 } 4810 void JSBuiltinsObjectPrint(FILE* out); 4811 #endif 4812 #ifdef DEBUG 4813 void JSBuiltinsObjectVerify(); 4814 #endif 4815 4816 // Layout description. The size of the builtins object includes 4817 // room for two pointers per runtime routine written in javascript 4818 // (function and code object). 4819 static const int kJSBuiltinsCount = Builtins::id_count; 4820 static const int kJSBuiltinsOffset = GlobalObject::kHeaderSize; 4821 static const int kJSBuiltinsCodeOffset = 4822 GlobalObject::kHeaderSize + (kJSBuiltinsCount * kPointerSize); 4823 static const int kSize = 4824 kJSBuiltinsCodeOffset + (kJSBuiltinsCount * kPointerSize); 4825 4826 static int OffsetOfFunctionWithId(Builtins::JavaScript id) { 4827 return kJSBuiltinsOffset + id * kPointerSize; 4828 } 4829 4830 static int OffsetOfCodeWithId(Builtins::JavaScript id) { 4831 return kJSBuiltinsCodeOffset + id * kPointerSize; 4832 } 4833 4834 private: 4835 DISALLOW_IMPLICIT_CONSTRUCTORS(JSBuiltinsObject); 4836 }; 4837 4838 4839 // Representation for JS Wrapper objects, String, Number, Boolean, Date, etc. 4840 class JSValue: public JSObject { 4841 public: 4842 // [value]: the object being wrapped. 4843 DECL_ACCESSORS(value, Object) 4844 4845 // Casting. 4846 static inline JSValue* cast(Object* obj); 4847 4848 // Dispatched behavior. 4849 #ifdef OBJECT_PRINT 4850 inline void JSValuePrint() { 4851 JSValuePrint(stdout); 4852 } 4853 void JSValuePrint(FILE* out); 4854 #endif 4855 #ifdef DEBUG 4856 void JSValueVerify(); 4857 #endif 4858 4859 // Layout description. 4860 static const int kValueOffset = JSObject::kHeaderSize; 4861 static const int kSize = kValueOffset + kPointerSize; 4862 4863 private: 4864 DISALLOW_IMPLICIT_CONSTRUCTORS(JSValue); 4865 }; 4866 4867 4868 // Representation of message objects used for error reporting through 4869 // the API. The messages are formatted in JavaScript so this object is 4870 // a real JavaScript object. The information used for formatting the 4871 // error messages are not directly accessible from JavaScript to 4872 // prevent leaking information to user code called during error 4873 // formatting. 4874 class JSMessageObject: public JSObject { 4875 public: 4876 // [type]: the type of error message. 4877 DECL_ACCESSORS(type, String) 4878 4879 // [arguments]: the arguments for formatting the error message. 4880 DECL_ACCESSORS(arguments, JSArray) 4881 4882 // [script]: the script from which the error message originated. 4883 DECL_ACCESSORS(script, Object) 4884 4885 // [stack_trace]: the stack trace for this error message. 4886 DECL_ACCESSORS(stack_trace, Object) 4887 4888 // [stack_frames]: an array of stack frames for this error object. 4889 DECL_ACCESSORS(stack_frames, Object) 4890 4891 // [start_position]: the start position in the script for the error message. 4892 inline int start_position(); 4893 inline void set_start_position(int value); 4894 4895 // [end_position]: the end position in the script for the error message. 4896 inline int end_position(); 4897 inline void set_end_position(int value); 4898 4899 // Casting. 4900 static inline JSMessageObject* cast(Object* obj); 4901 4902 // Dispatched behavior. 4903 #ifdef OBJECT_PRINT 4904 inline void JSMessageObjectPrint() { 4905 JSMessageObjectPrint(stdout); 4906 } 4907 void JSMessageObjectPrint(FILE* out); 4908 #endif 4909 #ifdef DEBUG 4910 void JSMessageObjectVerify(); 4911 #endif 4912 4913 // Layout description. 4914 static const int kTypeOffset = JSObject::kHeaderSize; 4915 static const int kArgumentsOffset = kTypeOffset + kPointerSize; 4916 static const int kScriptOffset = kArgumentsOffset + kPointerSize; 4917 static const int kStackTraceOffset = kScriptOffset + kPointerSize; 4918 static const int kStackFramesOffset = kStackTraceOffset + kPointerSize; 4919 static const int kStartPositionOffset = kStackFramesOffset + kPointerSize; 4920 static const int kEndPositionOffset = kStartPositionOffset + kPointerSize; 4921 static const int kSize = kEndPositionOffset + kPointerSize; 4922 4923 typedef FixedBodyDescriptor<HeapObject::kMapOffset, 4924 kStackFramesOffset + kPointerSize, 4925 kSize> BodyDescriptor; 4926 }; 4927 4928 4929 // Regular expressions 4930 // The regular expression holds a single reference to a FixedArray in 4931 // the kDataOffset field. 4932 // The FixedArray contains the following data: 4933 // - tag : type of regexp implementation (not compiled yet, atom or irregexp) 4934 // - reference to the original source string 4935 // - reference to the original flag string 4936 // If it is an atom regexp 4937 // - a reference to a literal string to search for 4938 // If it is an irregexp regexp: 4939 // - a reference to code for ASCII inputs (bytecode or compiled). 4940 // - a reference to code for UC16 inputs (bytecode or compiled). 4941 // - max number of registers used by irregexp implementations. 4942 // - number of capture registers (output values) of the regexp. 4943 class JSRegExp: public JSObject { 4944 public: 4945 // Meaning of Type: 4946 // NOT_COMPILED: Initial value. No data has been stored in the JSRegExp yet. 4947 // ATOM: A simple string to match against using an indexOf operation. 4948 // IRREGEXP: Compiled with Irregexp. 4949 // IRREGEXP_NATIVE: Compiled to native code with Irregexp. 4950 enum Type { NOT_COMPILED, ATOM, IRREGEXP }; 4951 enum Flag { NONE = 0, GLOBAL = 1, IGNORE_CASE = 2, MULTILINE = 4 }; 4952 4953 class Flags { 4954 public: 4955 explicit Flags(uint32_t value) : value_(value) { } 4956 bool is_global() { return (value_ & GLOBAL) != 0; } 4957 bool is_ignore_case() { return (value_ & IGNORE_CASE) != 0; } 4958 bool is_multiline() { return (value_ & MULTILINE) != 0; } 4959 uint32_t value() { return value_; } 4960 private: 4961 uint32_t value_; 4962 }; 4963 4964 DECL_ACCESSORS(data, Object) 4965 4966 inline Type TypeTag(); 4967 inline int CaptureCount(); 4968 inline Flags GetFlags(); 4969 inline String* Pattern(); 4970 inline Object* DataAt(int index); 4971 // Set implementation data after the object has been prepared. 4972 inline void SetDataAt(int index, Object* value); 4973 static int code_index(bool is_ascii) { 4974 if (is_ascii) { 4975 return kIrregexpASCIICodeIndex; 4976 } else { 4977 return kIrregexpUC16CodeIndex; 4978 } 4979 } 4980 4981 static inline JSRegExp* cast(Object* obj); 4982 4983 // Dispatched behavior. 4984 #ifdef DEBUG 4985 void JSRegExpVerify(); 4986 #endif 4987 4988 static const int kDataOffset = JSObject::kHeaderSize; 4989 static const int kSize = kDataOffset + kPointerSize; 4990 4991 // Indices in the data array. 4992 static const int kTagIndex = 0; 4993 static const int kSourceIndex = kTagIndex + 1; 4994 static const int kFlagsIndex = kSourceIndex + 1; 4995 static const int kDataIndex = kFlagsIndex + 1; 4996 // The data fields are used in different ways depending on the 4997 // value of the tag. 4998 // Atom regexps (literal strings). 4999 static const int kAtomPatternIndex = kDataIndex; 5000 5001 static const int kAtomDataSize = kAtomPatternIndex + 1; 5002 5003 // Irregexp compiled code or bytecode for ASCII. If compilation 5004 // fails, this fields hold an exception object that should be 5005 // thrown if the regexp is used again. 5006 static const int kIrregexpASCIICodeIndex = kDataIndex; 5007 // Irregexp compiled code or bytecode for UC16. If compilation 5008 // fails, this fields hold an exception object that should be 5009 // thrown if the regexp is used again. 5010 static const int kIrregexpUC16CodeIndex = kDataIndex + 1; 5011 // Maximal number of registers used by either ASCII or UC16. 5012 // Only used to check that there is enough stack space 5013 static const int kIrregexpMaxRegisterCountIndex = kDataIndex + 2; 5014 // Number of captures in the compiled regexp. 5015 static const int kIrregexpCaptureCountIndex = kDataIndex + 3; 5016 5017 static const int kIrregexpDataSize = kIrregexpCaptureCountIndex + 1; 5018 5019 // Offsets directly into the data fixed array. 5020 static const int kDataTagOffset = 5021 FixedArray::kHeaderSize + kTagIndex * kPointerSize; 5022 static const int kDataAsciiCodeOffset = 5023 FixedArray::kHeaderSize + kIrregexpASCIICodeIndex * kPointerSize; 5024 static const int kDataUC16CodeOffset = 5025 FixedArray::kHeaderSize + kIrregexpUC16CodeIndex * kPointerSize; 5026 static const int kIrregexpCaptureCountOffset = 5027 FixedArray::kHeaderSize + kIrregexpCaptureCountIndex * kPointerSize; 5028 5029 // In-object fields. 5030 static const int kSourceFieldIndex = 0; 5031 static const int kGlobalFieldIndex = 1; 5032 static const int kIgnoreCaseFieldIndex = 2; 5033 static const int kMultilineFieldIndex = 3; 5034 static const int kLastIndexFieldIndex = 4; 5035 static const int kInObjectFieldCount = 5; 5036 }; 5037 5038 5039 class CompilationCacheShape { 5040 public: 5041 static inline bool IsMatch(HashTableKey* key, Object* value) { 5042 return key->IsMatch(value); 5043 } 5044 5045 static inline uint32_t Hash(HashTableKey* key) { 5046 return key->Hash(); 5047 } 5048 5049 static inline uint32_t HashForObject(HashTableKey* key, Object* object) { 5050 return key->HashForObject(object); 5051 } 5052 5053 MUST_USE_RESULT static MaybeObject* AsObject(HashTableKey* key) { 5054 return key->AsObject(); 5055 } 5056 5057 static const int kPrefixSize = 0; 5058 static const int kEntrySize = 2; 5059 }; 5060 5061 5062 class CompilationCacheTable: public HashTable<CompilationCacheShape, 5063 HashTableKey*> { 5064 public: 5065 // Find cached value for a string key, otherwise return null. 5066 Object* Lookup(String* src); 5067 Object* LookupEval(String* src, Context* context, StrictModeFlag strict_mode); 5068 Object* LookupRegExp(String* source, JSRegExp::Flags flags); 5069 MaybeObject* Put(String* src, Object* value); 5070 MaybeObject* PutEval(String* src, 5071 Context* context, 5072 SharedFunctionInfo* value); 5073 MaybeObject* PutRegExp(String* src, JSRegExp::Flags flags, FixedArray* value); 5074 5075 // Remove given value from cache. 5076 void Remove(Object* value); 5077 5078 static inline CompilationCacheTable* cast(Object* obj); 5079 5080 private: 5081 DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationCacheTable); 5082 }; 5083 5084 5085 class CodeCache: public Struct { 5086 public: 5087 DECL_ACCESSORS(default_cache, FixedArray) 5088 DECL_ACCESSORS(normal_type_cache, Object) 5089 5090 // Add the code object to the cache. 5091 MUST_USE_RESULT MaybeObject* Update(String* name, Code* code); 5092 5093 // Lookup code object in the cache. Returns code object if found and undefined 5094 // if not. 5095 Object* Lookup(String* name, Code::Flags flags); 5096 5097 // Get the internal index of a code object in the cache. Returns -1 if the 5098 // code object is not in that cache. This index can be used to later call 5099 // RemoveByIndex. The cache cannot be modified between a call to GetIndex and 5100 // RemoveByIndex. 5101 int GetIndex(Object* name, Code* code); 5102 5103 // Remove an object from the cache with the provided internal index. 5104 void RemoveByIndex(Object* name, Code* code, int index); 5105 5106 static inline CodeCache* cast(Object* obj); 5107 5108 #ifdef OBJECT_PRINT 5109 inline void CodeCachePrint() { 5110 CodeCachePrint(stdout); 5111 } 5112 void CodeCachePrint(FILE* out); 5113 #endif 5114 #ifdef DEBUG 5115 void CodeCacheVerify(); 5116 #endif 5117 5118 static const int kDefaultCacheOffset = HeapObject::kHeaderSize; 5119 static const int kNormalTypeCacheOffset = 5120 kDefaultCacheOffset + kPointerSize; 5121 static const int kSize = kNormalTypeCacheOffset + kPointerSize; 5122 5123 private: 5124 MUST_USE_RESULT MaybeObject* UpdateDefaultCache(String* name, Code* code); 5125 MUST_USE_RESULT MaybeObject* UpdateNormalTypeCache(String* name, Code* code); 5126 Object* LookupDefaultCache(String* name, Code::Flags flags); 5127 Object* LookupNormalTypeCache(String* name, Code::Flags flags); 5128 5129 // Code cache layout of the default cache. Elements are alternating name and 5130 // code objects for non normal load/store/call IC's. 5131 static const int kCodeCacheEntrySize = 2; 5132 static const int kCodeCacheEntryNameOffset = 0; 5133 static const int kCodeCacheEntryCodeOffset = 1; 5134 5135 DISALLOW_IMPLICIT_CONSTRUCTORS(CodeCache); 5136 }; 5137 5138 5139 class CodeCacheHashTableShape { 5140 public: 5141 static inline bool IsMatch(HashTableKey* key, Object* value) { 5142 return key->IsMatch(value); 5143 } 5144 5145 static inline uint32_t Hash(HashTableKey* key) { 5146 return key->Hash(); 5147 } 5148 5149 static inline uint32_t HashForObject(HashTableKey* key, Object* object) { 5150 return key->HashForObject(object); 5151 } 5152 5153 MUST_USE_RESULT static MaybeObject* AsObject(HashTableKey* key) { 5154 return key->AsObject(); 5155 } 5156 5157 static const int kPrefixSize = 0; 5158 static const int kEntrySize = 2; 5159 }; 5160 5161 5162 class CodeCacheHashTable: public HashTable<CodeCacheHashTableShape, 5163 HashTableKey*> { 5164 public: 5165 Object* Lookup(String* name, Code::Flags flags); 5166 MUST_USE_RESULT MaybeObject* Put(String* name, Code* code); 5167 5168 int GetIndex(String* name, Code::Flags flags); 5169 void RemoveByIndex(int index); 5170 5171 static inline CodeCacheHashTable* cast(Object* obj); 5172 5173 // Initial size of the fixed array backing the hash table. 5174 static const int kInitialSize = 64; 5175 5176 private: 5177 DISALLOW_IMPLICIT_CONSTRUCTORS(CodeCacheHashTable); 5178 }; 5179 5180 5181 enum AllowNullsFlag {ALLOW_NULLS, DISALLOW_NULLS}; 5182 enum RobustnessFlag {ROBUST_STRING_TRAVERSAL, FAST_STRING_TRAVERSAL}; 5183 5184 5185 class StringHasher { 5186 public: 5187 explicit inline StringHasher(int length); 5188 5189 // Returns true if the hash of this string can be computed without 5190 // looking at the contents. 5191 inline bool has_trivial_hash(); 5192 5193 // Add a character to the hash and update the array index calculation. 5194 inline void AddCharacter(uc32 c); 5195 5196 // Adds a character to the hash but does not update the array index 5197 // calculation. This can only be called when it has been verified 5198 // that the input is not an array index. 5199 inline void AddCharacterNoIndex(uc32 c); 5200 5201 // Returns the value to store in the hash field of a string with 5202 // the given length and contents. 5203 uint32_t GetHashField(); 5204 5205 // Returns true if the characters seen so far make up a legal array 5206 // index. 5207 bool is_array_index() { return is_array_index_; } 5208 5209 bool is_valid() { return is_valid_; } 5210 5211 void invalidate() { is_valid_ = false; } 5212 5213 // Calculated hash value for a string consisting of 1 to 5214 // String::kMaxArrayIndexSize digits with no leading zeros (except "0"). 5215 // value is represented decimal value. 5216 static uint32_t MakeArrayIndexHash(uint32_t value, int length); 5217 5218 private: 5219 5220 uint32_t array_index() { 5221 ASSERT(is_array_index()); 5222 return array_index_; 5223 } 5224 5225 inline uint32_t GetHash(); 5226 5227 int length_; 5228 uint32_t raw_running_hash_; 5229 uint32_t array_index_; 5230 bool is_array_index_; 5231 bool is_first_char_; 5232 bool is_valid_; 5233 friend class TwoCharHashTableKey; 5234 }; 5235 5236 5237 // Calculates string hash. 5238 template <typename schar> 5239 inline uint32_t HashSequentialString(const schar* chars, int length); 5240 5241 5242 // The characteristics of a string are stored in its map. Retrieving these 5243 // few bits of information is moderately expensive, involving two memory 5244 // loads where the second is dependent on the first. To improve efficiency 5245 // the shape of the string is given its own class so that it can be retrieved 5246 // once and used for several string operations. A StringShape is small enough 5247 // to be passed by value and is immutable, but be aware that flattening a 5248 // string can potentially alter its shape. Also be aware that a GC caused by 5249 // something else can alter the shape of a string due to ConsString 5250 // shortcutting. Keeping these restrictions in mind has proven to be error- 5251 // prone and so we no longer put StringShapes in variables unless there is a 5252 // concrete performance benefit at that particular point in the code. 5253 class StringShape BASE_EMBEDDED { 5254 public: 5255 inline explicit StringShape(String* s); 5256 inline explicit StringShape(Map* s); 5257 inline explicit StringShape(InstanceType t); 5258 inline bool IsSequential(); 5259 inline bool IsExternal(); 5260 inline bool IsCons(); 5261 inline bool IsExternalAscii(); 5262 inline bool IsExternalTwoByte(); 5263 inline bool IsSequentialAscii(); 5264 inline bool IsSequentialTwoByte(); 5265 inline bool IsSymbol(); 5266 inline StringRepresentationTag representation_tag(); 5267 inline uint32_t full_representation_tag(); 5268 inline uint32_t size_tag(); 5269 #ifdef DEBUG 5270 inline uint32_t type() { return type_; } 5271 inline void invalidate() { valid_ = false; } 5272 inline bool valid() { return valid_; } 5273 #else 5274 inline void invalidate() { } 5275 #endif 5276 private: 5277 uint32_t type_; 5278 #ifdef DEBUG 5279 inline void set_valid() { valid_ = true; } 5280 bool valid_; 5281 #else 5282 inline void set_valid() { } 5283 #endif 5284 }; 5285 5286 5287 // The String abstract class captures JavaScript string values: 5288 // 5289 // Ecma-262: 5290 // 4.3.16 String Value 5291 // A string value is a member of the type String and is a finite 5292 // ordered sequence of zero or more 16-bit unsigned integer values. 5293 // 5294 // All string values have a length field. 5295 class String: public HeapObject { 5296 public: 5297 // Get and set the length of the string. 5298 inline int length(); 5299 inline void set_length(int value); 5300 5301 // Get and set the hash field of the string. 5302 inline uint32_t hash_field(); 5303 inline void set_hash_field(uint32_t value); 5304 5305 inline bool IsAsciiRepresentation(); 5306 inline bool IsTwoByteRepresentation(); 5307 5308 // Returns whether this string has ascii chars, i.e. all of them can 5309 // be ascii encoded. This might be the case even if the string is 5310 // two-byte. Such strings may appear when the embedder prefers 5311 // two-byte external representations even for ascii data. 5312 // 5313 // NOTE: this should be considered only a hint. False negatives are 5314 // possible. 5315 inline bool HasOnlyAsciiChars(); 5316 5317 // Get and set individual two byte chars in the string. 5318 inline void Set(int index, uint16_t value); 5319 // Get individual two byte char in the string. Repeated calls 5320 // to this method are not efficient unless the string is flat. 5321 inline uint16_t Get(int index); 5322 5323 // Try to flatten the string. Checks first inline to see if it is 5324 // necessary. Does nothing if the string is not a cons string. 5325 // Flattening allocates a sequential string with the same data as 5326 // the given string and mutates the cons string to a degenerate 5327 // form, where the first component is the new sequential string and 5328 // the second component is the empty string. If allocation fails, 5329 // this function returns a failure. If flattening succeeds, this 5330 // function returns the sequential string that is now the first 5331 // component of the cons string. 5332 // 5333 // Degenerate cons strings are handled specially by the garbage 5334 // collector (see IsShortcutCandidate). 5335 // 5336 // Use FlattenString from Handles.cc to flatten even in case an 5337 // allocation failure happens. 5338 inline MaybeObject* TryFlatten(PretenureFlag pretenure = NOT_TENURED); 5339 5340 // Convenience function. Has exactly the same behavior as 5341 // TryFlatten(), except in the case of failure returns the original 5342 // string. 5343 inline String* TryFlattenGetString(PretenureFlag pretenure = NOT_TENURED); 5344 5345 Vector<const char> ToAsciiVector(); 5346 Vector<const uc16> ToUC16Vector(); 5347 5348 // Mark the string as an undetectable object. It only applies to 5349 // ascii and two byte string types. 5350 bool MarkAsUndetectable(); 5351 5352 // Return a substring. 5353 MUST_USE_RESULT MaybeObject* SubString(int from, 5354 int to, 5355 PretenureFlag pretenure = NOT_TENURED); 5356 5357 // String equality operations. 5358 inline bool Equals(String* other); 5359 bool IsEqualTo(Vector<const char> str); 5360 bool IsAsciiEqualTo(Vector<const char> str); 5361 bool IsTwoByteEqualTo(Vector<const uc16> str); 5362 5363 // Return a UTF8 representation of the string. The string is null 5364 // terminated but may optionally contain nulls. Length is returned 5365 // in length_output if length_output is not a null pointer The string 5366 // should be nearly flat, otherwise the performance of this method may 5367 // be very slow (quadratic in the length). Setting robustness_flag to 5368 // ROBUST_STRING_TRAVERSAL invokes behaviour that is robust This means it 5369 // handles unexpected data without causing assert failures and it does not 5370 // do any heap allocations. This is useful when printing stack traces. 5371 SmartPointer<char> ToCString(AllowNullsFlag allow_nulls, 5372 RobustnessFlag robustness_flag, 5373 int offset, 5374 int length, 5375 int* length_output = 0); 5376 SmartPointer<char> ToCString( 5377 AllowNullsFlag allow_nulls = DISALLOW_NULLS, 5378 RobustnessFlag robustness_flag = FAST_STRING_TRAVERSAL, 5379 int* length_output = 0); 5380 5381 int Utf8Length(); 5382 5383 // Return a 16 bit Unicode representation of the string. 5384 // The string should be nearly flat, otherwise the performance of 5385 // of this method may be very bad. Setting robustness_flag to 5386 // ROBUST_STRING_TRAVERSAL invokes behaviour that is robust This means it 5387 // handles unexpected data without causing assert failures and it does not 5388 // do any heap allocations. This is useful when printing stack traces. 5389 SmartPointer<uc16> ToWideCString( 5390 RobustnessFlag robustness_flag = FAST_STRING_TRAVERSAL); 5391 5392 // Tells whether the hash code has been computed. 5393 inline bool HasHashCode(); 5394 5395 // Returns a hash value used for the property table 5396 inline uint32_t Hash(); 5397 5398 static uint32_t ComputeHashField(unibrow::CharacterStream* buffer, 5399 int length); 5400 5401 static bool ComputeArrayIndex(unibrow::CharacterStream* buffer, 5402 uint32_t* index, 5403 int length); 5404 5405 // Externalization. 5406 bool MakeExternal(v8::String::ExternalStringResource* resource); 5407 bool MakeExternal(v8::String::ExternalAsciiStringResource* resource); 5408 5409 // Conversion. 5410 inline bool AsArrayIndex(uint32_t* index); 5411 5412 // Casting. 5413 static inline String* cast(Object* obj); 5414 5415 void PrintOn(FILE* out); 5416 5417 // For use during stack traces. Performs rudimentary sanity check. 5418 bool LooksValid(); 5419 5420 // Dispatched behavior. 5421 void StringShortPrint(StringStream* accumulator); 5422 #ifdef OBJECT_PRINT 5423 inline void StringPrint() { 5424 StringPrint(stdout); 5425 } 5426 void StringPrint(FILE* out); 5427 #endif 5428 #ifdef DEBUG 5429 void StringVerify(); 5430 #endif 5431 inline bool IsFlat(); 5432 5433 // Layout description. 5434 static const int kLengthOffset = HeapObject::kHeaderSize; 5435 static const int kHashFieldOffset = kLengthOffset + kPointerSize; 5436 static const int kSize = kHashFieldOffset + kPointerSize; 5437 5438 // Maximum number of characters to consider when trying to convert a string 5439 // value into an array index. 5440 static const int kMaxArrayIndexSize = 10; 5441 5442 // Max ascii char code. 5443 static const int kMaxAsciiCharCode = unibrow::Utf8::kMaxOneByteChar; 5444 static const unsigned kMaxAsciiCharCodeU = unibrow::Utf8::kMaxOneByteChar; 5445 static const int kMaxUC16CharCode = 0xffff; 5446 5447 // Minimum length for a cons string. 5448 static const int kMinNonFlatLength = 13; 5449 5450 // Mask constant for checking if a string has a computed hash code 5451 // and if it is an array index. The least significant bit indicates 5452 // whether a hash code has been computed. If the hash code has been 5453 // computed the 2nd bit tells whether the string can be used as an 5454 // array index. 5455 static const int kHashNotComputedMask = 1; 5456 static const int kIsNotArrayIndexMask = 1 << 1; 5457 static const int kNofHashBitFields = 2; 5458 5459 // Shift constant retrieving hash code from hash field. 5460 static const int kHashShift = kNofHashBitFields; 5461 5462 // Array index strings this short can keep their index in the hash 5463 // field. 5464 static const int kMaxCachedArrayIndexLength = 7; 5465 5466 // For strings which are array indexes the hash value has the string length 5467 // mixed into the hash, mainly to avoid a hash value of zero which would be 5468 // the case for the string '0'. 24 bits are used for the array index value. 5469 static const int kArrayIndexValueBits = 24; 5470 static const int kArrayIndexLengthBits = 5471 kBitsPerInt - kArrayIndexValueBits - kNofHashBitFields; 5472 5473 STATIC_CHECK((kArrayIndexLengthBits > 0)); 5474 STATIC_CHECK(kMaxArrayIndexSize < (1 << kArrayIndexLengthBits)); 5475 5476 static const int kArrayIndexHashLengthShift = 5477 kArrayIndexValueBits + kNofHashBitFields; 5478 5479 static const int kArrayIndexHashMask = (1 << kArrayIndexHashLengthShift) - 1; 5480 5481 static const int kArrayIndexValueMask = 5482 ((1 << kArrayIndexValueBits) - 1) << kHashShift; 5483 5484 // Check that kMaxCachedArrayIndexLength + 1 is a power of two so we 5485 // could use a mask to test if the length of string is less than or equal to 5486 // kMaxCachedArrayIndexLength. 5487 STATIC_CHECK(IS_POWER_OF_TWO(kMaxCachedArrayIndexLength + 1)); 5488 5489 static const int kContainsCachedArrayIndexMask = 5490 (~kMaxCachedArrayIndexLength << kArrayIndexHashLengthShift) | 5491 kIsNotArrayIndexMask; 5492 5493 // Value of empty hash field indicating that the hash is not computed. 5494 static const int kEmptyHashField = 5495 kIsNotArrayIndexMask | kHashNotComputedMask; 5496 5497 // Value of hash field containing computed hash equal to zero. 5498 static const int kZeroHash = kIsNotArrayIndexMask; 5499 5500 // Maximal string length. 5501 static const int kMaxLength = (1 << (32 - 2)) - 1; 5502 5503 // Max length for computing hash. For strings longer than this limit the 5504 // string length is used as the hash value. 5505 static const int kMaxHashCalcLength = 16383; 5506 5507 // Limit for truncation in short printing. 5508 static const int kMaxShortPrintLength = 1024; 5509 5510 // Support for regular expressions. 5511 const uc16* GetTwoByteData(); 5512 const uc16* GetTwoByteData(unsigned start); 5513 5514 // Support for StringInputBuffer 5515 static const unibrow::byte* ReadBlock(String* input, 5516 unibrow::byte* util_buffer, 5517 unsigned capacity, 5518 unsigned* remaining, 5519 unsigned* offset); 5520 static const unibrow::byte* ReadBlock(String** input, 5521 unibrow::byte* util_buffer, 5522 unsigned capacity, 5523 unsigned* remaining, 5524 unsigned* offset); 5525 5526 // Helper function for flattening strings. 5527 template <typename sinkchar> 5528 static void WriteToFlat(String* source, 5529 sinkchar* sink, 5530 int from, 5531 int to); 5532 5533 static inline bool IsAscii(const char* chars, int length) { 5534 const char* limit = chars + length; 5535 #ifdef V8_HOST_CAN_READ_UNALIGNED 5536 ASSERT(kMaxAsciiCharCode == 0x7F); 5537 const uintptr_t non_ascii_mask = kUintptrAllBitsSet / 0xFF * 0x80; 5538 while (chars <= limit - sizeof(uintptr_t)) { 5539 if (*reinterpret_cast<const uintptr_t*>(chars) & non_ascii_mask) { 5540 return false; 5541 } 5542 chars += sizeof(uintptr_t); 5543 } 5544 #endif 5545 while (chars < limit) { 5546 if (static_cast<uint8_t>(*chars) > kMaxAsciiCharCodeU) return false; 5547 ++chars; 5548 } 5549 return true; 5550 } 5551 5552 static inline bool IsAscii(const uc16* chars, int length) { 5553 const uc16* limit = chars + length; 5554 while (chars < limit) { 5555 if (*chars > kMaxAsciiCharCodeU) return false; 5556 ++chars; 5557 } 5558 return true; 5559 } 5560 5561 protected: 5562 class ReadBlockBuffer { 5563 public: 5564 ReadBlockBuffer(unibrow::byte* util_buffer_, 5565 unsigned cursor_, 5566 unsigned capacity_, 5567 unsigned remaining_) : 5568 util_buffer(util_buffer_), 5569 cursor(cursor_), 5570 capacity(capacity_), 5571 remaining(remaining_) { 5572 } 5573 unibrow::byte* util_buffer; 5574 unsigned cursor; 5575 unsigned capacity; 5576 unsigned remaining; 5577 }; 5578 5579 static inline const unibrow::byte* ReadBlock(String* input, 5580 ReadBlockBuffer* buffer, 5581 unsigned* offset, 5582 unsigned max_chars); 5583 static void ReadBlockIntoBuffer(String* input, 5584 ReadBlockBuffer* buffer, 5585 unsigned* offset_ptr, 5586 unsigned max_chars); 5587 5588 private: 5589 // Try to flatten the top level ConsString that is hiding behind this 5590 // string. This is a no-op unless the string is a ConsString. Flatten 5591 // mutates the ConsString and might return a failure. 5592 MUST_USE_RESULT MaybeObject* SlowTryFlatten(PretenureFlag pretenure); 5593 5594 static inline bool IsHashFieldComputed(uint32_t field); 5595 5596 // Slow case of String::Equals. This implementation works on any strings 5597 // but it is most efficient on strings that are almost flat. 5598 bool SlowEquals(String* other); 5599 5600 // Slow case of AsArrayIndex. 5601 bool SlowAsArrayIndex(uint32_t* index); 5602 5603 // Compute and set the hash code. 5604 uint32_t ComputeAndSetHash(); 5605 5606 DISALLOW_IMPLICIT_CONSTRUCTORS(String); 5607 }; 5608 5609 5610 // The SeqString abstract class captures sequential string values. 5611 class SeqString: public String { 5612 public: 5613 5614 // Casting. 5615 static inline SeqString* cast(Object* obj); 5616 5617 private: 5618 DISALLOW_IMPLICIT_CONSTRUCTORS(SeqString); 5619 }; 5620 5621 5622 // The AsciiString class captures sequential ascii string objects. 5623 // Each character in the AsciiString is an ascii character. 5624 class SeqAsciiString: public SeqString { 5625 public: 5626 static const bool kHasAsciiEncoding = true; 5627 5628 // Dispatched behavior. 5629 inline uint16_t SeqAsciiStringGet(int index); 5630 inline void SeqAsciiStringSet(int index, uint16_t value); 5631 5632 // Get the address of the characters in this string. 5633 inline Address GetCharsAddress(); 5634 5635 inline char* GetChars(); 5636 5637 // Casting 5638 static inline SeqAsciiString* cast(Object* obj); 5639 5640 // Garbage collection support. This method is called by the 5641 // garbage collector to compute the actual size of an AsciiString 5642 // instance. 5643 inline int SeqAsciiStringSize(InstanceType instance_type); 5644 5645 // Computes the size for an AsciiString instance of a given length. 5646 static int SizeFor(int length) { 5647 return OBJECT_POINTER_ALIGN(kHeaderSize + length * kCharSize); 5648 } 5649 5650 // Layout description. 5651 static const int kHeaderSize = String::kSize; 5652 static const int kAlignedSize = POINTER_SIZE_ALIGN(kHeaderSize); 5653 5654 // Maximal memory usage for a single sequential ASCII string. 5655 static const int kMaxSize = 512 * MB; 5656 // Maximal length of a single sequential ASCII string. 5657 // Q.v. String::kMaxLength which is the maximal size of concatenated strings. 5658 static const int kMaxLength = (kMaxSize - kHeaderSize); 5659 5660 // Support for StringInputBuffer. 5661 inline void SeqAsciiStringReadBlockIntoBuffer(ReadBlockBuffer* buffer, 5662 unsigned* offset, 5663 unsigned chars); 5664 inline const unibrow::byte* SeqAsciiStringReadBlock(unsigned* remaining, 5665 unsigned* offset, 5666 unsigned chars); 5667 5668 private: 5669 DISALLOW_IMPLICIT_CONSTRUCTORS(SeqAsciiString); 5670 }; 5671 5672 5673 // The TwoByteString class captures sequential unicode string objects. 5674 // Each character in the TwoByteString is a two-byte uint16_t. 5675 class SeqTwoByteString: public SeqString { 5676 public: 5677 static const bool kHasAsciiEncoding = false; 5678 5679 // Dispatched behavior. 5680 inline uint16_t SeqTwoByteStringGet(int index); 5681 inline void SeqTwoByteStringSet(int index, uint16_t value); 5682 5683 // Get the address of the characters in this string. 5684 inline Address GetCharsAddress(); 5685 5686 inline uc16* GetChars(); 5687 5688 // For regexp code. 5689 const uint16_t* SeqTwoByteStringGetData(unsigned start); 5690 5691 // Casting 5692 static inline SeqTwoByteString* cast(Object* obj); 5693 5694 // Garbage collection support. This method is called by the 5695 // garbage collector to compute the actual size of a TwoByteString 5696 // instance. 5697 inline int SeqTwoByteStringSize(InstanceType instance_type); 5698 5699 // Computes the size for a TwoByteString instance of a given length. 5700 static int SizeFor(int length) { 5701 return OBJECT_POINTER_ALIGN(kHeaderSize + length * kShortSize); 5702 } 5703 5704 // Layout description. 5705 static const int kHeaderSize = String::kSize; 5706 static const int kAlignedSize = POINTER_SIZE_ALIGN(kHeaderSize); 5707 5708 // Maximal memory usage for a single sequential two-byte string. 5709 static const int kMaxSize = 512 * MB; 5710 // Maximal length of a single sequential two-byte string. 5711 // Q.v. String::kMaxLength which is the maximal size of concatenated strings. 5712 static const int kMaxLength = (kMaxSize - kHeaderSize) / sizeof(uint16_t); 5713 5714 // Support for StringInputBuffer. 5715 inline void SeqTwoByteStringReadBlockIntoBuffer(ReadBlockBuffer* buffer, 5716 unsigned* offset_ptr, 5717 unsigned chars); 5718 5719 private: 5720 DISALLOW_IMPLICIT_CONSTRUCTORS(SeqTwoByteString); 5721 }; 5722 5723 5724 // The ConsString class describes string values built by using the 5725 // addition operator on strings. A ConsString is a pair where the 5726 // first and second components are pointers to other string values. 5727 // One or both components of a ConsString can be pointers to other 5728 // ConsStrings, creating a binary tree of ConsStrings where the leaves 5729 // are non-ConsString string values. The string value represented by 5730 // a ConsString can be obtained by concatenating the leaf string 5731 // values in a left-to-right depth-first traversal of the tree. 5732 class ConsString: public String { 5733 public: 5734 // First string of the cons cell. 5735 inline String* first(); 5736 // Doesn't check that the result is a string, even in debug mode. This is 5737 // useful during GC where the mark bits confuse the checks. 5738 inline Object* unchecked_first(); 5739 inline void set_first(String* first, 5740 WriteBarrierMode mode = UPDATE_WRITE_BARRIER); 5741 5742 // Second string of the cons cell. 5743 inline String* second(); 5744 // Doesn't check that the result is a string, even in debug mode. This is 5745 // useful during GC where the mark bits confuse the checks. 5746 inline Object* unchecked_second(); 5747 inline void set_second(String* second, 5748 WriteBarrierMode mode = UPDATE_WRITE_BARRIER); 5749 5750 // Dispatched behavior. 5751 uint16_t ConsStringGet(int index); 5752 5753 // Casting. 5754 static inline ConsString* cast(Object* obj); 5755 5756 // Layout description. 5757 static const int kFirstOffset = POINTER_SIZE_ALIGN(String::kSize); 5758 static const int kSecondOffset = kFirstOffset + kPointerSize; 5759 static const int kSize = kSecondOffset + kPointerSize; 5760 5761 // Support for StringInputBuffer. 5762 inline const unibrow::byte* ConsStringReadBlock(ReadBlockBuffer* buffer, 5763 unsigned* offset_ptr, 5764 unsigned chars); 5765 inline void ConsStringReadBlockIntoBuffer(ReadBlockBuffer* buffer, 5766 unsigned* offset_ptr, 5767 unsigned chars); 5768 5769 // Minimum length for a cons string. 5770 static const int kMinLength = 13; 5771 5772 typedef FixedBodyDescriptor<kFirstOffset, kSecondOffset + kPointerSize, kSize> 5773 BodyDescriptor; 5774 5775 private: 5776 DISALLOW_IMPLICIT_CONSTRUCTORS(ConsString); 5777 }; 5778 5779 5780 // The ExternalString class describes string values that are backed by 5781 // a string resource that lies outside the V8 heap. ExternalStrings 5782 // consist of the length field common to all strings, a pointer to the 5783 // external resource. It is important to ensure (externally) that the 5784 // resource is not deallocated while the ExternalString is live in the 5785 // V8 heap. 5786 // 5787 // The API expects that all ExternalStrings are created through the 5788 // API. Therefore, ExternalStrings should not be used internally. 5789 class ExternalString: public String { 5790 public: 5791 // Casting 5792 static inline ExternalString* cast(Object* obj); 5793 5794 // Layout description. 5795 static const int kResourceOffset = POINTER_SIZE_ALIGN(String::kSize); 5796 static const int kSize = kResourceOffset + kPointerSize; 5797 5798 STATIC_CHECK(kResourceOffset == Internals::kStringResourceOffset); 5799 5800 private: 5801 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalString); 5802 }; 5803 5804 5805 // The ExternalAsciiString class is an external string backed by an 5806 // ASCII string. 5807 class ExternalAsciiString: public ExternalString { 5808 public: 5809 static const bool kHasAsciiEncoding = true; 5810 5811 typedef v8::String::ExternalAsciiStringResource Resource; 5812 5813 // The underlying resource. 5814 inline Resource* resource(); 5815 inline void set_resource(Resource* buffer); 5816 5817 // Dispatched behavior. 5818 uint16_t ExternalAsciiStringGet(int index); 5819 5820 // Casting. 5821 static inline ExternalAsciiString* cast(Object* obj); 5822 5823 // Garbage collection support. 5824 inline void ExternalAsciiStringIterateBody(ObjectVisitor* v); 5825 5826 template<typename StaticVisitor> 5827 inline void ExternalAsciiStringIterateBody(); 5828 5829 // Support for StringInputBuffer. 5830 const unibrow::byte* ExternalAsciiStringReadBlock(unsigned* remaining, 5831 unsigned* offset, 5832 unsigned chars); 5833 inline void ExternalAsciiStringReadBlockIntoBuffer(ReadBlockBuffer* buffer, 5834 unsigned* offset, 5835 unsigned chars); 5836 5837 private: 5838 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalAsciiString); 5839 }; 5840 5841 5842 // The ExternalTwoByteString class is an external string backed by a UTF-16 5843 // encoded string. 5844 class ExternalTwoByteString: public ExternalString { 5845 public: 5846 static const bool kHasAsciiEncoding = false; 5847 5848 typedef v8::String::ExternalStringResource Resource; 5849 5850 // The underlying string resource. 5851 inline Resource* resource(); 5852 inline void set_resource(Resource* buffer); 5853 5854 // Dispatched behavior. 5855 uint16_t ExternalTwoByteStringGet(int index); 5856 5857 // For regexp code. 5858 const uint16_t* ExternalTwoByteStringGetData(unsigned start); 5859 5860 // Casting. 5861 static inline ExternalTwoByteString* cast(Object* obj); 5862 5863 // Garbage collection support. 5864 inline void ExternalTwoByteStringIterateBody(ObjectVisitor* v); 5865 5866 template<typename StaticVisitor> 5867 inline void ExternalTwoByteStringIterateBody(); 5868 5869 5870 // Support for StringInputBuffer. 5871 void ExternalTwoByteStringReadBlockIntoBuffer(ReadBlockBuffer* buffer, 5872 unsigned* offset_ptr, 5873 unsigned chars); 5874 5875 private: 5876 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalTwoByteString); 5877 }; 5878 5879 5880 // Utility superclass for stack-allocated objects that must be updated 5881 // on gc. It provides two ways for the gc to update instances, either 5882 // iterating or updating after gc. 5883 class Relocatable BASE_EMBEDDED { 5884 public: 5885 explicit inline Relocatable(Isolate* isolate); 5886 inline virtual ~Relocatable(); 5887 virtual void IterateInstance(ObjectVisitor* v) { } 5888 virtual void PostGarbageCollection() { } 5889 5890 static void PostGarbageCollectionProcessing(); 5891 static int ArchiveSpacePerThread(); 5892 static char* ArchiveState(char* to); 5893 static char* RestoreState(char* from); 5894 static void Iterate(ObjectVisitor* v); 5895 static void Iterate(ObjectVisitor* v, Relocatable* top); 5896 static char* Iterate(ObjectVisitor* v, char* t); 5897 private: 5898 Isolate* isolate_; 5899 Relocatable* prev_; 5900 }; 5901 5902 5903 // A flat string reader provides random access to the contents of a 5904 // string independent of the character width of the string. The handle 5905 // must be valid as long as the reader is being used. 5906 class FlatStringReader : public Relocatable { 5907 public: 5908 FlatStringReader(Isolate* isolate, Handle<String> str); 5909 FlatStringReader(Isolate* isolate, Vector<const char> input); 5910 void PostGarbageCollection(); 5911 inline uc32 Get(int index); 5912 int length() { return length_; } 5913 private: 5914 String** str_; 5915 bool is_ascii_; 5916 int length_; 5917 const void* start_; 5918 }; 5919 5920 5921 // Note that StringInputBuffers are not valid across a GC! To fix this 5922 // it would have to store a String Handle instead of a String* and 5923 // AsciiStringReadBlock would have to be modified to use memcpy. 5924 // 5925 // StringInputBuffer is able to traverse any string regardless of how 5926 // deeply nested a sequence of ConsStrings it is made of. However, 5927 // performance will be better if deep strings are flattened before they 5928 // are traversed. Since flattening requires memory allocation this is 5929 // not always desirable, however (esp. in debugging situations). 5930 class StringInputBuffer: public unibrow::InputBuffer<String, String*, 1024> { 5931 public: 5932 virtual void Seek(unsigned pos); 5933 inline StringInputBuffer(): unibrow::InputBuffer<String, String*, 1024>() {} 5934 explicit inline StringInputBuffer(String* backing): 5935 unibrow::InputBuffer<String, String*, 1024>(backing) {} 5936 }; 5937 5938 5939 class SafeStringInputBuffer 5940 : public unibrow::InputBuffer<String, String**, 256> { 5941 public: 5942 virtual void Seek(unsigned pos); 5943 inline SafeStringInputBuffer() 5944 : unibrow::InputBuffer<String, String**, 256>() {} 5945 explicit inline SafeStringInputBuffer(String** backing) 5946 : unibrow::InputBuffer<String, String**, 256>(backing) {} 5947 }; 5948 5949 5950 template <typename T> 5951 class VectorIterator { 5952 public: 5953 VectorIterator(T* d, int l) : data_(Vector<const T>(d, l)), index_(0) { } 5954 explicit VectorIterator(Vector<const T> data) : data_(data), index_(0) { } 5955 T GetNext() { return data_[index_++]; } 5956 bool has_more() { return index_ < data_.length(); } 5957 private: 5958 Vector<const T> data_; 5959 int index_; 5960 }; 5961 5962 5963 // The Oddball describes objects null, undefined, true, and false. 5964 class Oddball: public HeapObject { 5965 public: 5966 // [to_string]: Cached to_string computed at startup. 5967 DECL_ACCESSORS(to_string, String) 5968 5969 // [to_number]: Cached to_number computed at startup. 5970 DECL_ACCESSORS(to_number, Object) 5971 5972 inline byte kind(); 5973 inline void set_kind(byte kind); 5974 5975 // Casting. 5976 static inline Oddball* cast(Object* obj); 5977 5978 // Dispatched behavior. 5979 #ifdef DEBUG 5980 void OddballVerify(); 5981 #endif 5982 5983 // Initialize the fields. 5984 MUST_USE_RESULT MaybeObject* Initialize(const char* to_string, 5985 Object* to_number, 5986 byte kind); 5987 5988 // Layout description. 5989 static const int kToStringOffset = HeapObject::kHeaderSize; 5990 static const int kToNumberOffset = kToStringOffset + kPointerSize; 5991 static const int kKindOffset = kToNumberOffset + kPointerSize; 5992 static const int kSize = kKindOffset + kPointerSize; 5993 5994 static const byte kFalse = 0; 5995 static const byte kTrue = 1; 5996 static const byte kNotBooleanMask = ~1; 5997 static const byte kTheHole = 2; 5998 static const byte kNull = 3; 5999 static const byte kArgumentMarker = 4; 6000 static const byte kUndefined = 5; 6001 static const byte kOther = 6; 6002 6003 typedef FixedBodyDescriptor<kToStringOffset, 6004 kToNumberOffset + kPointerSize, 6005 kSize> BodyDescriptor; 6006 6007 private: 6008 DISALLOW_IMPLICIT_CONSTRUCTORS(Oddball); 6009 }; 6010 6011 6012 class JSGlobalPropertyCell: public HeapObject { 6013 public: 6014 // [value]: value of the global property. 6015 DECL_ACCESSORS(value, Object) 6016 6017 // Casting. 6018 static inline JSGlobalPropertyCell* cast(Object* obj); 6019 6020 #ifdef DEBUG 6021 void JSGlobalPropertyCellVerify(); 6022 #endif 6023 #ifdef OBJECT_PRINT 6024 inline void JSGlobalPropertyCellPrint() { 6025 JSGlobalPropertyCellPrint(stdout); 6026 } 6027 void JSGlobalPropertyCellPrint(FILE* out); 6028 #endif 6029 6030 // Layout description. 6031 static const int kValueOffset = HeapObject::kHeaderSize; 6032 static const int kSize = kValueOffset + kPointerSize; 6033 6034 typedef FixedBodyDescriptor<kValueOffset, 6035 kValueOffset + kPointerSize, 6036 kSize> BodyDescriptor; 6037 6038 // Returns the isolate/heap this cell object belongs to. 6039 inline Isolate* isolate(); 6040 inline Heap* heap(); 6041 6042 private: 6043 DISALLOW_IMPLICIT_CONSTRUCTORS(JSGlobalPropertyCell); 6044 }; 6045 6046 6047 6048 // Proxy describes objects pointing from JavaScript to C structures. 6049 // Since they cannot contain references to JS HeapObjects they can be 6050 // placed in old_data_space. 6051 class Proxy: public HeapObject { 6052 public: 6053 // [proxy]: field containing the address. 6054 inline Address proxy(); 6055 inline void set_proxy(Address value); 6056 6057 // Casting. 6058 static inline Proxy* cast(Object* obj); 6059 6060 // Dispatched behavior. 6061 inline void ProxyIterateBody(ObjectVisitor* v); 6062 6063 template<typename StaticVisitor> 6064 inline void ProxyIterateBody(); 6065 6066 #ifdef OBJECT_PRINT 6067 inline void ProxyPrint() { 6068 ProxyPrint(stdout); 6069 } 6070 void ProxyPrint(FILE* out); 6071 #endif 6072 #ifdef DEBUG 6073 void ProxyVerify(); 6074 #endif 6075 6076 // Layout description. 6077 6078 static const int kProxyOffset = HeapObject::kHeaderSize; 6079 static const int kSize = kProxyOffset + kPointerSize; 6080 6081 STATIC_CHECK(kProxyOffset == Internals::kProxyProxyOffset); 6082 6083 private: 6084 DISALLOW_IMPLICIT_CONSTRUCTORS(Proxy); 6085 }; 6086 6087 6088 // The JSArray describes JavaScript Arrays 6089 // Such an array can be in one of two modes: 6090 // - fast, backing storage is a FixedArray and length <= elements.length(); 6091 // Please note: push and pop can be used to grow and shrink the array. 6092 // - slow, backing storage is a HashTable with numbers as keys. 6093 class JSArray: public JSObject { 6094 public: 6095 // [length]: The length property. 6096 DECL_ACCESSORS(length, Object) 6097 6098 // Overload the length setter to skip write barrier when the length 6099 // is set to a smi. This matches the set function on FixedArray. 6100 inline void set_length(Smi* length); 6101 6102 MUST_USE_RESULT MaybeObject* JSArrayUpdateLengthFromIndex(uint32_t index, 6103 Object* value); 6104 6105 // Initialize the array with the given capacity. The function may 6106 // fail due to out-of-memory situations, but only if the requested 6107 // capacity is non-zero. 6108 MUST_USE_RESULT MaybeObject* Initialize(int capacity); 6109 6110 // Set the content of the array to the content of storage. 6111 inline void SetContent(FixedArray* storage); 6112 6113 // Casting. 6114 static inline JSArray* cast(Object* obj); 6115 6116 // Uses handles. Ensures that the fixed array backing the JSArray has at 6117 // least the stated size. 6118 inline void EnsureSize(int minimum_size_of_backing_fixed_array); 6119 6120 // Dispatched behavior. 6121 #ifdef OBJECT_PRINT 6122 inline void JSArrayPrint() { 6123 JSArrayPrint(stdout); 6124 } 6125 void JSArrayPrint(FILE* out); 6126 #endif 6127 #ifdef DEBUG 6128 void JSArrayVerify(); 6129 #endif 6130 6131 // Number of element slots to pre-allocate for an empty array. 6132 static const int kPreallocatedArrayElements = 4; 6133 6134 // Layout description. 6135 static const int kLengthOffset = JSObject::kHeaderSize; 6136 static const int kSize = kLengthOffset + kPointerSize; 6137 6138 private: 6139 // Expand the fixed array backing of a fast-case JSArray to at least 6140 // the requested size. 6141 void Expand(int minimum_size_of_backing_fixed_array); 6142 6143 DISALLOW_IMPLICIT_CONSTRUCTORS(JSArray); 6144 }; 6145 6146 6147 // JSRegExpResult is just a JSArray with a specific initial map. 6148 // This initial map adds in-object properties for "index" and "input" 6149 // properties, as assigned by RegExp.prototype.exec, which allows 6150 // faster creation of RegExp exec results. 6151 // This class just holds constants used when creating the result. 6152 // After creation the result must be treated as a JSArray in all regards. 6153 class JSRegExpResult: public JSArray { 6154 public: 6155 // Offsets of object fields. 6156 static const int kIndexOffset = JSArray::kSize; 6157 static const int kInputOffset = kIndexOffset + kPointerSize; 6158 static const int kSize = kInputOffset + kPointerSize; 6159 // Indices of in-object properties. 6160 static const int kIndexIndex = 0; 6161 static const int kInputIndex = 1; 6162 private: 6163 DISALLOW_IMPLICIT_CONSTRUCTORS(JSRegExpResult); 6164 }; 6165 6166 6167 // An accessor must have a getter, but can have no setter. 6168 // 6169 // When setting a property, V8 searches accessors in prototypes. 6170 // If an accessor was found and it does not have a setter, 6171 // the request is ignored. 6172 // 6173 // If the accessor in the prototype has the READ_ONLY property attribute, then 6174 // a new value is added to the local object when the property is set. 6175 // This shadows the accessor in the prototype. 6176 class AccessorInfo: public Struct { 6177 public: 6178 DECL_ACCESSORS(getter, Object) 6179 DECL_ACCESSORS(setter, Object) 6180 DECL_ACCESSORS(data, Object) 6181 DECL_ACCESSORS(name, Object) 6182 DECL_ACCESSORS(flag, Smi) 6183 6184 inline bool all_can_read(); 6185 inline void set_all_can_read(bool value); 6186 6187 inline bool all_can_write(); 6188 inline void set_all_can_write(bool value); 6189 6190 inline bool prohibits_overwriting(); 6191 inline void set_prohibits_overwriting(bool value); 6192 6193 inline PropertyAttributes property_attributes(); 6194 inline void set_property_attributes(PropertyAttributes attributes); 6195 6196 static inline AccessorInfo* cast(Object* obj); 6197 6198 #ifdef OBJECT_PRINT 6199 inline void AccessorInfoPrint() { 6200 AccessorInfoPrint(stdout); 6201 } 6202 void AccessorInfoPrint(FILE* out); 6203 #endif 6204 #ifdef DEBUG 6205 void AccessorInfoVerify(); 6206 #endif 6207 6208 static const int kGetterOffset = HeapObject::kHeaderSize; 6209 static const int kSetterOffset = kGetterOffset + kPointerSize; 6210 static const int kDataOffset = kSetterOffset + kPointerSize; 6211 static const int kNameOffset = kDataOffset + kPointerSize; 6212 static const int kFlagOffset = kNameOffset + kPointerSize; 6213 static const int kSize = kFlagOffset + kPointerSize; 6214 6215 private: 6216 // Bit positions in flag. 6217 static const int kAllCanReadBit = 0; 6218 static const int kAllCanWriteBit = 1; 6219 static const int kProhibitsOverwritingBit = 2; 6220 class AttributesField: public BitField<PropertyAttributes, 3, 3> {}; 6221 6222 DISALLOW_IMPLICIT_CONSTRUCTORS(AccessorInfo); 6223 }; 6224 6225 6226 class AccessCheckInfo: public Struct { 6227 public: 6228 DECL_ACCESSORS(named_callback, Object) 6229 DECL_ACCESSORS(indexed_callback, Object) 6230 DECL_ACCESSORS(data, Object) 6231 6232 static inline AccessCheckInfo* cast(Object* obj); 6233 6234 #ifdef OBJECT_PRINT 6235 inline void AccessCheckInfoPrint() { 6236 AccessCheckInfoPrint(stdout); 6237 } 6238 void AccessCheckInfoPrint(FILE* out); 6239 #endif 6240 #ifdef DEBUG 6241 void AccessCheckInfoVerify(); 6242 #endif 6243 6244 static const int kNamedCallbackOffset = HeapObject::kHeaderSize; 6245 static const int kIndexedCallbackOffset = kNamedCallbackOffset + kPointerSize; 6246 static const int kDataOffset = kIndexedCallbackOffset + kPointerSize; 6247 static const int kSize = kDataOffset + kPointerSize; 6248 6249 private: 6250 DISALLOW_IMPLICIT_CONSTRUCTORS(AccessCheckInfo); 6251 }; 6252 6253 6254 class InterceptorInfo: public Struct { 6255 public: 6256 DECL_ACCESSORS(getter, Object) 6257 DECL_ACCESSORS(setter, Object) 6258 DECL_ACCESSORS(query, Object) 6259 DECL_ACCESSORS(deleter, Object) 6260 DECL_ACCESSORS(enumerator, Object) 6261 DECL_ACCESSORS(data, Object) 6262 6263 static inline InterceptorInfo* cast(Object* obj); 6264 6265 #ifdef OBJECT_PRINT 6266 inline void InterceptorInfoPrint() { 6267 InterceptorInfoPrint(stdout); 6268 } 6269 void InterceptorInfoPrint(FILE* out); 6270 #endif 6271 #ifdef DEBUG 6272 void InterceptorInfoVerify(); 6273 #endif 6274 6275 static const int kGetterOffset = HeapObject::kHeaderSize; 6276 static const int kSetterOffset = kGetterOffset + kPointerSize; 6277 static const int kQueryOffset = kSetterOffset + kPointerSize; 6278 static const int kDeleterOffset = kQueryOffset + kPointerSize; 6279 static const int kEnumeratorOffset = kDeleterOffset + kPointerSize; 6280 static const int kDataOffset = kEnumeratorOffset + kPointerSize; 6281 static const int kSize = kDataOffset + kPointerSize; 6282 6283 private: 6284 DISALLOW_IMPLICIT_CONSTRUCTORS(InterceptorInfo); 6285 }; 6286 6287 6288 class CallHandlerInfo: public Struct { 6289 public: 6290 DECL_ACCESSORS(callback, Object) 6291 DECL_ACCESSORS(data, Object) 6292 6293 static inline CallHandlerInfo* cast(Object* obj); 6294 6295 #ifdef OBJECT_PRINT 6296 inline void CallHandlerInfoPrint() { 6297 CallHandlerInfoPrint(stdout); 6298 } 6299 void CallHandlerInfoPrint(FILE* out); 6300 #endif 6301 #ifdef DEBUG 6302 void CallHandlerInfoVerify(); 6303 #endif 6304 6305 static const int kCallbackOffset = HeapObject::kHeaderSize; 6306 static const int kDataOffset = kCallbackOffset + kPointerSize; 6307 static const int kSize = kDataOffset + kPointerSize; 6308 6309 private: 6310 DISALLOW_IMPLICIT_CONSTRUCTORS(CallHandlerInfo); 6311 }; 6312 6313 6314 class TemplateInfo: public Struct { 6315 public: 6316 DECL_ACCESSORS(tag, Object) 6317 DECL_ACCESSORS(property_list, Object) 6318 6319 #ifdef DEBUG 6320 void TemplateInfoVerify(); 6321 #endif 6322 6323 static const int kTagOffset = HeapObject::kHeaderSize; 6324 static const int kPropertyListOffset = kTagOffset + kPointerSize; 6325 static const int kHeaderSize = kPropertyListOffset + kPointerSize; 6326 protected: 6327 friend class AGCCVersionRequiresThisClassToHaveAFriendSoHereItIs; 6328 DISALLOW_IMPLICIT_CONSTRUCTORS(TemplateInfo); 6329 }; 6330 6331 6332 class FunctionTemplateInfo: public TemplateInfo { 6333 public: 6334 DECL_ACCESSORS(serial_number, Object) 6335 DECL_ACCESSORS(call_code, Object) 6336 DECL_ACCESSORS(property_accessors, Object) 6337 DECL_ACCESSORS(prototype_template, Object) 6338 DECL_ACCESSORS(parent_template, Object) 6339 DECL_ACCESSORS(named_property_handler, Object) 6340 DECL_ACCESSORS(indexed_property_handler, Object) 6341 DECL_ACCESSORS(instance_template, Object) 6342 DECL_ACCESSORS(class_name, Object) 6343 DECL_ACCESSORS(signature, Object) 6344 DECL_ACCESSORS(instance_call_handler, Object) 6345 DECL_ACCESSORS(access_check_info, Object) 6346 DECL_ACCESSORS(flag, Smi) 6347 6348 // Following properties use flag bits. 6349 DECL_BOOLEAN_ACCESSORS(hidden_prototype) 6350 DECL_BOOLEAN_ACCESSORS(undetectable) 6351 // If the bit is set, object instances created by this function 6352 // requires access check. 6353 DECL_BOOLEAN_ACCESSORS(needs_access_check) 6354 6355 static inline FunctionTemplateInfo* cast(Object* obj); 6356 6357 #ifdef OBJECT_PRINT 6358 inline void FunctionTemplateInfoPrint() { 6359 FunctionTemplateInfoPrint(stdout); 6360 } 6361 void FunctionTemplateInfoPrint(FILE* out); 6362 #endif 6363 #ifdef DEBUG 6364 void FunctionTemplateInfoVerify(); 6365 #endif 6366 6367 static const int kSerialNumberOffset = TemplateInfo::kHeaderSize; 6368 static const int kCallCodeOffset = kSerialNumberOffset + kPointerSize; 6369 static const int kPropertyAccessorsOffset = kCallCodeOffset + kPointerSize; 6370 static const int kPrototypeTemplateOffset = 6371 kPropertyAccessorsOffset + kPointerSize; 6372 static const int kParentTemplateOffset = 6373 kPrototypeTemplateOffset + kPointerSize; 6374 static const int kNamedPropertyHandlerOffset = 6375 kParentTemplateOffset + kPointerSize; 6376 static const int kIndexedPropertyHandlerOffset = 6377 kNamedPropertyHandlerOffset + kPointerSize; 6378 static const int kInstanceTemplateOffset = 6379 kIndexedPropertyHandlerOffset + kPointerSize; 6380 static const int kClassNameOffset = kInstanceTemplateOffset + kPointerSize; 6381 static const int kSignatureOffset = kClassNameOffset + kPointerSize; 6382 static const int kInstanceCallHandlerOffset = kSignatureOffset + kPointerSize; 6383 static const int kAccessCheckInfoOffset = 6384 kInstanceCallHandlerOffset + kPointerSize; 6385 static const int kFlagOffset = kAccessCheckInfoOffset + kPointerSize; 6386 static const int kSize = kFlagOffset + kPointerSize; 6387 6388 private: 6389 // Bit position in the flag, from least significant bit position. 6390 static const int kHiddenPrototypeBit = 0; 6391 static const int kUndetectableBit = 1; 6392 static const int kNeedsAccessCheckBit = 2; 6393 6394 DISALLOW_IMPLICIT_CONSTRUCTORS(FunctionTemplateInfo); 6395 }; 6396 6397 6398 class ObjectTemplateInfo: public TemplateInfo { 6399 public: 6400 DECL_ACCESSORS(constructor, Object) 6401 DECL_ACCESSORS(internal_field_count, Object) 6402 6403 static inline ObjectTemplateInfo* cast(Object* obj); 6404 6405 #ifdef OBJECT_PRINT 6406 inline void ObjectTemplateInfoPrint() { 6407 ObjectTemplateInfoPrint(stdout); 6408 } 6409 void ObjectTemplateInfoPrint(FILE* out); 6410 #endif 6411 #ifdef DEBUG 6412 void ObjectTemplateInfoVerify(); 6413 #endif 6414 6415 static const int kConstructorOffset = TemplateInfo::kHeaderSize; 6416 static const int kInternalFieldCountOffset = 6417 kConstructorOffset + kPointerSize; 6418 static const int kSize = kInternalFieldCountOffset + kPointerSize; 6419 }; 6420 6421 6422 class SignatureInfo: public Struct { 6423 public: 6424 DECL_ACCESSORS(receiver, Object) 6425 DECL_ACCESSORS(args, Object) 6426 6427 static inline SignatureInfo* cast(Object* obj); 6428 6429 #ifdef OBJECT_PRINT 6430 inline void SignatureInfoPrint() { 6431 SignatureInfoPrint(stdout); 6432 } 6433 void SignatureInfoPrint(FILE* out); 6434 #endif 6435 #ifdef DEBUG 6436 void SignatureInfoVerify(); 6437 #endif 6438 6439 static const int kReceiverOffset = Struct::kHeaderSize; 6440 static const int kArgsOffset = kReceiverOffset + kPointerSize; 6441 static const int kSize = kArgsOffset + kPointerSize; 6442 6443 private: 6444 DISALLOW_IMPLICIT_CONSTRUCTORS(SignatureInfo); 6445 }; 6446 6447 6448 class TypeSwitchInfo: public Struct { 6449 public: 6450 DECL_ACCESSORS(types, Object) 6451 6452 static inline TypeSwitchInfo* cast(Object* obj); 6453 6454 #ifdef OBJECT_PRINT 6455 inline void TypeSwitchInfoPrint() { 6456 TypeSwitchInfoPrint(stdout); 6457 } 6458 void TypeSwitchInfoPrint(FILE* out); 6459 #endif 6460 #ifdef DEBUG 6461 void TypeSwitchInfoVerify(); 6462 #endif 6463 6464 static const int kTypesOffset = Struct::kHeaderSize; 6465 static const int kSize = kTypesOffset + kPointerSize; 6466 }; 6467 6468 6469 #ifdef ENABLE_DEBUGGER_SUPPORT 6470 // The DebugInfo class holds additional information for a function being 6471 // debugged. 6472 class DebugInfo: public Struct { 6473 public: 6474 // The shared function info for the source being debugged. 6475 DECL_ACCESSORS(shared, SharedFunctionInfo) 6476 // Code object for the original code. 6477 DECL_ACCESSORS(original_code, Code) 6478 // Code object for the patched code. This code object is the code object 6479 // currently active for the function. 6480 DECL_ACCESSORS(code, Code) 6481 // Fixed array holding status information for each active break point. 6482 DECL_ACCESSORS(break_points, FixedArray) 6483 6484 // Check if there is a break point at a code position. 6485 bool HasBreakPoint(int code_position); 6486 // Get the break point info object for a code position. 6487 Object* GetBreakPointInfo(int code_position); 6488 // Clear a break point. 6489 static void ClearBreakPoint(Handle<DebugInfo> debug_info, 6490 int code_position, 6491 Handle<Object> break_point_object); 6492 // Set a break point. 6493 static void SetBreakPoint(Handle<DebugInfo> debug_info, int code_position, 6494 int source_position, int statement_position, 6495 Handle<Object> break_point_object); 6496 // Get the break point objects for a code position. 6497 Object* GetBreakPointObjects(int code_position); 6498 // Find the break point info holding this break point object. 6499 static Object* FindBreakPointInfo(Handle<DebugInfo> debug_info, 6500 Handle<Object> break_point_object); 6501 // Get the number of break points for this function. 6502 int GetBreakPointCount(); 6503 6504 static inline DebugInfo* cast(Object* obj); 6505 6506 #ifdef OBJECT_PRINT 6507 inline void DebugInfoPrint() { 6508 DebugInfoPrint(stdout); 6509 } 6510 void DebugInfoPrint(FILE* out); 6511 #endif 6512 #ifdef DEBUG 6513 void DebugInfoVerify(); 6514 #endif 6515 6516 static const int kSharedFunctionInfoIndex = Struct::kHeaderSize; 6517 static const int kOriginalCodeIndex = kSharedFunctionInfoIndex + kPointerSize; 6518 static const int kPatchedCodeIndex = kOriginalCodeIndex + kPointerSize; 6519 static const int kActiveBreakPointsCountIndex = 6520 kPatchedCodeIndex + kPointerSize; 6521 static const int kBreakPointsStateIndex = 6522 kActiveBreakPointsCountIndex + kPointerSize; 6523 static const int kSize = kBreakPointsStateIndex + kPointerSize; 6524 6525 private: 6526 static const int kNoBreakPointInfo = -1; 6527 6528 // Lookup the index in the break_points array for a code position. 6529 int GetBreakPointInfoIndex(int code_position); 6530 6531 DISALLOW_IMPLICIT_CONSTRUCTORS(DebugInfo); 6532 }; 6533 6534 6535 // The BreakPointInfo class holds information for break points set in a 6536 // function. The DebugInfo object holds a BreakPointInfo object for each code 6537 // position with one or more break points. 6538 class BreakPointInfo: public Struct { 6539 public: 6540 // The position in the code for the break point. 6541 DECL_ACCESSORS(code_position, Smi) 6542 // The position in the source for the break position. 6543 DECL_ACCESSORS(source_position, Smi) 6544 // The position in the source for the last statement before this break 6545 // position. 6546 DECL_ACCESSORS(statement_position, Smi) 6547 // List of related JavaScript break points. 6548 DECL_ACCESSORS(break_point_objects, Object) 6549 6550 // Removes a break point. 6551 static void ClearBreakPoint(Handle<BreakPointInfo> info, 6552 Handle<Object> break_point_object); 6553 // Set a break point. 6554 static void SetBreakPoint(Handle<BreakPointInfo> info, 6555 Handle<Object> break_point_object); 6556 // Check if break point info has this break point object. 6557 static bool HasBreakPointObject(Handle<BreakPointInfo> info, 6558 Handle<Object> break_point_object); 6559 // Get the number of break points for this code position. 6560 int GetBreakPointCount(); 6561 6562 static inline BreakPointInfo* cast(Object* obj); 6563 6564 #ifdef OBJECT_PRINT 6565 inline void BreakPointInfoPrint() { 6566 BreakPointInfoPrint(stdout); 6567 } 6568 void BreakPointInfoPrint(FILE* out); 6569 #endif 6570 #ifdef DEBUG 6571 void BreakPointInfoVerify(); 6572 #endif 6573 6574 static const int kCodePositionIndex = Struct::kHeaderSize; 6575 static const int kSourcePositionIndex = kCodePositionIndex + kPointerSize; 6576 static const int kStatementPositionIndex = 6577 kSourcePositionIndex + kPointerSize; 6578 static const int kBreakPointObjectsIndex = 6579 kStatementPositionIndex + kPointerSize; 6580 static const int kSize = kBreakPointObjectsIndex + kPointerSize; 6581 6582 private: 6583 DISALLOW_IMPLICIT_CONSTRUCTORS(BreakPointInfo); 6584 }; 6585 #endif // ENABLE_DEBUGGER_SUPPORT 6586 6587 6588 #undef DECL_BOOLEAN_ACCESSORS 6589 #undef DECL_ACCESSORS 6590 6591 6592 // Abstract base class for visiting, and optionally modifying, the 6593 // pointers contained in Objects. Used in GC and serialization/deserialization. 6594 class ObjectVisitor BASE_EMBEDDED { 6595 public: 6596 virtual ~ObjectVisitor() {} 6597 6598 // Visits a contiguous arrays of pointers in the half-open range 6599 // [start, end). Any or all of the values may be modified on return. 6600 virtual void VisitPointers(Object** start, Object** end) = 0; 6601 6602 // To allow lazy clearing of inline caches the visitor has 6603 // a rich interface for iterating over Code objects.. 6604 6605 // Visits a code target in the instruction stream. 6606 virtual void VisitCodeTarget(RelocInfo* rinfo); 6607 6608 // Visits a code entry in a JS function. 6609 virtual void VisitCodeEntry(Address entry_address); 6610 6611 // Visits a global property cell reference in the instruction stream. 6612 virtual void VisitGlobalPropertyCell(RelocInfo* rinfo); 6613 6614 // Visits a runtime entry in the instruction stream. 6615 virtual void VisitRuntimeEntry(RelocInfo* rinfo) {} 6616 6617 // Visits the resource of an ASCII or two-byte string. 6618 virtual void VisitExternalAsciiString( 6619 v8::String::ExternalAsciiStringResource** resource) {} 6620 virtual void VisitExternalTwoByteString( 6621 v8::String::ExternalStringResource** resource) {} 6622 6623 // Visits a debug call target in the instruction stream. 6624 virtual void VisitDebugTarget(RelocInfo* rinfo); 6625 6626 // Handy shorthand for visiting a single pointer. 6627 virtual void VisitPointer(Object** p) { VisitPointers(p, p + 1); } 6628 6629 // Visits a contiguous arrays of external references (references to the C++ 6630 // heap) in the half-open range [start, end). Any or all of the values 6631 // may be modified on return. 6632 virtual void VisitExternalReferences(Address* start, Address* end) {} 6633 6634 inline void VisitExternalReference(Address* p) { 6635 VisitExternalReferences(p, p + 1); 6636 } 6637 6638 // Visits a handle that has an embedder-assigned class ID. 6639 virtual void VisitEmbedderReference(Object** p, uint16_t class_id) {} 6640 6641 #ifdef DEBUG 6642 // Intended for serialization/deserialization checking: insert, or 6643 // check for the presence of, a tag at this position in the stream. 6644 virtual void Synchronize(const char* tag) {} 6645 #else 6646 inline void Synchronize(const char* tag) {} 6647 #endif 6648 }; 6649 6650 6651 class StructBodyDescriptor : public 6652 FlexibleBodyDescriptor<HeapObject::kHeaderSize> { 6653 public: 6654 static inline int SizeOf(Map* map, HeapObject* object) { 6655 return map->instance_size(); 6656 } 6657 }; 6658 6659 6660 // BooleanBit is a helper class for setting and getting a bit in an 6661 // integer or Smi. 6662 class BooleanBit : public AllStatic { 6663 public: 6664 static inline bool get(Smi* smi, int bit_position) { 6665 return get(smi->value(), bit_position); 6666 } 6667 6668 static inline bool get(int value, int bit_position) { 6669 return (value & (1 << bit_position)) != 0; 6670 } 6671 6672 static inline Smi* set(Smi* smi, int bit_position, bool v) { 6673 return Smi::FromInt(set(smi->value(), bit_position, v)); 6674 } 6675 6676 static inline int set(int value, int bit_position, bool v) { 6677 if (v) { 6678 value |= (1 << bit_position); 6679 } else { 6680 value &= ~(1 << bit_position); 6681 } 6682 return value; 6683 } 6684 }; 6685 6686 } } // namespace v8::internal 6687 6688 #endif // V8_OBJECTS_H_ 6689