1 // Copyright 2006-2009 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 "code-stubs.h" 33 #include "smart-pointer.h" 34 #include "unicode-inl.h" 35 #if V8_TARGET_ARCH_ARM 36 #include "arm/constants-arm.h" 37 #elif V8_TARGET_ARCH_MIPS 38 #include "mips/constants-mips.h" 39 #endif 40 41 // 42 // All object types in the V8 JavaScript are described in this file. 43 // 44 // Inheritance hierarchy: 45 // - Object 46 // - Smi (immediate small integer) 47 // - Failure (immediate for marking failed operation) 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 // - Array 59 // - ByteArray 60 // - PixelArray 61 // - ExternalArray 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 // - MapCache 76 // - Context 77 // - GlobalContext 78 // - String 79 // - SeqString 80 // - SeqAsciiString 81 // - SeqTwoByteString 82 // - ConsString 83 // - ExternalString 84 // - ExternalAsciiString 85 // - ExternalTwoByteString 86 // - HeapNumber 87 // - Code 88 // - Map 89 // - Oddball 90 // - Proxy 91 // - SharedFunctionInfo 92 // - Struct 93 // - AccessorInfo 94 // - AccessCheckInfo 95 // - InterceptorInfo 96 // - CallHandlerInfo 97 // - TemplateInfo 98 // - FunctionTemplateInfo 99 // - ObjectTemplateInfo 100 // - Script 101 // - SignatureInfo 102 // - TypeSwitchInfo 103 // - DebugInfo 104 // - BreakPointInfo 105 // 106 // Formats of Object*: 107 // Smi: [31 bit signed int] 0 108 // HeapObject: [32 bit direct pointer] (4 byte aligned) | 01 109 // Failure: [30 bit signed int] 11 110 111 // Ecma-262 3rd 8.6.1 112 enum PropertyAttributes { 113 NONE = v8::None, 114 READ_ONLY = v8::ReadOnly, 115 DONT_ENUM = v8::DontEnum, 116 DONT_DELETE = v8::DontDelete, 117 ABSENT = 16 // Used in runtime to indicate a property is absent. 118 // ABSENT can never be stored in or returned from a descriptor's attributes 119 // bitfield. It is only used as a return value meaning the attributes of 120 // a non-existent property. 121 }; 122 123 namespace v8 { 124 namespace internal { 125 126 127 // PropertyDetails captures type and attributes for a property. 128 // They are used both in property dictionaries and instance descriptors. 129 class PropertyDetails BASE_EMBEDDED { 130 public: 131 132 PropertyDetails(PropertyAttributes attributes, 133 PropertyType type, 134 int index = 0) { 135 ASSERT(TypeField::is_valid(type)); 136 ASSERT(AttributesField::is_valid(attributes)); 137 ASSERT(IndexField::is_valid(index)); 138 139 value_ = TypeField::encode(type) 140 | AttributesField::encode(attributes) 141 | IndexField::encode(index); 142 143 ASSERT(type == this->type()); 144 ASSERT(attributes == this->attributes()); 145 ASSERT(index == this->index()); 146 } 147 148 // Conversion for storing details as Object*. 149 inline PropertyDetails(Smi* smi); 150 inline Smi* AsSmi(); 151 type()152 PropertyType type() { return TypeField::decode(value_); } 153 IsTransition()154 bool IsTransition() { 155 PropertyType t = type(); 156 ASSERT(t != INTERCEPTOR); 157 return t == MAP_TRANSITION || t == CONSTANT_TRANSITION; 158 } 159 IsProperty()160 bool IsProperty() { 161 return type() < FIRST_PHANTOM_PROPERTY_TYPE; 162 } 163 attributes()164 PropertyAttributes attributes() { return AttributesField::decode(value_); } 165 index()166 int index() { return IndexField::decode(value_); } 167 168 inline PropertyDetails AsDeleted(); 169 IsValidIndex(int index)170 static bool IsValidIndex(int index) { return IndexField::is_valid(index); } 171 IsReadOnly()172 bool IsReadOnly() { return (attributes() & READ_ONLY) != 0; } IsDontDelete()173 bool IsDontDelete() { return (attributes() & DONT_DELETE) != 0; } IsDontEnum()174 bool IsDontEnum() { return (attributes() & DONT_ENUM) != 0; } IsDeleted()175 bool IsDeleted() { return DeletedField::decode(value_) != 0;} 176 177 // Bit fields in value_ (type, shift, size). Must be public so the 178 // constants can be embedded in generated code. 179 class TypeField: public BitField<PropertyType, 0, 3> {}; 180 class AttributesField: public BitField<PropertyAttributes, 3, 3> {}; 181 class DeletedField: public BitField<uint32_t, 6, 1> {}; 182 class IndexField: public BitField<uint32_t, 7, 32-7> {}; 183 184 static const int kInitialIndex = 1; 185 private: 186 uint32_t value_; 187 }; 188 189 190 // Setter that skips the write barrier if mode is SKIP_WRITE_BARRIER. 191 enum WriteBarrierMode { SKIP_WRITE_BARRIER, UPDATE_WRITE_BARRIER }; 192 193 194 // PropertyNormalizationMode is used to specify whether to keep 195 // inobject properties when normalizing properties of a JSObject. 196 enum PropertyNormalizationMode { 197 CLEAR_INOBJECT_PROPERTIES, 198 KEEP_INOBJECT_PROPERTIES 199 }; 200 201 202 // All Maps have a field instance_type containing a InstanceType. 203 // It describes the type of the instances. 204 // 205 // As an example, a JavaScript object is a heap object and its map 206 // instance_type is JS_OBJECT_TYPE. 207 // 208 // The names of the string instance types are intended to systematically 209 // mirror their encoding in the instance_type field of the map. The default 210 // encoding is considered TWO_BYTE. It is not mentioned in the name. ASCII 211 // encoding is mentioned explicitly in the name. Likewise, the default 212 // representation is considered sequential. It is not mentioned in the 213 // name. The other representations (eg, CONS, EXTERNAL) are explicitly 214 // mentioned. Finally, the string is either a SYMBOL_TYPE (if it is a 215 // symbol) or a STRING_TYPE (if it is not a symbol). 216 // 217 // NOTE: The following things are some that depend on the string types having 218 // instance_types that are less than those of all other types: 219 // HeapObject::Size, HeapObject::IterateBody, the typeof operator, and 220 // Object::IsString. 221 // 222 // NOTE: Everything following JS_VALUE_TYPE is considered a 223 // JSObject for GC purposes. The first four entries here have typeof 224 // 'object', whereas JS_FUNCTION_TYPE has typeof 'function'. 225 #define INSTANCE_TYPE_LIST_ALL(V) \ 226 V(SYMBOL_TYPE) \ 227 V(ASCII_SYMBOL_TYPE) \ 228 V(CONS_SYMBOL_TYPE) \ 229 V(CONS_ASCII_SYMBOL_TYPE) \ 230 V(EXTERNAL_SYMBOL_TYPE) \ 231 V(EXTERNAL_ASCII_SYMBOL_TYPE) \ 232 V(STRING_TYPE) \ 233 V(ASCII_STRING_TYPE) \ 234 V(CONS_STRING_TYPE) \ 235 V(CONS_ASCII_STRING_TYPE) \ 236 V(EXTERNAL_STRING_TYPE) \ 237 V(EXTERNAL_ASCII_STRING_TYPE) \ 238 V(PRIVATE_EXTERNAL_ASCII_STRING_TYPE) \ 239 \ 240 V(MAP_TYPE) \ 241 V(CODE_TYPE) \ 242 V(JS_GLOBAL_PROPERTY_CELL_TYPE) \ 243 V(ODDBALL_TYPE) \ 244 \ 245 V(HEAP_NUMBER_TYPE) \ 246 V(PROXY_TYPE) \ 247 V(BYTE_ARRAY_TYPE) \ 248 V(PIXEL_ARRAY_TYPE) \ 249 /* Note: the order of these external array */ \ 250 /* types is relied upon in */ \ 251 /* Object::IsExternalArray(). */ \ 252 V(EXTERNAL_BYTE_ARRAY_TYPE) \ 253 V(EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE) \ 254 V(EXTERNAL_SHORT_ARRAY_TYPE) \ 255 V(EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE) \ 256 V(EXTERNAL_INT_ARRAY_TYPE) \ 257 V(EXTERNAL_UNSIGNED_INT_ARRAY_TYPE) \ 258 V(EXTERNAL_FLOAT_ARRAY_TYPE) \ 259 V(FILLER_TYPE) \ 260 \ 261 V(FIXED_ARRAY_TYPE) \ 262 V(ACCESSOR_INFO_TYPE) \ 263 V(ACCESS_CHECK_INFO_TYPE) \ 264 V(INTERCEPTOR_INFO_TYPE) \ 265 V(SHARED_FUNCTION_INFO_TYPE) \ 266 V(CALL_HANDLER_INFO_TYPE) \ 267 V(FUNCTION_TEMPLATE_INFO_TYPE) \ 268 V(OBJECT_TEMPLATE_INFO_TYPE) \ 269 V(SIGNATURE_INFO_TYPE) \ 270 V(TYPE_SWITCH_INFO_TYPE) \ 271 V(SCRIPT_TYPE) \ 272 \ 273 V(JS_VALUE_TYPE) \ 274 V(JS_OBJECT_TYPE) \ 275 V(JS_CONTEXT_EXTENSION_OBJECT_TYPE) \ 276 V(JS_GLOBAL_OBJECT_TYPE) \ 277 V(JS_BUILTINS_OBJECT_TYPE) \ 278 V(JS_GLOBAL_PROXY_TYPE) \ 279 V(JS_ARRAY_TYPE) \ 280 V(JS_REGEXP_TYPE) \ 281 \ 282 V(JS_FUNCTION_TYPE) \ 283 284 #ifdef ENABLE_DEBUGGER_SUPPORT 285 #define INSTANCE_TYPE_LIST_DEBUGGER(V) \ 286 V(DEBUG_INFO_TYPE) \ 287 V(BREAK_POINT_INFO_TYPE) 288 #else 289 #define INSTANCE_TYPE_LIST_DEBUGGER(V) 290 #endif 291 292 #define INSTANCE_TYPE_LIST(V) \ 293 INSTANCE_TYPE_LIST_ALL(V) \ 294 INSTANCE_TYPE_LIST_DEBUGGER(V) 295 296 297 // Since string types are not consecutive, this macro is used to 298 // iterate over them. 299 #define STRING_TYPE_LIST(V) \ 300 V(SYMBOL_TYPE, \ 301 SeqTwoByteString::kAlignedSize, \ 302 symbol, \ 303 Symbol) \ 304 V(ASCII_SYMBOL_TYPE, \ 305 SeqAsciiString::kAlignedSize, \ 306 ascii_symbol, \ 307 AsciiSymbol) \ 308 V(CONS_SYMBOL_TYPE, \ 309 ConsString::kSize, \ 310 cons_symbol, \ 311 ConsSymbol) \ 312 V(CONS_ASCII_SYMBOL_TYPE, \ 313 ConsString::kSize, \ 314 cons_ascii_symbol, \ 315 ConsAsciiSymbol) \ 316 V(EXTERNAL_SYMBOL_TYPE, \ 317 ExternalTwoByteString::kSize, \ 318 external_symbol, \ 319 ExternalSymbol) \ 320 V(EXTERNAL_ASCII_SYMBOL_TYPE, \ 321 ExternalAsciiString::kSize, \ 322 external_ascii_symbol, \ 323 ExternalAsciiSymbol) \ 324 V(STRING_TYPE, \ 325 SeqTwoByteString::kAlignedSize, \ 326 string, \ 327 String) \ 328 V(ASCII_STRING_TYPE, \ 329 SeqAsciiString::kAlignedSize, \ 330 ascii_string, \ 331 AsciiString) \ 332 V(CONS_STRING_TYPE, \ 333 ConsString::kSize, \ 334 cons_string, \ 335 ConsString) \ 336 V(CONS_ASCII_STRING_TYPE, \ 337 ConsString::kSize, \ 338 cons_ascii_string, \ 339 ConsAsciiString) \ 340 V(EXTERNAL_STRING_TYPE, \ 341 ExternalTwoByteString::kSize, \ 342 external_string, \ 343 ExternalString) \ 344 V(EXTERNAL_ASCII_STRING_TYPE, \ 345 ExternalAsciiString::kSize, \ 346 external_ascii_string, \ 347 ExternalAsciiString) \ 348 349 // A struct is a simple object a set of object-valued fields. Including an 350 // object type in this causes the compiler to generate most of the boilerplate 351 // code for the class including allocation and garbage collection routines, 352 // casts and predicates. All you need to define is the class, methods and 353 // object verification routines. Easy, no? 354 // 355 // Note that for subtle reasons related to the ordering or numerical values of 356 // type tags, elements in this list have to be added to the INSTANCE_TYPE_LIST 357 // manually. 358 #define STRUCT_LIST_ALL(V) \ 359 V(ACCESSOR_INFO, AccessorInfo, accessor_info) \ 360 V(ACCESS_CHECK_INFO, AccessCheckInfo, access_check_info) \ 361 V(INTERCEPTOR_INFO, InterceptorInfo, interceptor_info) \ 362 V(CALL_HANDLER_INFO, CallHandlerInfo, call_handler_info) \ 363 V(FUNCTION_TEMPLATE_INFO, FunctionTemplateInfo, function_template_info) \ 364 V(OBJECT_TEMPLATE_INFO, ObjectTemplateInfo, object_template_info) \ 365 V(SIGNATURE_INFO, SignatureInfo, signature_info) \ 366 V(TYPE_SWITCH_INFO, TypeSwitchInfo, type_switch_info) \ 367 V(SCRIPT, Script, script) 368 369 #ifdef ENABLE_DEBUGGER_SUPPORT 370 #define STRUCT_LIST_DEBUGGER(V) \ 371 V(DEBUG_INFO, DebugInfo, debug_info) \ 372 V(BREAK_POINT_INFO, BreakPointInfo, break_point_info) 373 #else 374 #define STRUCT_LIST_DEBUGGER(V) 375 #endif 376 377 #define STRUCT_LIST(V) \ 378 STRUCT_LIST_ALL(V) \ 379 STRUCT_LIST_DEBUGGER(V) 380 381 // We use the full 8 bits of the instance_type field to encode heap object 382 // instance types. The high-order bit (bit 7) is set if the object is not a 383 // string, and cleared if it is a string. 384 const uint32_t kIsNotStringMask = 0x80; 385 const uint32_t kStringTag = 0x0; 386 const uint32_t kNotStringTag = 0x80; 387 388 // Bit 6 indicates that the object is a symbol (if set) or not (if cleared). 389 // There are not enough types that the non-string types (with bit 7 set) can 390 // have bit 6 set too. 391 const uint32_t kIsSymbolMask = 0x40; 392 const uint32_t kNotSymbolTag = 0x0; 393 const uint32_t kSymbolTag = 0x40; 394 395 // If bit 7 is clear then bit 2 indicates whether the string consists of 396 // two-byte characters or one-byte characters. 397 const uint32_t kStringEncodingMask = 0x4; 398 const uint32_t kTwoByteStringTag = 0x0; 399 const uint32_t kAsciiStringTag = 0x4; 400 401 // If bit 7 is clear, the low-order 2 bits indicate the representation 402 // of the string. 403 const uint32_t kStringRepresentationMask = 0x03; 404 enum StringRepresentationTag { 405 kSeqStringTag = 0x0, 406 kConsStringTag = 0x1, 407 kExternalStringTag = 0x3 408 }; 409 410 411 // A ConsString with an empty string as the right side is a candidate 412 // for being shortcut by the garbage collector unless it is a 413 // symbol. It's not common to have non-flat symbols, so we do not 414 // shortcut them thereby avoiding turning symbols into strings. See 415 // heap.cc and mark-compact.cc. 416 const uint32_t kShortcutTypeMask = 417 kIsNotStringMask | 418 kIsSymbolMask | 419 kStringRepresentationMask; 420 const uint32_t kShortcutTypeTag = kConsStringTag; 421 422 423 enum InstanceType { 424 // String types. 425 SYMBOL_TYPE = kSymbolTag | kSeqStringTag, 426 ASCII_SYMBOL_TYPE = kAsciiStringTag | kSymbolTag | kSeqStringTag, 427 CONS_SYMBOL_TYPE = kSymbolTag | kConsStringTag, 428 CONS_ASCII_SYMBOL_TYPE = kAsciiStringTag | kSymbolTag | kConsStringTag, 429 EXTERNAL_SYMBOL_TYPE = kSymbolTag | kExternalStringTag, 430 EXTERNAL_ASCII_SYMBOL_TYPE = 431 kAsciiStringTag | kSymbolTag | kExternalStringTag, 432 STRING_TYPE = kSeqStringTag, 433 ASCII_STRING_TYPE = kAsciiStringTag | kSeqStringTag, 434 CONS_STRING_TYPE = kConsStringTag, 435 CONS_ASCII_STRING_TYPE = kAsciiStringTag | kConsStringTag, 436 EXTERNAL_STRING_TYPE = kExternalStringTag, 437 EXTERNAL_ASCII_STRING_TYPE = kAsciiStringTag | kExternalStringTag, 438 PRIVATE_EXTERNAL_ASCII_STRING_TYPE = EXTERNAL_ASCII_STRING_TYPE, 439 440 // Objects allocated in their own spaces (never in new space). 441 MAP_TYPE = kNotStringTag, // FIRST_NONSTRING_TYPE 442 CODE_TYPE, 443 ODDBALL_TYPE, 444 JS_GLOBAL_PROPERTY_CELL_TYPE, 445 446 // "Data", objects that cannot contain non-map-word pointers to heap 447 // objects. 448 HEAP_NUMBER_TYPE, 449 PROXY_TYPE, 450 BYTE_ARRAY_TYPE, 451 PIXEL_ARRAY_TYPE, 452 EXTERNAL_BYTE_ARRAY_TYPE, // FIRST_EXTERNAL_ARRAY_TYPE 453 EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE, 454 EXTERNAL_SHORT_ARRAY_TYPE, 455 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE, 456 EXTERNAL_INT_ARRAY_TYPE, 457 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE, 458 EXTERNAL_FLOAT_ARRAY_TYPE, // LAST_EXTERNAL_ARRAY_TYPE 459 FILLER_TYPE, // LAST_DATA_TYPE 460 461 // Structs. 462 ACCESSOR_INFO_TYPE, 463 ACCESS_CHECK_INFO_TYPE, 464 INTERCEPTOR_INFO_TYPE, 465 CALL_HANDLER_INFO_TYPE, 466 FUNCTION_TEMPLATE_INFO_TYPE, 467 OBJECT_TEMPLATE_INFO_TYPE, 468 SIGNATURE_INFO_TYPE, 469 TYPE_SWITCH_INFO_TYPE, 470 SCRIPT_TYPE, 471 #ifdef ENABLE_DEBUGGER_SUPPORT 472 DEBUG_INFO_TYPE, 473 BREAK_POINT_INFO_TYPE, 474 #endif 475 476 FIXED_ARRAY_TYPE, 477 SHARED_FUNCTION_INFO_TYPE, 478 479 JS_VALUE_TYPE, // FIRST_JS_OBJECT_TYPE 480 JS_OBJECT_TYPE, 481 JS_CONTEXT_EXTENSION_OBJECT_TYPE, 482 JS_GLOBAL_OBJECT_TYPE, 483 JS_BUILTINS_OBJECT_TYPE, 484 JS_GLOBAL_PROXY_TYPE, 485 JS_ARRAY_TYPE, 486 JS_REGEXP_TYPE, // LAST_JS_OBJECT_TYPE 487 488 JS_FUNCTION_TYPE, 489 490 // Pseudo-types 491 FIRST_TYPE = 0x0, 492 LAST_TYPE = JS_FUNCTION_TYPE, 493 INVALID_TYPE = FIRST_TYPE - 1, 494 FIRST_NONSTRING_TYPE = MAP_TYPE, 495 // Boundaries for testing for an external array. 496 FIRST_EXTERNAL_ARRAY_TYPE = EXTERNAL_BYTE_ARRAY_TYPE, 497 LAST_EXTERNAL_ARRAY_TYPE = EXTERNAL_FLOAT_ARRAY_TYPE, 498 // Boundary for promotion to old data space/old pointer space. 499 LAST_DATA_TYPE = FILLER_TYPE, 500 // Boundaries for testing the type is a JavaScript "object". Note that 501 // function objects are not counted as objects, even though they are 502 // implemented as such; only values whose typeof is "object" are included. 503 FIRST_JS_OBJECT_TYPE = JS_VALUE_TYPE, 504 LAST_JS_OBJECT_TYPE = JS_REGEXP_TYPE 505 }; 506 507 508 enum CompareResult { 509 LESS = -1, 510 EQUAL = 0, 511 GREATER = 1, 512 513 NOT_EQUAL = GREATER 514 }; 515 516 517 #define DECL_BOOLEAN_ACCESSORS(name) \ 518 inline bool name(); \ 519 inline void set_##name(bool value); \ 520 521 522 #define DECL_ACCESSORS(name, type) \ 523 inline type* name(); \ 524 inline void set_##name(type* value, \ 525 WriteBarrierMode mode = UPDATE_WRITE_BARRIER); \ 526 527 528 class StringStream; 529 class ObjectVisitor; 530 531 struct ValueInfo : public Malloced { ValueInfoValueInfo532 ValueInfo() : type(FIRST_TYPE), ptr(NULL), str(NULL), number(0) { } 533 InstanceType type; 534 Object* ptr; 535 const char* str; 536 double number; 537 }; 538 539 540 // A template-ized version of the IsXXX functions. 541 template <class C> static inline bool Is(Object* obj); 542 543 544 // Object is the abstract superclass for all classes in the 545 // object hierarchy. 546 // Object does not use any virtual functions to avoid the 547 // allocation of the C++ vtable. 548 // Since Smi and Failure are subclasses of Object no 549 // data members can be present in Object. 550 class Object BASE_EMBEDDED { 551 public: 552 // Type testing. 553 inline bool IsSmi(); 554 inline bool IsHeapObject(); 555 inline bool IsHeapNumber(); 556 inline bool IsString(); 557 inline bool IsSymbol(); 558 // See objects-inl.h for more details 559 inline bool IsSeqString(); 560 inline bool IsExternalString(); 561 inline bool IsExternalTwoByteString(); 562 inline bool IsExternalAsciiString(); 563 inline bool IsSeqTwoByteString(); 564 inline bool IsSeqAsciiString(); 565 inline bool IsConsString(); 566 567 inline bool IsNumber(); 568 inline bool IsByteArray(); 569 inline bool IsPixelArray(); 570 inline bool IsExternalArray(); 571 inline bool IsExternalByteArray(); 572 inline bool IsExternalUnsignedByteArray(); 573 inline bool IsExternalShortArray(); 574 inline bool IsExternalUnsignedShortArray(); 575 inline bool IsExternalIntArray(); 576 inline bool IsExternalUnsignedIntArray(); 577 inline bool IsExternalFloatArray(); 578 inline bool IsFailure(); 579 inline bool IsRetryAfterGC(); 580 inline bool IsOutOfMemoryFailure(); 581 inline bool IsException(); 582 inline bool IsJSObject(); 583 inline bool IsJSContextExtensionObject(); 584 inline bool IsMap(); 585 inline bool IsFixedArray(); 586 inline bool IsDescriptorArray(); 587 inline bool IsContext(); 588 inline bool IsCatchContext(); 589 inline bool IsGlobalContext(); 590 inline bool IsJSFunction(); 591 inline bool IsCode(); 592 inline bool IsOddball(); 593 inline bool IsSharedFunctionInfo(); 594 inline bool IsJSValue(); 595 inline bool IsStringWrapper(); 596 inline bool IsProxy(); 597 inline bool IsBoolean(); 598 inline bool IsJSArray(); 599 inline bool IsJSRegExp(); 600 inline bool IsHashTable(); 601 inline bool IsDictionary(); 602 inline bool IsSymbolTable(); 603 inline bool IsCompilationCacheTable(); 604 inline bool IsMapCache(); 605 inline bool IsPrimitive(); 606 inline bool IsGlobalObject(); 607 inline bool IsJSGlobalObject(); 608 inline bool IsJSBuiltinsObject(); 609 inline bool IsJSGlobalProxy(); 610 inline bool IsUndetectableObject(); 611 inline bool IsAccessCheckNeeded(); 612 inline bool IsJSGlobalPropertyCell(); 613 614 // Returns true if this object is an instance of the specified 615 // function template. 616 inline bool IsInstanceOf(FunctionTemplateInfo* type); 617 618 inline bool IsStruct(); 619 #define DECLARE_STRUCT_PREDICATE(NAME, Name, name) inline bool Is##Name(); 620 STRUCT_LIST(DECLARE_STRUCT_PREDICATE) 621 #undef DECLARE_STRUCT_PREDICATE 622 623 // Oddball testing. 624 INLINE(bool IsUndefined()); 625 INLINE(bool IsTheHole()); 626 INLINE(bool IsNull()); 627 INLINE(bool IsTrue()); 628 INLINE(bool IsFalse()); 629 630 // Extract the number. 631 inline double Number(); 632 633 inline bool HasSpecificClassOf(String* name); 634 635 Object* ToObject(); // ECMA-262 9.9. 636 Object* ToBoolean(); // ECMA-262 9.2. 637 638 // Convert to a JSObject if needed. 639 // global_context is used when creating wrapper object. 640 Object* ToObject(Context* global_context); 641 642 // Converts this to a Smi if possible. 643 // Failure is returned otherwise. 644 inline Object* ToSmi(); 645 646 void Lookup(String* name, LookupResult* result); 647 648 // Property access. 649 inline Object* GetProperty(String* key); 650 inline Object* GetProperty(String* key, PropertyAttributes* attributes); 651 Object* GetPropertyWithReceiver(Object* receiver, 652 String* key, 653 PropertyAttributes* attributes); 654 Object* GetProperty(Object* receiver, 655 LookupResult* result, 656 String* key, 657 PropertyAttributes* attributes); 658 Object* GetPropertyWithCallback(Object* receiver, 659 Object* structure, 660 String* name, 661 Object* holder); 662 Object* GetPropertyWithDefinedGetter(Object* receiver, 663 JSFunction* getter); 664 665 inline Object* GetElement(uint32_t index); 666 Object* GetElementWithReceiver(Object* receiver, uint32_t index); 667 668 // Return the object's prototype (might be Heap::null_value()). 669 Object* GetPrototype(); 670 671 // Returns true if this is a JSValue containing a string and the index is 672 // < the length of the string. Used to implement [] on strings. 673 inline bool IsStringObjectWithCharacterAt(uint32_t index); 674 675 #ifdef DEBUG 676 // Prints this object with details. 677 void Print(); 678 void PrintLn(); 679 // Verifies the object. 680 void Verify(); 681 682 // Verify a pointer is a valid object pointer. 683 static void VerifyPointer(Object* p); 684 #endif 685 686 // Prints this object without details. 687 void ShortPrint(); 688 689 // Prints this object without details to a message accumulator. 690 void ShortPrint(StringStream* accumulator); 691 692 // Casting: This cast is only needed to satisfy macros in objects-inl.h. cast(Object * value)693 static Object* cast(Object* value) { return value; } 694 695 // Layout description. 696 static const int kHeaderSize = 0; // Object does not take up any space. 697 698 private: 699 DISALLOW_IMPLICIT_CONSTRUCTORS(Object); 700 }; 701 702 703 // Smi represents integer Numbers that can be stored in 31 bits. 704 // Smis are immediate which means they are NOT allocated in the heap. 705 // The this pointer has the following format: [31 bit signed int] 0 706 // For long smis it has the following format: 707 // [32 bit signed int] [31 bits zero padding] 0 708 // Smi stands for small integer. 709 class Smi: public Object { 710 public: 711 // Returns the integer value. 712 inline int value(); 713 714 // Convert a value to a Smi object. 715 static inline Smi* FromInt(int value); 716 717 static inline Smi* FromIntptr(intptr_t value); 718 719 // Returns whether value can be represented in a Smi. 720 static inline bool IsValid(intptr_t value); 721 722 // Casting. 723 static inline Smi* cast(Object* object); 724 725 // Dispatched behavior. 726 void SmiPrint(); 727 void SmiPrint(StringStream* accumulator); 728 #ifdef DEBUG 729 void SmiVerify(); 730 #endif 731 732 static const int kMinValue = (-1 << (kSmiValueSize - 1)); 733 static const int kMaxValue = -(kMinValue + 1); 734 735 private: 736 DISALLOW_IMPLICIT_CONSTRUCTORS(Smi); 737 }; 738 739 740 // Failure is used for reporting out of memory situations and 741 // propagating exceptions through the runtime system. Failure objects 742 // are transient and cannot occur as part of the object graph. 743 // 744 // Failures are a single word, encoded as follows: 745 // +-------------------------+---+--+--+ 746 // |...rrrrrrrrrrrrrrrrrrrrrr|sss|tt|11| 747 // +-------------------------+---+--+--+ 748 // 7 6 4 32 10 749 // 750 // 751 // The low two bits, 0-1, are the failure tag, 11. The next two bits, 752 // 2-3, are a failure type tag 'tt' with possible values: 753 // 00 RETRY_AFTER_GC 754 // 01 EXCEPTION 755 // 10 INTERNAL_ERROR 756 // 11 OUT_OF_MEMORY_EXCEPTION 757 // 758 // The next three bits, 4-6, are an allocation space tag 'sss'. The 759 // allocation space tag is 000 for all failure types except 760 // RETRY_AFTER_GC. For RETRY_AFTER_GC, the possible values are the 761 // allocation spaces (the encoding is found in globals.h). 762 // 763 // The remaining bits is the size of the allocation request in units 764 // of the pointer size, and is zeroed except for RETRY_AFTER_GC 765 // failures. The 25 bits (on a 32 bit platform) gives a representable 766 // range of 2^27 bytes (128MB). 767 768 // Failure type tag info. 769 const int kFailureTypeTagSize = 2; 770 const int kFailureTypeTagMask = (1 << kFailureTypeTagSize) - 1; 771 772 class Failure: public Object { 773 public: 774 // RuntimeStubs assumes EXCEPTION = 1 in the compiler-generated code. 775 enum Type { 776 RETRY_AFTER_GC = 0, 777 EXCEPTION = 1, // Returning this marker tells the real exception 778 // is in Top::pending_exception. 779 INTERNAL_ERROR = 2, 780 OUT_OF_MEMORY_EXCEPTION = 3 781 }; 782 783 inline Type type() const; 784 785 // Returns the space that needs to be collected for RetryAfterGC failures. 786 inline AllocationSpace allocation_space() const; 787 788 // Returns the number of bytes requested (up to the representable maximum) 789 // for RetryAfterGC failures. 790 inline int requested() const; 791 792 inline bool IsInternalError() const; 793 inline bool IsOutOfMemoryException() const; 794 795 static Failure* RetryAfterGC(int requested_bytes, AllocationSpace space); 796 static inline Failure* RetryAfterGC(int requested_bytes); // NEW_SPACE 797 static inline Failure* Exception(); 798 static inline Failure* InternalError(); 799 static inline Failure* OutOfMemoryException(); 800 // Casting. 801 static inline Failure* cast(Object* object); 802 803 // Dispatched behavior. 804 void FailurePrint(); 805 void FailurePrint(StringStream* accumulator); 806 #ifdef DEBUG 807 void FailureVerify(); 808 #endif 809 810 private: 811 inline intptr_t value() const; 812 static inline Failure* Construct(Type type, intptr_t value = 0); 813 814 DISALLOW_IMPLICIT_CONSTRUCTORS(Failure); 815 }; 816 817 818 // Heap objects typically have a map pointer in their first word. However, 819 // during GC other data (eg, mark bits, forwarding addresses) is sometimes 820 // encoded in the first word. The class MapWord is an abstraction of the 821 // value in a heap object's first word. 822 class MapWord BASE_EMBEDDED { 823 public: 824 // Normal state: the map word contains a map pointer. 825 826 // Create a map word from a map pointer. 827 static inline MapWord FromMap(Map* map); 828 829 // View this map word as a map pointer. 830 inline Map* ToMap(); 831 832 833 // Scavenge collection: the map word of live objects in the from space 834 // contains a forwarding address (a heap object pointer in the to space). 835 836 // True if this map word is a forwarding address for a scavenge 837 // collection. Only valid during a scavenge collection (specifically, 838 // when all map words are heap object pointers, ie. not during a full GC). 839 inline bool IsForwardingAddress(); 840 841 // Create a map word from a forwarding address. 842 static inline MapWord FromForwardingAddress(HeapObject* object); 843 844 // View this map word as a forwarding address. 845 inline HeapObject* ToForwardingAddress(); 846 847 // Marking phase of full collection: the map word of live objects is 848 // marked, and may be marked as overflowed (eg, the object is live, its 849 // children have not been visited, and it does not fit in the marking 850 // stack). 851 852 // True if this map word's mark bit is set. 853 inline bool IsMarked(); 854 855 // Return this map word but with its mark bit set. 856 inline void SetMark(); 857 858 // Return this map word but with its mark bit cleared. 859 inline void ClearMark(); 860 861 // True if this map word's overflow bit is set. 862 inline bool IsOverflowed(); 863 864 // Return this map word but with its overflow bit set. 865 inline void SetOverflow(); 866 867 // Return this map word but with its overflow bit cleared. 868 inline void ClearOverflow(); 869 870 871 // Compacting phase of a full compacting collection: the map word of live 872 // objects contains an encoding of the original map address along with the 873 // forwarding address (represented as an offset from the first live object 874 // in the same page as the (old) object address). 875 876 // Create a map word from a map address and a forwarding address offset. 877 static inline MapWord EncodeAddress(Address map_address, int offset); 878 879 // Return the map address encoded in this map word. 880 inline Address DecodeMapAddress(MapSpace* map_space); 881 882 // Return the forwarding offset encoded in this map word. 883 inline int DecodeOffset(); 884 885 886 // During serialization: the map word is used to hold an encoded 887 // address, and possibly a mark bit (set and cleared with SetMark 888 // and ClearMark). 889 890 // Create a map word from an encoded address. 891 static inline MapWord FromEncodedAddress(Address address); 892 893 inline Address ToEncodedAddress(); 894 895 // Bits used by the marking phase of the garbage collector. 896 // 897 // The first word of a heap object is normally a map pointer. The last two 898 // bits are tagged as '01' (kHeapObjectTag). We reuse the last two bits to 899 // mark an object as live and/or overflowed: 900 // last bit = 0, marked as alive 901 // second bit = 1, overflowed 902 // An object is only marked as overflowed when it is marked as live while 903 // the marking stack is overflowed. 904 static const int kMarkingBit = 0; // marking bit 905 static const int kMarkingMask = (1 << kMarkingBit); // marking mask 906 static const int kOverflowBit = 1; // overflow bit 907 static const int kOverflowMask = (1 << kOverflowBit); // overflow mask 908 909 // Forwarding pointers and map pointer encoding. On 32 bit all the bits are 910 // used. 911 // +-----------------+------------------+-----------------+ 912 // |forwarding offset|page offset of map|page index of map| 913 // +-----------------+------------------+-----------------+ 914 // ^ ^ ^ 915 // | | | 916 // | | kMapPageIndexBits 917 // | kMapPageOffsetBits 918 // kForwardingOffsetBits 919 static const int kMapPageOffsetBits = kPageSizeBits - kMapAlignmentBits; 920 static const int kForwardingOffsetBits = kPageSizeBits - kObjectAlignmentBits; 921 #ifdef V8_HOST_ARCH_64_BIT 922 static const int kMapPageIndexBits = 16; 923 #else 924 // Use all the 32-bits to encode on a 32-bit platform. 925 static const int kMapPageIndexBits = 926 32 - (kMapPageOffsetBits + kForwardingOffsetBits); 927 #endif 928 929 static const int kMapPageIndexShift = 0; 930 static const int kMapPageOffsetShift = 931 kMapPageIndexShift + kMapPageIndexBits; 932 static const int kForwardingOffsetShift = 933 kMapPageOffsetShift + kMapPageOffsetBits; 934 935 // Bit masks covering the different parts the encoding. 936 static const uintptr_t kMapPageIndexMask = 937 (1 << kMapPageOffsetShift) - 1; 938 static const uintptr_t kMapPageOffsetMask = 939 ((1 << kForwardingOffsetShift) - 1) & ~kMapPageIndexMask; 940 static const uintptr_t kForwardingOffsetMask = 941 ~(kMapPageIndexMask | kMapPageOffsetMask); 942 943 private: 944 // HeapObject calls the private constructor and directly reads the value. 945 friend class HeapObject; 946 MapWord(uintptr_t value)947 explicit MapWord(uintptr_t value) : value_(value) {} 948 949 uintptr_t value_; 950 }; 951 952 953 // HeapObject is the superclass for all classes describing heap allocated 954 // objects. 955 class HeapObject: public Object { 956 public: 957 // [map]: Contains a map which contains the object's reflective 958 // information. 959 inline Map* map(); 960 inline void set_map(Map* value); 961 962 // During garbage collection, the map word of a heap object does not 963 // necessarily contain a map pointer. 964 inline MapWord map_word(); 965 inline void set_map_word(MapWord map_word); 966 967 // Converts an address to a HeapObject pointer. 968 static inline HeapObject* FromAddress(Address address); 969 970 // Returns the address of this HeapObject. 971 inline Address address(); 972 973 // Iterates over pointers contained in the object (including the Map) 974 void Iterate(ObjectVisitor* v); 975 976 // Iterates over all pointers contained in the object except the 977 // first map pointer. The object type is given in the first 978 // parameter. This function does not access the map pointer in the 979 // object, and so is safe to call while the map pointer is modified. 980 void IterateBody(InstanceType type, int object_size, ObjectVisitor* v); 981 982 // This method only applies to struct objects. Iterates over all the fields 983 // of this struct. 984 void IterateStructBody(int object_size, ObjectVisitor* v); 985 986 // Returns the heap object's size in bytes 987 inline int Size(); 988 989 // Given a heap object's map pointer, returns the heap size in bytes 990 // Useful when the map pointer field is used for other purposes. 991 // GC internal. 992 inline int SizeFromMap(Map* map); 993 994 // Support for the marking heap objects during the marking phase of GC. 995 // True if the object is marked live. 996 inline bool IsMarked(); 997 998 // Mutate this object's map pointer to indicate that the object is live. 999 inline void SetMark(); 1000 1001 // Mutate this object's map pointer to remove the indication that the 1002 // object is live (ie, partially restore the map pointer). 1003 inline void ClearMark(); 1004 1005 // True if this object is marked as overflowed. Overflowed objects have 1006 // been reached and marked during marking of the heap, but their children 1007 // have not necessarily been marked and they have not been pushed on the 1008 // marking stack. 1009 inline bool IsOverflowed(); 1010 1011 // Mutate this object's map pointer to indicate that the object is 1012 // overflowed. 1013 inline void SetOverflow(); 1014 1015 // Mutate this object's map pointer to remove the indication that the 1016 // object is overflowed (ie, partially restore the map pointer). 1017 inline void ClearOverflow(); 1018 1019 // Returns the field at offset in obj, as a read/write Object* reference. 1020 // Does no checking, and is safe to use during GC, while maps are invalid. 1021 // Does not update remembered sets, so should only be assigned to 1022 // during marking GC. 1023 static inline Object** RawField(HeapObject* obj, int offset); 1024 1025 // Casting. 1026 static inline HeapObject* cast(Object* obj); 1027 1028 // Return the write barrier mode for this. Callers of this function 1029 // must be able to present a reference to an AssertNoAllocation 1030 // object as a sign that they are not going to use this function 1031 // from code that allocates and thus invalidates the returned write 1032 // barrier mode. 1033 inline WriteBarrierMode GetWriteBarrierMode(const AssertNoAllocation&); 1034 1035 // Dispatched behavior. 1036 void HeapObjectShortPrint(StringStream* accumulator); 1037 #ifdef DEBUG 1038 void HeapObjectPrint(); 1039 void HeapObjectVerify(); 1040 inline void VerifyObjectField(int offset); 1041 1042 void PrintHeader(const char* id); 1043 1044 // Verify a pointer is a valid HeapObject pointer that points to object 1045 // areas in the heap. 1046 static void VerifyHeapPointer(Object* p); 1047 #endif 1048 1049 // Layout description. 1050 // First field in a heap object is map. 1051 static const int kMapOffset = Object::kHeaderSize; 1052 static const int kHeaderSize = kMapOffset + kPointerSize; 1053 1054 STATIC_CHECK(kMapOffset == Internals::kHeapObjectMapOffset); 1055 1056 protected: 1057 // helpers for calling an ObjectVisitor to iterate over pointers in the 1058 // half-open range [start, end) specified as integer offsets 1059 inline void IteratePointers(ObjectVisitor* v, int start, int end); 1060 // as above, for the single element at "offset" 1061 inline void IteratePointer(ObjectVisitor* v, int offset); 1062 1063 // Computes the object size from the map. 1064 // Should only be used from SizeFromMap. 1065 int SlowSizeFromMap(Map* map); 1066 1067 private: 1068 DISALLOW_IMPLICIT_CONSTRUCTORS(HeapObject); 1069 }; 1070 1071 1072 // The HeapNumber class describes heap allocated numbers that cannot be 1073 // represented in a Smi (small integer) 1074 class HeapNumber: public HeapObject { 1075 public: 1076 // [value]: number value. 1077 inline double value(); 1078 inline void set_value(double value); 1079 1080 // Casting. 1081 static inline HeapNumber* cast(Object* obj); 1082 1083 // Dispatched behavior. 1084 Object* HeapNumberToBoolean(); 1085 void HeapNumberPrint(); 1086 void HeapNumberPrint(StringStream* accumulator); 1087 #ifdef DEBUG 1088 void HeapNumberVerify(); 1089 #endif 1090 1091 // Layout description. 1092 static const int kValueOffset = HeapObject::kHeaderSize; 1093 // IEEE doubles are two 32 bit words. The first is just mantissa, the second 1094 // is a mixture of sign, exponent and mantissa. Our current platforms are all 1095 // little endian apart from non-EABI arm which is little endian with big 1096 // endian floating point word ordering! 1097 #if !defined(V8_HOST_ARCH_ARM) || defined(USE_ARM_EABI) 1098 static const int kMantissaOffset = kValueOffset; 1099 static const int kExponentOffset = kValueOffset + 4; 1100 #else 1101 static const int kMantissaOffset = kValueOffset + 4; 1102 static const int kExponentOffset = kValueOffset; 1103 # define BIG_ENDIAN_FLOATING_POINT 1 1104 #endif 1105 static const int kSize = kValueOffset + kDoubleSize; 1106 static const uint32_t kSignMask = 0x80000000u; 1107 static const uint32_t kExponentMask = 0x7ff00000u; 1108 static const uint32_t kMantissaMask = 0xfffffu; 1109 static const int kExponentBias = 1023; 1110 static const int kExponentShift = 20; 1111 static const int kMantissaBitsInTopWord = 20; 1112 static const int kNonMantissaBitsInTopWord = 12; 1113 1114 private: 1115 DISALLOW_IMPLICIT_CONSTRUCTORS(HeapNumber); 1116 }; 1117 1118 1119 // The JSObject describes real heap allocated JavaScript objects with 1120 // properties. 1121 // Note that the map of JSObject changes during execution to enable inline 1122 // caching. 1123 class JSObject: public HeapObject { 1124 public: 1125 enum DeleteMode { NORMAL_DELETION, FORCE_DELETION }; 1126 enum ElementsKind { 1127 FAST_ELEMENTS, 1128 DICTIONARY_ELEMENTS, 1129 PIXEL_ELEMENTS, 1130 EXTERNAL_BYTE_ELEMENTS, 1131 EXTERNAL_UNSIGNED_BYTE_ELEMENTS, 1132 EXTERNAL_SHORT_ELEMENTS, 1133 EXTERNAL_UNSIGNED_SHORT_ELEMENTS, 1134 EXTERNAL_INT_ELEMENTS, 1135 EXTERNAL_UNSIGNED_INT_ELEMENTS, 1136 EXTERNAL_FLOAT_ELEMENTS 1137 }; 1138 1139 // [properties]: Backing storage for properties. 1140 // properties is a FixedArray in the fast case, and a Dictionary in the 1141 // slow case. 1142 DECL_ACCESSORS(properties, FixedArray) // Get and set fast properties. 1143 inline void initialize_properties(); 1144 inline bool HasFastProperties(); 1145 inline StringDictionary* property_dictionary(); // Gets slow properties. 1146 1147 // [elements]: The elements (properties with names that are integers). 1148 // elements is a FixedArray in the fast case, and a Dictionary in the slow 1149 // case or a PixelArray in a special case. 1150 DECL_ACCESSORS(elements, Array) // Get and set fast elements. 1151 inline void initialize_elements(); 1152 inline ElementsKind GetElementsKind(); 1153 inline bool HasFastElements(); 1154 inline bool HasDictionaryElements(); 1155 inline bool HasPixelElements(); 1156 inline bool HasExternalArrayElements(); 1157 inline bool HasExternalByteElements(); 1158 inline bool HasExternalUnsignedByteElements(); 1159 inline bool HasExternalShortElements(); 1160 inline bool HasExternalUnsignedShortElements(); 1161 inline bool HasExternalIntElements(); 1162 inline bool HasExternalUnsignedIntElements(); 1163 inline bool HasExternalFloatElements(); 1164 inline NumberDictionary* element_dictionary(); // Gets slow elements. 1165 1166 // Collects elements starting at index 0. 1167 // Undefined values are placed after non-undefined values. 1168 // Returns the number of non-undefined values. 1169 Object* PrepareElementsForSort(uint32_t limit); 1170 // As PrepareElementsForSort, but only on objects where elements is 1171 // a dictionary, and it will stay a dictionary. 1172 Object* PrepareSlowElementsForSort(uint32_t limit); 1173 1174 Object* SetProperty(String* key, 1175 Object* value, 1176 PropertyAttributes attributes); 1177 Object* SetProperty(LookupResult* result, 1178 String* key, 1179 Object* value, 1180 PropertyAttributes attributes); 1181 Object* SetPropertyWithFailedAccessCheck(LookupResult* result, 1182 String* name, 1183 Object* value); 1184 Object* SetPropertyWithCallback(Object* structure, 1185 String* name, 1186 Object* value, 1187 JSObject* holder); 1188 Object* SetPropertyWithDefinedSetter(JSFunction* setter, 1189 Object* value); 1190 Object* SetPropertyWithInterceptor(String* name, 1191 Object* value, 1192 PropertyAttributes attributes); 1193 Object* SetPropertyPostInterceptor(String* name, 1194 Object* value, 1195 PropertyAttributes attributes); 1196 Object* IgnoreAttributesAndSetLocalProperty(String* key, 1197 Object* value, 1198 PropertyAttributes attributes); 1199 1200 // Retrieve a value in a normalized object given a lookup result. 1201 // Handles the special representation of JS global objects. 1202 Object* GetNormalizedProperty(LookupResult* result); 1203 1204 // Sets the property value in a normalized object given a lookup result. 1205 // Handles the special representation of JS global objects. 1206 Object* SetNormalizedProperty(LookupResult* result, Object* value); 1207 1208 // Sets the property value in a normalized object given (key, value, details). 1209 // Handles the special representation of JS global objects. 1210 Object* SetNormalizedProperty(String* name, 1211 Object* value, 1212 PropertyDetails details); 1213 1214 // Deletes the named property in a normalized object. 1215 Object* DeleteNormalizedProperty(String* name, DeleteMode mode); 1216 1217 // Returns the class name ([[Class]] property in the specification). 1218 String* class_name(); 1219 1220 // Returns the constructor name (the name (possibly, inferred name) of the 1221 // function that was used to instantiate the object). 1222 String* constructor_name(); 1223 1224 // Retrieve interceptors. 1225 InterceptorInfo* GetNamedInterceptor(); 1226 InterceptorInfo* GetIndexedInterceptor(); 1227 1228 inline PropertyAttributes GetPropertyAttribute(String* name); 1229 PropertyAttributes GetPropertyAttributeWithReceiver(JSObject* receiver, 1230 String* name); 1231 PropertyAttributes GetLocalPropertyAttribute(String* name); 1232 1233 Object* DefineAccessor(String* name, bool is_getter, JSFunction* fun, 1234 PropertyAttributes attributes); 1235 Object* LookupAccessor(String* name, bool is_getter); 1236 1237 // Used from Object::GetProperty(). 1238 Object* GetPropertyWithFailedAccessCheck(Object* receiver, 1239 LookupResult* result, 1240 String* name, 1241 PropertyAttributes* attributes); 1242 Object* GetPropertyWithInterceptor(JSObject* receiver, 1243 String* name, 1244 PropertyAttributes* attributes); 1245 Object* GetPropertyPostInterceptor(JSObject* receiver, 1246 String* name, 1247 PropertyAttributes* attributes); 1248 Object* GetLocalPropertyPostInterceptor(JSObject* receiver, 1249 String* name, 1250 PropertyAttributes* attributes); 1251 1252 // Returns true if this is an instance of an api function and has 1253 // been modified since it was created. May give false positives. 1254 bool IsDirty(); 1255 HasProperty(String * name)1256 bool HasProperty(String* name) { 1257 return GetPropertyAttribute(name) != ABSENT; 1258 } 1259 1260 // Can cause a GC if it hits an interceptor. HasLocalProperty(String * name)1261 bool HasLocalProperty(String* name) { 1262 return GetLocalPropertyAttribute(name) != ABSENT; 1263 } 1264 1265 // If the receiver is a JSGlobalProxy this method will return its prototype, 1266 // otherwise the result is the receiver itself. 1267 inline Object* BypassGlobalProxy(); 1268 1269 // Accessors for hidden properties object. 1270 // 1271 // Hidden properties are not local properties of the object itself. 1272 // Instead they are stored on an auxiliary JSObject stored as a local 1273 // property with a special name Heap::hidden_symbol(). But if the 1274 // receiver is a JSGlobalProxy then the auxiliary object is a property 1275 // of its prototype. 1276 // 1277 // Has/Get/SetHiddenPropertiesObject methods don't allow the holder to be 1278 // a JSGlobalProxy. Use BypassGlobalProxy method above to get to the real 1279 // holder. 1280 // 1281 // These accessors do not touch interceptors or accessors. 1282 inline bool HasHiddenPropertiesObject(); 1283 inline Object* GetHiddenPropertiesObject(); 1284 inline Object* SetHiddenPropertiesObject(Object* hidden_obj); 1285 1286 Object* DeleteProperty(String* name, DeleteMode mode); 1287 Object* DeleteElement(uint32_t index, DeleteMode mode); 1288 1289 // Tests for the fast common case for property enumeration. 1290 bool IsSimpleEnum(); 1291 1292 // Do we want to keep the elements in fast case when increasing the 1293 // capacity? 1294 bool ShouldConvertToSlowElements(int new_capacity); 1295 // Returns true if the backing storage for the slow-case elements of 1296 // this object takes up nearly as much space as a fast-case backing 1297 // storage would. In that case the JSObject should have fast 1298 // elements. 1299 bool ShouldConvertToFastElements(); 1300 1301 // Return the object's prototype (might be Heap::null_value()). 1302 inline Object* GetPrototype(); 1303 1304 // Set the object's prototype (only JSObject and null are allowed). 1305 Object* SetPrototype(Object* value, bool skip_hidden_prototypes); 1306 1307 // Tells whether the index'th element is present. 1308 inline bool HasElement(uint32_t index); 1309 bool HasElementWithReceiver(JSObject* receiver, uint32_t index); 1310 bool HasLocalElement(uint32_t index); 1311 1312 bool HasElementWithInterceptor(JSObject* receiver, uint32_t index); 1313 bool HasElementPostInterceptor(JSObject* receiver, uint32_t index); 1314 1315 Object* SetFastElement(uint32_t index, Object* value); 1316 1317 // Set the index'th array element. 1318 // A Failure object is returned if GC is needed. 1319 Object* SetElement(uint32_t index, Object* value); 1320 1321 // Returns the index'th element. 1322 // The undefined object if index is out of bounds. 1323 Object* GetElementWithReceiver(JSObject* receiver, uint32_t index); 1324 1325 void SetFastElements(FixedArray* elements); 1326 Object* SetSlowElements(Object* length); 1327 1328 // Lookup interceptors are used for handling properties controlled by host 1329 // objects. 1330 inline bool HasNamedInterceptor(); 1331 inline bool HasIndexedInterceptor(); 1332 1333 // Support functions for v8 api (needed for correct interceptor behavior). 1334 bool HasRealNamedProperty(String* key); 1335 bool HasRealElementProperty(uint32_t index); 1336 bool HasRealNamedCallbackProperty(String* key); 1337 1338 // Initializes the array to a certain length 1339 Object* SetElementsLength(Object* length); 1340 1341 // Get the header size for a JSObject. Used to compute the index of 1342 // internal fields as well as the number of internal fields. 1343 inline int GetHeaderSize(); 1344 1345 inline int GetInternalFieldCount(); 1346 inline Object* GetInternalField(int index); 1347 inline void SetInternalField(int index, Object* value); 1348 1349 // Lookup a property. If found, the result is valid and has 1350 // detailed information. 1351 void LocalLookup(String* name, LookupResult* result); 1352 void Lookup(String* name, LookupResult* result); 1353 1354 // The following lookup functions skip interceptors. 1355 void LocalLookupRealNamedProperty(String* name, LookupResult* result); 1356 void LookupRealNamedProperty(String* name, LookupResult* result); 1357 void LookupRealNamedPropertyInPrototypes(String* name, LookupResult* result); 1358 void LookupCallbackSetterInPrototypes(String* name, LookupResult* result); 1359 Object* LookupCallbackSetterInPrototypes(uint32_t index); 1360 void LookupCallback(String* name, LookupResult* result); 1361 1362 // Returns the number of properties on this object filtering out properties 1363 // with the specified attributes (ignoring interceptors). 1364 int NumberOfLocalProperties(PropertyAttributes filter); 1365 // Returns the number of enumerable properties (ignoring interceptors). 1366 int NumberOfEnumProperties(); 1367 // Fill in details for properties into storage starting at the specified 1368 // index. 1369 void GetLocalPropertyNames(FixedArray* storage, int index); 1370 1371 // Returns the number of properties on this object filtering out properties 1372 // with the specified attributes (ignoring interceptors). 1373 int NumberOfLocalElements(PropertyAttributes filter); 1374 // Returns the number of enumerable elements (ignoring interceptors). 1375 int NumberOfEnumElements(); 1376 // Returns the number of elements on this object filtering out elements 1377 // with the specified attributes (ignoring interceptors). 1378 int GetLocalElementKeys(FixedArray* storage, PropertyAttributes filter); 1379 // Count and fill in the enumerable elements into storage. 1380 // (storage->length() == NumberOfEnumElements()). 1381 // If storage is NULL, will count the elements without adding 1382 // them to any storage. 1383 // Returns the number of enumerable elements. 1384 int GetEnumElementKeys(FixedArray* storage); 1385 1386 // Add a property to a fast-case object using a map transition to 1387 // new_map. 1388 Object* AddFastPropertyUsingMap(Map* new_map, 1389 String* name, 1390 Object* value); 1391 1392 // Add a constant function property to a fast-case object. 1393 // This leaves a CONSTANT_TRANSITION in the old map, and 1394 // if it is called on a second object with this map, a 1395 // normal property is added instead, with a map transition. 1396 // This avoids the creation of many maps with the same constant 1397 // function, all orphaned. 1398 Object* AddConstantFunctionProperty(String* name, 1399 JSFunction* function, 1400 PropertyAttributes attributes); 1401 1402 Object* ReplaceSlowProperty(String* name, 1403 Object* value, 1404 PropertyAttributes attributes); 1405 1406 // Converts a descriptor of any other type to a real field, 1407 // backed by the properties array. Descriptors of visible 1408 // types, such as CONSTANT_FUNCTION, keep their enumeration order. 1409 // Converts the descriptor on the original object's map to a 1410 // map transition, and the the new field is on the object's new map. 1411 Object* ConvertDescriptorToFieldAndMapTransition( 1412 String* name, 1413 Object* new_value, 1414 PropertyAttributes attributes); 1415 1416 // Converts a descriptor of any other type to a real field, 1417 // backed by the properties array. Descriptors of visible 1418 // types, such as CONSTANT_FUNCTION, keep their enumeration order. 1419 Object* ConvertDescriptorToField(String* name, 1420 Object* new_value, 1421 PropertyAttributes attributes); 1422 1423 // Add a property to a fast-case object. 1424 Object* AddFastProperty(String* name, 1425 Object* value, 1426 PropertyAttributes attributes); 1427 1428 // Add a property to a slow-case object. 1429 Object* AddSlowProperty(String* name, 1430 Object* value, 1431 PropertyAttributes attributes); 1432 1433 // Add a property to an object. 1434 Object* AddProperty(String* name, 1435 Object* value, 1436 PropertyAttributes attributes); 1437 1438 // Convert the object to use the canonical dictionary 1439 // representation. If the object is expected to have additional properties 1440 // added this number can be indicated to have the backing store allocated to 1441 // an initial capacity for holding these properties. 1442 Object* NormalizeProperties(PropertyNormalizationMode mode, 1443 int expected_additional_properties); 1444 Object* NormalizeElements(); 1445 1446 // Transform slow named properties to fast variants. 1447 // Returns failure if allocation failed. 1448 Object* TransformToFastProperties(int unused_property_fields); 1449 1450 // Access fast-case object properties at index. 1451 inline Object* FastPropertyAt(int index); 1452 inline Object* FastPropertyAtPut(int index, Object* value); 1453 1454 // Access to in object properties. 1455 inline Object* InObjectPropertyAt(int index); 1456 inline Object* InObjectPropertyAtPut(int index, 1457 Object* value, 1458 WriteBarrierMode mode 1459 = UPDATE_WRITE_BARRIER); 1460 1461 // initializes the body after properties slot, properties slot is 1462 // initialized by set_properties 1463 // Note: this call does not update write barrier, it is caller's 1464 // reponsibility to ensure that *v* can be collected without WB here. 1465 inline void InitializeBody(int object_size); 1466 1467 // Check whether this object references another object 1468 bool ReferencesObject(Object* obj); 1469 1470 // Casting. 1471 static inline JSObject* cast(Object* obj); 1472 1473 // Dispatched behavior. 1474 void JSObjectIterateBody(int object_size, ObjectVisitor* v); 1475 void JSObjectShortPrint(StringStream* accumulator); 1476 #ifdef DEBUG 1477 void JSObjectPrint(); 1478 void JSObjectVerify(); 1479 void PrintProperties(); 1480 void PrintElements(); 1481 1482 // Structure for collecting spill information about JSObjects. 1483 class SpillInformation { 1484 public: 1485 void Clear(); 1486 void Print(); 1487 int number_of_objects_; 1488 int number_of_objects_with_fast_properties_; 1489 int number_of_objects_with_fast_elements_; 1490 int number_of_fast_used_fields_; 1491 int number_of_fast_unused_fields_; 1492 int number_of_slow_used_properties_; 1493 int number_of_slow_unused_properties_; 1494 int number_of_fast_used_elements_; 1495 int number_of_fast_unused_elements_; 1496 int number_of_slow_used_elements_; 1497 int number_of_slow_unused_elements_; 1498 }; 1499 1500 void IncrementSpillStatistics(SpillInformation* info); 1501 #endif 1502 Object* SlowReverseLookup(Object* value); 1503 1504 // Maximal number of elements (numbered 0 .. kMaxElementCount - 1). 1505 // Also maximal value of JSArray's length property. 1506 static const uint32_t kMaxElementCount = 0xffffffffu; 1507 1508 static const uint32_t kMaxGap = 1024; 1509 static const int kMaxFastElementsLength = 5000; 1510 static const int kInitialMaxFastElementArray = 100000; 1511 static const int kMaxFastProperties = 8; 1512 static const int kMaxInstanceSize = 255 * kPointerSize; 1513 // When extending the backing storage for property values, we increase 1514 // its size by more than the 1 entry necessary, so sequentially adding fields 1515 // to the same object requires fewer allocations and copies. 1516 static const int kFieldsAdded = 3; 1517 1518 // Layout description. 1519 static const int kPropertiesOffset = HeapObject::kHeaderSize; 1520 static const int kElementsOffset = kPropertiesOffset + kPointerSize; 1521 static const int kHeaderSize = kElementsOffset + kPointerSize; 1522 1523 STATIC_CHECK(kHeaderSize == Internals::kJSObjectHeaderSize); 1524 1525 Object* GetElementWithInterceptor(JSObject* receiver, uint32_t index); 1526 1527 private: 1528 Object* SetElementWithInterceptor(uint32_t index, Object* value); 1529 Object* SetElementWithoutInterceptor(uint32_t index, Object* value); 1530 1531 Object* GetElementPostInterceptor(JSObject* receiver, uint32_t index); 1532 1533 Object* DeletePropertyPostInterceptor(String* name, DeleteMode mode); 1534 Object* DeletePropertyWithInterceptor(String* name); 1535 1536 Object* DeleteElementPostInterceptor(uint32_t index, DeleteMode mode); 1537 Object* DeleteElementWithInterceptor(uint32_t index); 1538 1539 PropertyAttributes GetPropertyAttributePostInterceptor(JSObject* receiver, 1540 String* name, 1541 bool continue_search); 1542 PropertyAttributes GetPropertyAttributeWithInterceptor(JSObject* receiver, 1543 String* name, 1544 bool continue_search); 1545 PropertyAttributes GetPropertyAttributeWithFailedAccessCheck( 1546 Object* receiver, 1547 LookupResult* result, 1548 String* name, 1549 bool continue_search); 1550 PropertyAttributes GetPropertyAttribute(JSObject* receiver, 1551 LookupResult* result, 1552 String* name, 1553 bool continue_search); 1554 1555 // Returns true if most of the elements backing storage is used. 1556 bool HasDenseElements(); 1557 1558 Object* DefineGetterSetter(String* name, PropertyAttributes attributes); 1559 1560 void LookupInDescriptor(String* name, LookupResult* result); 1561 1562 DISALLOW_IMPLICIT_CONSTRUCTORS(JSObject); 1563 }; 1564 1565 1566 // Abstract super class arrays. It provides length behavior. 1567 class Array: public HeapObject { 1568 public: 1569 // [length]: length of the array. 1570 inline int length(); 1571 inline void set_length(int value); 1572 1573 // Convert an object to an array index. 1574 // Returns true if the conversion succeeded. 1575 static inline bool IndexFromObject(Object* object, uint32_t* index); 1576 1577 // Layout descriptor. 1578 static const int kLengthOffset = HeapObject::kHeaderSize; 1579 1580 protected: 1581 // No code should use the Array class directly, only its subclasses. 1582 // Use the kHeaderSize of the appropriate subclass, which may be aligned. 1583 static const int kHeaderSize = kLengthOffset + kIntSize; 1584 static const int kAlignedSize = POINTER_SIZE_ALIGN(kHeaderSize); 1585 1586 private: 1587 DISALLOW_IMPLICIT_CONSTRUCTORS(Array); 1588 }; 1589 1590 1591 // FixedArray describes fixed sized arrays where element 1592 // type is Object*. 1593 1594 class FixedArray: public Array { 1595 public: 1596 1597 // Setter and getter for elements. 1598 inline Object* get(int index); 1599 // Setter that uses write barrier. 1600 inline void set(int index, Object* value); 1601 1602 // Setter that doesn't need write barrier). 1603 inline void set(int index, Smi* value); 1604 // Setter with explicit barrier mode. 1605 inline void set(int index, Object* value, WriteBarrierMode mode); 1606 1607 // Setters for frequently used oddballs located in old space. 1608 inline void set_undefined(int index); 1609 inline void set_null(int index); 1610 inline void set_the_hole(int index); 1611 1612 // Copy operations. 1613 inline Object* Copy(); 1614 Object* CopySize(int new_length); 1615 1616 // Add the elements of a JSArray to this FixedArray. 1617 Object* AddKeysFromJSArray(JSArray* array); 1618 1619 // Compute the union of this and other. 1620 Object* UnionOfKeys(FixedArray* other); 1621 1622 // Copy a sub array from the receiver to dest. 1623 void CopyTo(int pos, FixedArray* dest, int dest_pos, int len); 1624 1625 // Garbage collection support. SizeFor(int length)1626 static int SizeFor(int length) { return kHeaderSize + length * kPointerSize; } 1627 1628 // Code Generation support. OffsetOfElementAt(int index)1629 static int OffsetOfElementAt(int index) { return SizeFor(index); } 1630 1631 // Casting. 1632 static inline FixedArray* cast(Object* obj); 1633 1634 static const int kHeaderSize = Array::kAlignedSize; 1635 1636 // Maximal allowed size, in bytes, of a single FixedArray. 1637 // Prevents overflowing size computations, as well as extreme memory 1638 // consumption. 1639 static const int kMaxSize = 512 * MB; 1640 // Maximally allowed length of a FixedArray. 1641 static const int kMaxLength = (kMaxSize - kHeaderSize) / kPointerSize; 1642 1643 // Dispatched behavior. FixedArraySize()1644 int FixedArraySize() { return SizeFor(length()); } 1645 void FixedArrayIterateBody(ObjectVisitor* v); 1646 #ifdef DEBUG 1647 void FixedArrayPrint(); 1648 void FixedArrayVerify(); 1649 // Checks if two FixedArrays have identical contents. 1650 bool IsEqualTo(FixedArray* other); 1651 #endif 1652 1653 // Swap two elements in a pair of arrays. If this array and the 1654 // numbers array are the same object, the elements are only swapped 1655 // once. 1656 void SwapPairs(FixedArray* numbers, int i, int j); 1657 1658 // Sort prefix of this array and the numbers array as pairs wrt. the 1659 // numbers. If the numbers array and the this array are the same 1660 // object, the prefix of this array is sorted. 1661 void SortPairs(FixedArray* numbers, uint32_t len); 1662 1663 protected: 1664 // Set operation on FixedArray without using write barriers. Can 1665 // only be used for storing old space objects or smis. 1666 static inline void fast_set(FixedArray* array, int index, Object* value); 1667 1668 private: 1669 DISALLOW_IMPLICIT_CONSTRUCTORS(FixedArray); 1670 }; 1671 1672 1673 // DescriptorArrays are fixed arrays used to hold instance descriptors. 1674 // The format of the these objects is: 1675 // [0]: point to a fixed array with (value, detail) pairs. 1676 // [1]: next enumeration index (Smi), or pointer to small fixed array: 1677 // [0]: next enumeration index (Smi) 1678 // [1]: pointer to fixed array with enum cache 1679 // [2]: first key 1680 // [length() - 1]: last key 1681 // 1682 class DescriptorArray: public FixedArray { 1683 public: 1684 // Is this the singleton empty_descriptor_array? 1685 inline bool IsEmpty(); 1686 1687 // Returns the number of descriptors in the array. number_of_descriptors()1688 int number_of_descriptors() { 1689 return IsEmpty() ? 0 : length() - kFirstIndex; 1690 } 1691 NextEnumerationIndex()1692 int NextEnumerationIndex() { 1693 if (IsEmpty()) return PropertyDetails::kInitialIndex; 1694 Object* obj = get(kEnumerationIndexIndex); 1695 if (obj->IsSmi()) { 1696 return Smi::cast(obj)->value(); 1697 } else { 1698 Object* index = FixedArray::cast(obj)->get(kEnumCacheBridgeEnumIndex); 1699 return Smi::cast(index)->value(); 1700 } 1701 } 1702 1703 // Set next enumeration index and flush any enum cache. SetNextEnumerationIndex(int value)1704 void SetNextEnumerationIndex(int value) { 1705 if (!IsEmpty()) { 1706 fast_set(this, kEnumerationIndexIndex, Smi::FromInt(value)); 1707 } 1708 } HasEnumCache()1709 bool HasEnumCache() { 1710 return !IsEmpty() && !get(kEnumerationIndexIndex)->IsSmi(); 1711 } 1712 GetEnumCache()1713 Object* GetEnumCache() { 1714 ASSERT(HasEnumCache()); 1715 FixedArray* bridge = FixedArray::cast(get(kEnumerationIndexIndex)); 1716 return bridge->get(kEnumCacheBridgeCacheIndex); 1717 } 1718 1719 // Initialize or change the enum cache, 1720 // using the supplied storage for the small "bridge". 1721 void SetEnumCache(FixedArray* bridge_storage, FixedArray* new_cache); 1722 1723 // Accessors for fetching instance descriptor at descriptor number. 1724 inline String* GetKey(int descriptor_number); 1725 inline Object* GetValue(int descriptor_number); 1726 inline Smi* GetDetails(int descriptor_number); 1727 inline PropertyType GetType(int descriptor_number); 1728 inline int GetFieldIndex(int descriptor_number); 1729 inline JSFunction* GetConstantFunction(int descriptor_number); 1730 inline Object* GetCallbacksObject(int descriptor_number); 1731 inline AccessorDescriptor* GetCallbacks(int descriptor_number); 1732 inline bool IsProperty(int descriptor_number); 1733 inline bool IsTransition(int descriptor_number); 1734 inline bool IsNullDescriptor(int descriptor_number); 1735 inline bool IsDontEnum(int descriptor_number); 1736 1737 // Accessor for complete descriptor. 1738 inline void Get(int descriptor_number, Descriptor* desc); 1739 inline void Set(int descriptor_number, Descriptor* desc); 1740 1741 // Transfer complete descriptor from another descriptor array to 1742 // this one. 1743 inline void CopyFrom(int index, DescriptorArray* src, int src_index); 1744 1745 // Copy the descriptor array, insert a new descriptor and optionally 1746 // remove map transitions. If the descriptor is already present, it is 1747 // replaced. If a replaced descriptor is a real property (not a transition 1748 // or null), its enumeration index is kept as is. 1749 // If adding a real property, map transitions must be removed. If adding 1750 // a transition, they must not be removed. All null descriptors are removed. 1751 Object* CopyInsert(Descriptor* descriptor, TransitionFlag transition_flag); 1752 1753 // Remove all transitions. Return a copy of the array with all transitions 1754 // removed, or a Failure object if the new array could not be allocated. 1755 Object* RemoveTransitions(); 1756 1757 // Sort the instance descriptors by the hash codes of their keys. 1758 void Sort(); 1759 1760 // Search the instance descriptors for given name. 1761 inline int Search(String* name); 1762 1763 // Tells whether the name is present int the array. Contains(String * name)1764 bool Contains(String* name) { return kNotFound != Search(name); } 1765 1766 // Perform a binary search in the instance descriptors represented 1767 // by this fixed array. low and high are descriptor indices. If there 1768 // are three instance descriptors in this array it should be called 1769 // with low=0 and high=2. 1770 int BinarySearch(String* name, int low, int high); 1771 1772 // Perform a linear search in the instance descriptors represented 1773 // by this fixed array. len is the number of descriptor indices that are 1774 // valid. Does not require the descriptors to be sorted. 1775 int LinearSearch(String* name, int len); 1776 1777 // Allocates a DescriptorArray, but returns the singleton 1778 // empty descriptor array object if number_of_descriptors is 0. 1779 static Object* Allocate(int number_of_descriptors); 1780 1781 // Casting. 1782 static inline DescriptorArray* cast(Object* obj); 1783 1784 // Constant for denoting key was not found. 1785 static const int kNotFound = -1; 1786 1787 static const int kContentArrayIndex = 0; 1788 static const int kEnumerationIndexIndex = 1; 1789 static const int kFirstIndex = 2; 1790 1791 // The length of the "bridge" to the enum cache. 1792 static const int kEnumCacheBridgeLength = 2; 1793 static const int kEnumCacheBridgeEnumIndex = 0; 1794 static const int kEnumCacheBridgeCacheIndex = 1; 1795 1796 // Layout description. 1797 static const int kContentArrayOffset = FixedArray::kHeaderSize; 1798 static const int kEnumerationIndexOffset = kContentArrayOffset + kPointerSize; 1799 static const int kFirstOffset = kEnumerationIndexOffset + kPointerSize; 1800 1801 // Layout description for the bridge array. 1802 static const int kEnumCacheBridgeEnumOffset = FixedArray::kHeaderSize; 1803 static const int kEnumCacheBridgeCacheOffset = 1804 kEnumCacheBridgeEnumOffset + kPointerSize; 1805 1806 #ifdef DEBUG 1807 // Print all the descriptors. 1808 void PrintDescriptors(); 1809 1810 // Is the descriptor array sorted and without duplicates? 1811 bool IsSortedNoDuplicates(); 1812 1813 // Are two DescriptorArrays equal? 1814 bool IsEqualTo(DescriptorArray* other); 1815 #endif 1816 1817 // The maximum number of descriptors we want in a descriptor array (should 1818 // fit in a page). 1819 static const int kMaxNumberOfDescriptors = 1024 + 512; 1820 1821 private: 1822 // Conversion from descriptor number to array indices. ToKeyIndex(int descriptor_number)1823 static int ToKeyIndex(int descriptor_number) { 1824 return descriptor_number+kFirstIndex; 1825 } 1826 ToDetailsIndex(int descriptor_number)1827 static int ToDetailsIndex(int descriptor_number) { 1828 return (descriptor_number << 1) + 1; 1829 } 1830 ToValueIndex(int descriptor_number)1831 static int ToValueIndex(int descriptor_number) { 1832 return descriptor_number << 1; 1833 } 1834 is_null_descriptor(int descriptor_number)1835 bool is_null_descriptor(int descriptor_number) { 1836 return PropertyDetails(GetDetails(descriptor_number)).type() == 1837 NULL_DESCRIPTOR; 1838 } 1839 // Swap operation on FixedArray without using write barriers. 1840 static inline void fast_swap(FixedArray* array, int first, int second); 1841 1842 // Swap descriptor first and second. 1843 inline void Swap(int first, int second); 1844 GetContentArray()1845 FixedArray* GetContentArray() { 1846 return FixedArray::cast(get(kContentArrayIndex)); 1847 } 1848 DISALLOW_IMPLICIT_CONSTRUCTORS(DescriptorArray); 1849 }; 1850 1851 1852 // HashTable is a subclass of FixedArray that implements a hash table 1853 // that uses open addressing and quadratic probing. 1854 // 1855 // In order for the quadratic probing to work, elements that have not 1856 // yet been used and elements that have been deleted are 1857 // distinguished. Probing continues when deleted elements are 1858 // encountered and stops when unused elements are encountered. 1859 // 1860 // - Elements with key == undefined have not been used yet. 1861 // - Elements with key == null have been deleted. 1862 // 1863 // The hash table class is parameterized with a Shape and a Key. 1864 // Shape must be a class with the following interface: 1865 // class ExampleShape { 1866 // public: 1867 // // Tells whether key matches other. 1868 // static bool IsMatch(Key key, Object* other); 1869 // // Returns the hash value for key. 1870 // static uint32_t Hash(Key key); 1871 // // Returns the hash value for object. 1872 // static uint32_t HashForObject(Key key, Object* object); 1873 // // Convert key to an object. 1874 // static inline Object* AsObject(Key key); 1875 // // The prefix size indicates number of elements in the beginning 1876 // // of the backing storage. 1877 // static const int kPrefixSize = ..; 1878 // // The Element size indicates number of elements per entry. 1879 // static const int kEntrySize = ..; 1880 // }; 1881 // The prefix size indicates an amount of memory in the 1882 // beginning of the backing storage that can be used for non-element 1883 // information by subclasses. 1884 1885 template<typename Shape, typename Key> 1886 class HashTable: public FixedArray { 1887 public: 1888 // Returns the number of elements in the hash table. NumberOfElements()1889 int NumberOfElements() { 1890 return Smi::cast(get(kNumberOfElementsIndex))->value(); 1891 } 1892 1893 // Returns the number of deleted elements in the hash table. NumberOfDeletedElements()1894 int NumberOfDeletedElements() { 1895 return Smi::cast(get(kNumberOfDeletedElementsIndex))->value(); 1896 } 1897 1898 // Returns the capacity of the hash table. Capacity()1899 int Capacity() { 1900 return Smi::cast(get(kCapacityIndex))->value(); 1901 } 1902 1903 // ElementAdded should be called whenever an element is added to a 1904 // hash table. ElementAdded()1905 void ElementAdded() { SetNumberOfElements(NumberOfElements() + 1); } 1906 1907 // ElementRemoved should be called whenever an element is removed from 1908 // a hash table. ElementRemoved()1909 void ElementRemoved() { 1910 SetNumberOfElements(NumberOfElements() - 1); 1911 SetNumberOfDeletedElements(NumberOfDeletedElements() + 1); 1912 } ElementsRemoved(int n)1913 void ElementsRemoved(int n) { 1914 SetNumberOfElements(NumberOfElements() - n); 1915 SetNumberOfDeletedElements(NumberOfDeletedElements() + n); 1916 } 1917 1918 // Returns a new HashTable object. Might return Failure. 1919 static Object* Allocate(int at_least_space_for); 1920 1921 // Returns the key at entry. KeyAt(int entry)1922 Object* KeyAt(int entry) { return get(EntryToIndex(entry)); } 1923 1924 // Tells whether k is a real key. Null and undefined are not allowed 1925 // as keys and can be used to indicate missing or deleted elements. IsKey(Object * k)1926 bool IsKey(Object* k) { 1927 return !k->IsNull() && !k->IsUndefined(); 1928 } 1929 1930 // Garbage collection support. 1931 void IteratePrefix(ObjectVisitor* visitor); 1932 void IterateElements(ObjectVisitor* visitor); 1933 1934 // Casting. 1935 static inline HashTable* cast(Object* obj); 1936 1937 // Compute the probe offset (quadratic probing). INLINE(static uint32_t GetProbeOffset (uint32_t n))1938 INLINE(static uint32_t GetProbeOffset(uint32_t n)) { 1939 return (n + n * n) >> 1; 1940 } 1941 1942 static const int kNumberOfElementsIndex = 0; 1943 static const int kNumberOfDeletedElementsIndex = 1; 1944 static const int kCapacityIndex = 2; 1945 static const int kPrefixStartIndex = 3; 1946 static const int kElementsStartIndex = 1947 kPrefixStartIndex + Shape::kPrefixSize; 1948 static const int kEntrySize = Shape::kEntrySize; 1949 static const int kElementsStartOffset = 1950 kHeaderSize + kElementsStartIndex * kPointerSize; 1951 1952 // Constant used for denoting a absent entry. 1953 static const int kNotFound = -1; 1954 1955 // Maximal capacity of HashTable. Based on maximal length of underlying 1956 // FixedArray. Staying below kMaxCapacity also ensures that EntryToIndex 1957 // cannot overflow. 1958 static const int kMaxCapacity = 1959 (FixedArray::kMaxLength - kElementsStartOffset) / kEntrySize; 1960 1961 // Find entry for key otherwise return -1. 1962 int FindEntry(Key key); 1963 1964 protected: 1965 1966 // Find the entry at which to insert element with the given key that 1967 // has the given hash value. 1968 uint32_t FindInsertionEntry(uint32_t hash); 1969 1970 // Returns the index for an entry (of the key) EntryToIndex(int entry)1971 static inline int EntryToIndex(int entry) { 1972 return (entry * kEntrySize) + kElementsStartIndex; 1973 } 1974 1975 // Update the number of elements in the hash table. SetNumberOfElements(int nof)1976 void SetNumberOfElements(int nof) { 1977 fast_set(this, kNumberOfElementsIndex, Smi::FromInt(nof)); 1978 } 1979 1980 // Update the number of deleted elements in the hash table. SetNumberOfDeletedElements(int nod)1981 void SetNumberOfDeletedElements(int nod) { 1982 fast_set(this, kNumberOfDeletedElementsIndex, Smi::FromInt(nod)); 1983 } 1984 1985 // Sets the capacity of the hash table. SetCapacity(int capacity)1986 void SetCapacity(int capacity) { 1987 // To scale a computed hash code to fit within the hash table, we 1988 // use bit-wise AND with a mask, so the capacity must be positive 1989 // and non-zero. 1990 ASSERT(capacity > 0); 1991 ASSERT(capacity <= kMaxCapacity); 1992 fast_set(this, kCapacityIndex, Smi::FromInt(capacity)); 1993 } 1994 1995 1996 // Returns probe entry. GetProbe(uint32_t hash,uint32_t number,uint32_t size)1997 static uint32_t GetProbe(uint32_t hash, uint32_t number, uint32_t size) { 1998 ASSERT(IsPowerOf2(size)); 1999 return (hash + GetProbeOffset(number)) & (size - 1); 2000 } 2001 FirstProbe(uint32_t hash,uint32_t size)2002 static uint32_t FirstProbe(uint32_t hash, uint32_t size) { 2003 return hash & (size - 1); 2004 } 2005 NextProbe(uint32_t last,uint32_t number,uint32_t size)2006 static uint32_t NextProbe(uint32_t last, uint32_t number, uint32_t size) { 2007 return (last + number) & (size - 1); 2008 } 2009 2010 // Ensure enough space for n additional elements. 2011 Object* EnsureCapacity(int n, Key key); 2012 }; 2013 2014 2015 2016 // HashTableKey is an abstract superclass for virtual key behavior. 2017 class HashTableKey { 2018 public: 2019 // Returns whether the other object matches this key. 2020 virtual bool IsMatch(Object* other) = 0; 2021 // Returns the hash value for this key. 2022 virtual uint32_t Hash() = 0; 2023 // Returns the hash value for object. 2024 virtual uint32_t HashForObject(Object* key) = 0; 2025 // Returns the key object for storing into the hash table. 2026 // If allocations fails a failure object is returned. 2027 virtual Object* AsObject() = 0; 2028 // Required. ~HashTableKey()2029 virtual ~HashTableKey() {} 2030 }; 2031 2032 class SymbolTableShape { 2033 public: IsMatch(HashTableKey * key,Object * value)2034 static bool IsMatch(HashTableKey* key, Object* value) { 2035 return key->IsMatch(value); 2036 } Hash(HashTableKey * key)2037 static uint32_t Hash(HashTableKey* key) { 2038 return key->Hash(); 2039 } HashForObject(HashTableKey * key,Object * object)2040 static uint32_t HashForObject(HashTableKey* key, Object* object) { 2041 return key->HashForObject(object); 2042 } AsObject(HashTableKey * key)2043 static Object* AsObject(HashTableKey* key) { 2044 return key->AsObject(); 2045 } 2046 2047 static const int kPrefixSize = 0; 2048 static const int kEntrySize = 1; 2049 }; 2050 2051 // SymbolTable. 2052 // 2053 // No special elements in the prefix and the element size is 1 2054 // because only the symbol itself (the key) needs to be stored. 2055 class SymbolTable: public HashTable<SymbolTableShape, HashTableKey*> { 2056 public: 2057 // Find symbol in the symbol table. If it is not there yet, it is 2058 // added. The return value is the symbol table which might have 2059 // been enlarged. If the return value is not a failure, the symbol 2060 // pointer *s is set to the symbol found. 2061 Object* LookupSymbol(Vector<const char> str, Object** s); 2062 Object* LookupString(String* key, Object** s); 2063 2064 // Looks up a symbol that is equal to the given string and returns 2065 // true if it is found, assigning the symbol to the given output 2066 // parameter. 2067 bool LookupSymbolIfExists(String* str, String** symbol); 2068 bool LookupTwoCharsSymbolIfExists(uint32_t c1, uint32_t c2, String** symbol); 2069 2070 // Casting. 2071 static inline SymbolTable* cast(Object* obj); 2072 2073 private: 2074 Object* LookupKey(HashTableKey* key, Object** s); 2075 2076 DISALLOW_IMPLICIT_CONSTRUCTORS(SymbolTable); 2077 }; 2078 2079 2080 class MapCacheShape { 2081 public: IsMatch(HashTableKey * key,Object * value)2082 static bool IsMatch(HashTableKey* key, Object* value) { 2083 return key->IsMatch(value); 2084 } Hash(HashTableKey * key)2085 static uint32_t Hash(HashTableKey* key) { 2086 return key->Hash(); 2087 } 2088 HashForObject(HashTableKey * key,Object * object)2089 static uint32_t HashForObject(HashTableKey* key, Object* object) { 2090 return key->HashForObject(object); 2091 } 2092 AsObject(HashTableKey * key)2093 static Object* AsObject(HashTableKey* key) { 2094 return key->AsObject(); 2095 } 2096 2097 static const int kPrefixSize = 0; 2098 static const int kEntrySize = 2; 2099 }; 2100 2101 2102 // MapCache. 2103 // 2104 // Maps keys that are a fixed array of symbols to a map. 2105 // Used for canonicalize maps for object literals. 2106 class MapCache: public HashTable<MapCacheShape, HashTableKey*> { 2107 public: 2108 // Find cached value for a string key, otherwise return null. 2109 Object* Lookup(FixedArray* key); 2110 Object* Put(FixedArray* key, Map* value); 2111 static inline MapCache* cast(Object* obj); 2112 2113 private: 2114 DISALLOW_IMPLICIT_CONSTRUCTORS(MapCache); 2115 }; 2116 2117 2118 template <typename Shape, typename Key> 2119 class Dictionary: public HashTable<Shape, Key> { 2120 public: 2121 cast(Object * obj)2122 static inline Dictionary<Shape, Key>* cast(Object* obj) { 2123 return reinterpret_cast<Dictionary<Shape, Key>*>(obj); 2124 } 2125 2126 // Returns the value at entry. ValueAt(int entry)2127 Object* ValueAt(int entry) { 2128 return get(HashTable<Shape, Key>::EntryToIndex(entry)+1); 2129 } 2130 2131 // Set the value for entry. ValueAtPut(int entry,Object * value)2132 void ValueAtPut(int entry, Object* value) { 2133 set(HashTable<Shape, Key>::EntryToIndex(entry)+1, value); 2134 } 2135 2136 // Returns the property details for the property at entry. DetailsAt(int entry)2137 PropertyDetails DetailsAt(int entry) { 2138 ASSERT(entry >= 0); // Not found is -1, which is not caught by get(). 2139 return PropertyDetails( 2140 Smi::cast(get(HashTable<Shape, Key>::EntryToIndex(entry) + 2))); 2141 } 2142 2143 // Set the details for entry. DetailsAtPut(int entry,PropertyDetails value)2144 void DetailsAtPut(int entry, PropertyDetails value) { 2145 set(HashTable<Shape, Key>::EntryToIndex(entry) + 2, value.AsSmi()); 2146 } 2147 2148 // Sorting support 2149 void CopyValuesTo(FixedArray* elements); 2150 2151 // Delete a property from the dictionary. 2152 Object* DeleteProperty(int entry, JSObject::DeleteMode mode); 2153 2154 // Returns the number of elements in the dictionary filtering out properties 2155 // with the specified attributes. 2156 int NumberOfElementsFilterAttributes(PropertyAttributes filter); 2157 2158 // Returns the number of enumerable elements in the dictionary. 2159 int NumberOfEnumElements(); 2160 2161 // Copies keys to preallocated fixed array. 2162 void CopyKeysTo(FixedArray* storage, PropertyAttributes filter); 2163 // Fill in details for properties into storage. 2164 void CopyKeysTo(FixedArray* storage); 2165 2166 // Accessors for next enumeration index. SetNextEnumerationIndex(int index)2167 void SetNextEnumerationIndex(int index) { 2168 fast_set(this, kNextEnumerationIndexIndex, Smi::FromInt(index)); 2169 } 2170 NextEnumerationIndex()2171 int NextEnumerationIndex() { 2172 return Smi::cast(FixedArray::get(kNextEnumerationIndexIndex))->value(); 2173 } 2174 2175 // Returns a new array for dictionary usage. Might return Failure. 2176 static Object* Allocate(int at_least_space_for); 2177 2178 // Ensure enough space for n additional elements. 2179 Object* EnsureCapacity(int n, Key key); 2180 2181 #ifdef DEBUG 2182 void Print(); 2183 #endif 2184 // Returns the key (slow). 2185 Object* SlowReverseLookup(Object* value); 2186 2187 // Sets the entry to (key, value) pair. 2188 inline void SetEntry(int entry, 2189 Object* key, 2190 Object* value, 2191 PropertyDetails details); 2192 2193 Object* Add(Key key, Object* value, PropertyDetails details); 2194 2195 protected: 2196 // Generic at put operation. 2197 Object* AtPut(Key key, Object* value); 2198 2199 // Add entry to dictionary. 2200 Object* AddEntry(Key key, 2201 Object* value, 2202 PropertyDetails details, 2203 uint32_t hash); 2204 2205 // Generate new enumeration indices to avoid enumeration index overflow. 2206 Object* GenerateNewEnumerationIndices(); 2207 static const int kMaxNumberKeyIndex = 2208 HashTable<Shape, Key>::kPrefixStartIndex; 2209 static const int kNextEnumerationIndexIndex = kMaxNumberKeyIndex + 1; 2210 }; 2211 2212 2213 class StringDictionaryShape { 2214 public: 2215 static inline bool IsMatch(String* key, Object* other); 2216 static inline uint32_t Hash(String* key); 2217 static inline uint32_t HashForObject(String* key, Object* object); 2218 static inline Object* AsObject(String* key); 2219 static const int kPrefixSize = 2; 2220 static const int kEntrySize = 3; 2221 static const bool kIsEnumerable = true; 2222 }; 2223 2224 2225 class StringDictionary: public Dictionary<StringDictionaryShape, String*> { 2226 public: cast(Object * obj)2227 static inline StringDictionary* cast(Object* obj) { 2228 ASSERT(obj->IsDictionary()); 2229 return reinterpret_cast<StringDictionary*>(obj); 2230 } 2231 2232 // Copies enumerable keys to preallocated fixed array. 2233 void CopyEnumKeysTo(FixedArray* storage, FixedArray* sort_array); 2234 2235 // For transforming properties of a JSObject. 2236 Object* TransformPropertiesToFastFor(JSObject* obj, 2237 int unused_property_fields); 2238 }; 2239 2240 2241 class NumberDictionaryShape { 2242 public: 2243 static inline bool IsMatch(uint32_t key, Object* other); 2244 static inline uint32_t Hash(uint32_t key); 2245 static inline uint32_t HashForObject(uint32_t key, Object* object); 2246 static inline Object* AsObject(uint32_t key); 2247 static const int kPrefixSize = 2; 2248 static const int kEntrySize = 3; 2249 static const bool kIsEnumerable = false; 2250 }; 2251 2252 2253 class NumberDictionary: public Dictionary<NumberDictionaryShape, uint32_t> { 2254 public: cast(Object * obj)2255 static NumberDictionary* cast(Object* obj) { 2256 ASSERT(obj->IsDictionary()); 2257 return reinterpret_cast<NumberDictionary*>(obj); 2258 } 2259 2260 // Type specific at put (default NONE attributes is used when adding). 2261 Object* AtNumberPut(uint32_t key, Object* value); 2262 Object* AddNumberEntry(uint32_t key, 2263 Object* value, 2264 PropertyDetails details); 2265 2266 // Set an existing entry or add a new one if needed. 2267 Object* Set(uint32_t key, Object* value, PropertyDetails details); 2268 2269 void UpdateMaxNumberKey(uint32_t key); 2270 2271 // If slow elements are required we will never go back to fast-case 2272 // for the elements kept in this dictionary. We require slow 2273 // elements if an element has been added at an index larger than 2274 // kRequiresSlowElementsLimit or set_requires_slow_elements() has been called 2275 // when defining a getter or setter with a number key. 2276 inline bool requires_slow_elements(); 2277 inline void set_requires_slow_elements(); 2278 2279 // Get the value of the max number key that has been added to this 2280 // dictionary. max_number_key can only be called if 2281 // requires_slow_elements returns false. 2282 inline uint32_t max_number_key(); 2283 2284 // Remove all entries were key is a number and (from <= key && key < to). 2285 void RemoveNumberEntries(uint32_t from, uint32_t to); 2286 2287 // Bit masks. 2288 static const int kRequiresSlowElementsMask = 1; 2289 static const int kRequiresSlowElementsTagSize = 1; 2290 static const uint32_t kRequiresSlowElementsLimit = (1 << 29) - 1; 2291 }; 2292 2293 2294 // ByteArray represents fixed sized byte arrays. Used by the outside world, 2295 // such as PCRE, and also by the memory allocator and garbage collector to 2296 // fill in free blocks in the heap. 2297 class ByteArray: public Array { 2298 public: 2299 // Setter and getter. 2300 inline byte get(int index); 2301 inline void set(int index, byte value); 2302 2303 // Treat contents as an int array. 2304 inline int get_int(int index); 2305 SizeFor(int length)2306 static int SizeFor(int length) { 2307 return OBJECT_SIZE_ALIGN(kHeaderSize + length); 2308 } 2309 // We use byte arrays for free blocks in the heap. Given a desired size in 2310 // bytes that is a multiple of the word size and big enough to hold a byte 2311 // array, this function returns the number of elements a byte array should 2312 // have. LengthFor(int size_in_bytes)2313 static int LengthFor(int size_in_bytes) { 2314 ASSERT(IsAligned(size_in_bytes, kPointerSize)); 2315 ASSERT(size_in_bytes >= kHeaderSize); 2316 return size_in_bytes - kHeaderSize; 2317 } 2318 2319 // Returns data start address. 2320 inline Address GetDataStartAddress(); 2321 2322 // Returns a pointer to the ByteArray object for a given data start address. 2323 static inline ByteArray* FromDataStartAddress(Address address); 2324 2325 // Casting. 2326 static inline ByteArray* cast(Object* obj); 2327 2328 // Dispatched behavior. ByteArraySize()2329 int ByteArraySize() { return SizeFor(length()); } 2330 #ifdef DEBUG 2331 void ByteArrayPrint(); 2332 void ByteArrayVerify(); 2333 #endif 2334 2335 // ByteArray headers are not quadword aligned. 2336 static const int kHeaderSize = Array::kHeaderSize; 2337 static const int kAlignedSize = Array::kAlignedSize; 2338 2339 // Maximal memory consumption for a single ByteArray. 2340 static const int kMaxSize = 512 * MB; 2341 // Maximal length of a single ByteArray. 2342 static const int kMaxLength = kMaxSize - kHeaderSize; 2343 2344 private: 2345 DISALLOW_IMPLICIT_CONSTRUCTORS(ByteArray); 2346 }; 2347 2348 2349 // A PixelArray represents a fixed-size byte array with special semantics 2350 // used for implementing the CanvasPixelArray object. Please see the 2351 // specification at: 2352 // http://www.whatwg.org/specs/web-apps/current-work/ 2353 // multipage/the-canvas-element.html#canvaspixelarray 2354 // In particular, write access clamps the value written to 0 or 255 if the 2355 // value written is outside this range. 2356 class PixelArray: public Array { 2357 public: 2358 // [external_pointer]: The pointer to the external memory area backing this 2359 // pixel array. 2360 DECL_ACCESSORS(external_pointer, uint8_t) // Pointer to the data store. 2361 2362 // Setter and getter. 2363 inline uint8_t get(int index); 2364 inline void set(int index, uint8_t value); 2365 2366 // This accessor applies the correct conversion from Smi, HeapNumber and 2367 // undefined and clamps the converted value between 0 and 255. 2368 Object* SetValue(uint32_t index, Object* value); 2369 2370 // Casting. 2371 static inline PixelArray* cast(Object* obj); 2372 2373 #ifdef DEBUG 2374 void PixelArrayPrint(); 2375 void PixelArrayVerify(); 2376 #endif // DEBUG 2377 2378 // Maximal acceptable length for a pixel array. 2379 static const int kMaxLength = 0x3fffffff; 2380 2381 // PixelArray headers are not quadword aligned. 2382 static const int kExternalPointerOffset = Array::kAlignedSize; 2383 static const int kHeaderSize = kExternalPointerOffset + kPointerSize; 2384 static const int kAlignedSize = OBJECT_SIZE_ALIGN(kHeaderSize); 2385 2386 private: 2387 DISALLOW_IMPLICIT_CONSTRUCTORS(PixelArray); 2388 }; 2389 2390 2391 // An ExternalArray represents a fixed-size array of primitive values 2392 // which live outside the JavaScript heap. Its subclasses are used to 2393 // implement the CanvasArray types being defined in the WebGL 2394 // specification. As of this writing the first public draft is not yet 2395 // available, but Khronos members can access the draft at: 2396 // https://cvs.khronos.org/svn/repos/3dweb/trunk/doc/spec/WebGL-spec.html 2397 // 2398 // The semantics of these arrays differ from CanvasPixelArray. 2399 // Out-of-range values passed to the setter are converted via a C 2400 // cast, not clamping. Out-of-range indices cause exceptions to be 2401 // raised rather than being silently ignored. 2402 class ExternalArray: public Array { 2403 public: 2404 // [external_pointer]: The pointer to the external memory area backing this 2405 // external array. 2406 DECL_ACCESSORS(external_pointer, void) // Pointer to the data store. 2407 2408 // Casting. 2409 static inline ExternalArray* cast(Object* obj); 2410 2411 // Maximal acceptable length for an external array. 2412 static const int kMaxLength = 0x3fffffff; 2413 2414 // ExternalArray headers are not quadword aligned. 2415 static const int kExternalPointerOffset = Array::kAlignedSize; 2416 static const int kHeaderSize = kExternalPointerOffset + kPointerSize; 2417 static const int kAlignedSize = OBJECT_SIZE_ALIGN(kHeaderSize); 2418 2419 private: 2420 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalArray); 2421 }; 2422 2423 2424 class ExternalByteArray: public ExternalArray { 2425 public: 2426 // Setter and getter. 2427 inline int8_t get(int index); 2428 inline void set(int index, int8_t value); 2429 2430 // This accessor applies the correct conversion from Smi, HeapNumber 2431 // and undefined. 2432 Object* SetValue(uint32_t index, Object* value); 2433 2434 // Casting. 2435 static inline ExternalByteArray* cast(Object* obj); 2436 2437 #ifdef DEBUG 2438 void ExternalByteArrayPrint(); 2439 void ExternalByteArrayVerify(); 2440 #endif // DEBUG 2441 2442 private: 2443 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalByteArray); 2444 }; 2445 2446 2447 class ExternalUnsignedByteArray: public ExternalArray { 2448 public: 2449 // Setter and getter. 2450 inline uint8_t get(int index); 2451 inline void set(int index, uint8_t value); 2452 2453 // This accessor applies the correct conversion from Smi, HeapNumber 2454 // and undefined. 2455 Object* SetValue(uint32_t index, Object* value); 2456 2457 // Casting. 2458 static inline ExternalUnsignedByteArray* cast(Object* obj); 2459 2460 #ifdef DEBUG 2461 void ExternalUnsignedByteArrayPrint(); 2462 void ExternalUnsignedByteArrayVerify(); 2463 #endif // DEBUG 2464 2465 private: 2466 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalUnsignedByteArray); 2467 }; 2468 2469 2470 class ExternalShortArray: public ExternalArray { 2471 public: 2472 // Setter and getter. 2473 inline int16_t get(int index); 2474 inline void set(int index, int16_t value); 2475 2476 // This accessor applies the correct conversion from Smi, HeapNumber 2477 // and undefined. 2478 Object* SetValue(uint32_t index, Object* value); 2479 2480 // Casting. 2481 static inline ExternalShortArray* cast(Object* obj); 2482 2483 #ifdef DEBUG 2484 void ExternalShortArrayPrint(); 2485 void ExternalShortArrayVerify(); 2486 #endif // DEBUG 2487 2488 private: 2489 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalShortArray); 2490 }; 2491 2492 2493 class ExternalUnsignedShortArray: public ExternalArray { 2494 public: 2495 // Setter and getter. 2496 inline uint16_t get(int index); 2497 inline void set(int index, uint16_t value); 2498 2499 // This accessor applies the correct conversion from Smi, HeapNumber 2500 // and undefined. 2501 Object* SetValue(uint32_t index, Object* value); 2502 2503 // Casting. 2504 static inline ExternalUnsignedShortArray* cast(Object* obj); 2505 2506 #ifdef DEBUG 2507 void ExternalUnsignedShortArrayPrint(); 2508 void ExternalUnsignedShortArrayVerify(); 2509 #endif // DEBUG 2510 2511 private: 2512 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalUnsignedShortArray); 2513 }; 2514 2515 2516 class ExternalIntArray: public ExternalArray { 2517 public: 2518 // Setter and getter. 2519 inline int32_t get(int index); 2520 inline void set(int index, int32_t value); 2521 2522 // This accessor applies the correct conversion from Smi, HeapNumber 2523 // and undefined. 2524 Object* SetValue(uint32_t index, Object* value); 2525 2526 // Casting. 2527 static inline ExternalIntArray* cast(Object* obj); 2528 2529 #ifdef DEBUG 2530 void ExternalIntArrayPrint(); 2531 void ExternalIntArrayVerify(); 2532 #endif // DEBUG 2533 2534 private: 2535 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalIntArray); 2536 }; 2537 2538 2539 class ExternalUnsignedIntArray: public ExternalArray { 2540 public: 2541 // Setter and getter. 2542 inline uint32_t get(int index); 2543 inline void set(int index, uint32_t value); 2544 2545 // This accessor applies the correct conversion from Smi, HeapNumber 2546 // and undefined. 2547 Object* SetValue(uint32_t index, Object* value); 2548 2549 // Casting. 2550 static inline ExternalUnsignedIntArray* cast(Object* obj); 2551 2552 #ifdef DEBUG 2553 void ExternalUnsignedIntArrayPrint(); 2554 void ExternalUnsignedIntArrayVerify(); 2555 #endif // DEBUG 2556 2557 private: 2558 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalUnsignedIntArray); 2559 }; 2560 2561 2562 class ExternalFloatArray: public ExternalArray { 2563 public: 2564 // Setter and getter. 2565 inline float get(int index); 2566 inline void set(int index, float value); 2567 2568 // This accessor applies the correct conversion from Smi, HeapNumber 2569 // and undefined. 2570 Object* SetValue(uint32_t index, Object* value); 2571 2572 // Casting. 2573 static inline ExternalFloatArray* cast(Object* obj); 2574 2575 #ifdef DEBUG 2576 void ExternalFloatArrayPrint(); 2577 void ExternalFloatArrayVerify(); 2578 #endif // DEBUG 2579 2580 private: 2581 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalFloatArray); 2582 }; 2583 2584 2585 // Code describes objects with on-the-fly generated machine code. 2586 class Code: public HeapObject { 2587 public: 2588 // Opaque data type for encapsulating code flags like kind, inline 2589 // cache state, and arguments count. 2590 enum Flags { }; 2591 2592 enum Kind { 2593 FUNCTION, 2594 STUB, 2595 BUILTIN, 2596 LOAD_IC, 2597 KEYED_LOAD_IC, 2598 CALL_IC, 2599 STORE_IC, 2600 KEYED_STORE_IC, 2601 // No more than eight kinds. The value currently encoded in three bits in 2602 // Flags. 2603 2604 // Pseudo-kinds. 2605 REGEXP = BUILTIN, 2606 FIRST_IC_KIND = LOAD_IC, 2607 LAST_IC_KIND = KEYED_STORE_IC 2608 }; 2609 2610 enum { 2611 NUMBER_OF_KINDS = KEYED_STORE_IC + 1 2612 }; 2613 2614 #ifdef ENABLE_DISASSEMBLER 2615 // Printing 2616 static const char* Kind2String(Kind kind); 2617 static const char* ICState2String(InlineCacheState state); 2618 static const char* PropertyType2String(PropertyType type); 2619 void Disassemble(const char* name); 2620 #endif // ENABLE_DISASSEMBLER 2621 2622 // [instruction_size]: Size of the native instructions 2623 inline int instruction_size(); 2624 inline void set_instruction_size(int value); 2625 2626 // [relocation_size]: Size of relocation information. 2627 inline int relocation_size(); 2628 inline void set_relocation_size(int value); 2629 2630 // [sinfo_size]: Size of scope information. 2631 inline int sinfo_size(); 2632 inline void set_sinfo_size(int value); 2633 2634 // [flags]: Various code flags. 2635 inline Flags flags(); 2636 inline void set_flags(Flags flags); 2637 2638 // [flags]: Access to specific code flags. 2639 inline Kind kind(); 2640 inline InlineCacheState ic_state(); // Only valid for IC stubs. 2641 inline InLoopFlag ic_in_loop(); // Only valid for IC stubs. 2642 inline PropertyType type(); // Only valid for monomorphic IC stubs. 2643 inline int arguments_count(); // Only valid for call IC stubs. 2644 2645 // Testers for IC stub kinds. 2646 inline bool is_inline_cache_stub(); is_load_stub()2647 inline bool is_load_stub() { return kind() == LOAD_IC; } is_keyed_load_stub()2648 inline bool is_keyed_load_stub() { return kind() == KEYED_LOAD_IC; } is_store_stub()2649 inline bool is_store_stub() { return kind() == STORE_IC; } is_keyed_store_stub()2650 inline bool is_keyed_store_stub() { return kind() == KEYED_STORE_IC; } is_call_stub()2651 inline bool is_call_stub() { return kind() == CALL_IC; } 2652 2653 // [major_key]: For kind STUB, the major key. 2654 inline CodeStub::Major major_key(); 2655 inline void set_major_key(CodeStub::Major major); 2656 2657 // Flags operations. 2658 static inline Flags ComputeFlags(Kind kind, 2659 InLoopFlag in_loop = NOT_IN_LOOP, 2660 InlineCacheState ic_state = UNINITIALIZED, 2661 PropertyType type = NORMAL, 2662 int argc = -1); 2663 2664 static inline Flags ComputeMonomorphicFlags( 2665 Kind kind, 2666 PropertyType type, 2667 InLoopFlag in_loop = NOT_IN_LOOP, 2668 int argc = -1); 2669 2670 static inline Kind ExtractKindFromFlags(Flags flags); 2671 static inline InlineCacheState ExtractICStateFromFlags(Flags flags); 2672 static inline InLoopFlag ExtractICInLoopFromFlags(Flags flags); 2673 static inline PropertyType ExtractTypeFromFlags(Flags flags); 2674 static inline int ExtractArgumentsCountFromFlags(Flags flags); 2675 static inline Flags RemoveTypeFromFlags(Flags flags); 2676 2677 // Convert a target address into a code object. 2678 static inline Code* GetCodeFromTargetAddress(Address address); 2679 2680 // Returns the address of the first instruction. 2681 inline byte* instruction_start(); 2682 2683 // Returns the size of the instructions, padding, and relocation information. 2684 inline int body_size(); 2685 2686 // Returns the address of the first relocation info (read backwards!). 2687 inline byte* relocation_start(); 2688 2689 // Code entry point. 2690 inline byte* entry(); 2691 2692 // Returns true if pc is inside this object's instructions. 2693 inline bool contains(byte* pc); 2694 2695 // Returns the address of the scope information. 2696 inline byte* sinfo_start(); 2697 2698 // Relocate the code by delta bytes. Called to signal that this code 2699 // object has been moved by delta bytes. 2700 void Relocate(intptr_t delta); 2701 2702 // Migrate code described by desc. 2703 void CopyFrom(const CodeDesc& desc); 2704 2705 // Returns the object size for a given body and sinfo size (Used for 2706 // allocation). SizeFor(int body_size,int sinfo_size)2707 static int SizeFor(int body_size, int sinfo_size) { 2708 ASSERT_SIZE_TAG_ALIGNED(body_size); 2709 ASSERT_SIZE_TAG_ALIGNED(sinfo_size); 2710 return RoundUp(kHeaderSize + body_size + sinfo_size, kCodeAlignment); 2711 } 2712 2713 // Calculate the size of the code object to report for log events. This takes 2714 // the layout of the code object into account. ExecutableSize()2715 int ExecutableSize() { 2716 // Check that the assumptions about the layout of the code object holds. 2717 ASSERT_EQ(static_cast<int>(instruction_start() - address()), 2718 Code::kHeaderSize); 2719 return instruction_size() + Code::kHeaderSize; 2720 } 2721 2722 // Locating source position. 2723 int SourcePosition(Address pc); 2724 int SourceStatementPosition(Address pc); 2725 2726 // Casting. 2727 static inline Code* cast(Object* obj); 2728 2729 // Dispatched behavior. CodeSize()2730 int CodeSize() { return SizeFor(body_size(), sinfo_size()); } 2731 void CodeIterateBody(ObjectVisitor* v); 2732 #ifdef DEBUG 2733 void CodePrint(); 2734 void CodeVerify(); 2735 #endif 2736 // Code entry points are aligned to 32 bytes. 2737 static const int kCodeAlignmentBits = 5; 2738 static const int kCodeAlignment = 1 << kCodeAlignmentBits; 2739 static const int kCodeAlignmentMask = kCodeAlignment - 1; 2740 2741 // Layout description. 2742 static const int kInstructionSizeOffset = HeapObject::kHeaderSize; 2743 static const int kRelocationSizeOffset = kInstructionSizeOffset + kIntSize; 2744 static const int kSInfoSizeOffset = kRelocationSizeOffset + kIntSize; 2745 static const int kFlagsOffset = kSInfoSizeOffset + kIntSize; 2746 static const int kKindSpecificFlagsOffset = kFlagsOffset + kIntSize; 2747 // Add padding to align the instruction start following right after 2748 // the Code object header. 2749 static const int kHeaderSize = 2750 (kKindSpecificFlagsOffset + kIntSize + kCodeAlignmentMask) & 2751 ~kCodeAlignmentMask; 2752 2753 // Byte offsets within kKindSpecificFlagsOffset. 2754 static const int kStubMajorKeyOffset = kKindSpecificFlagsOffset + 1; 2755 2756 // Flags layout. 2757 static const int kFlagsICStateShift = 0; 2758 static const int kFlagsICInLoopShift = 3; 2759 static const int kFlagsKindShift = 4; 2760 static const int kFlagsTypeShift = 7; 2761 static const int kFlagsArgumentsCountShift = 10; 2762 2763 static const int kFlagsICStateMask = 0x00000007; // 0000000111 2764 static const int kFlagsICInLoopMask = 0x00000008; // 0000001000 2765 static const int kFlagsKindMask = 0x00000070; // 0001110000 2766 static const int kFlagsTypeMask = 0x00000380; // 1110000000 2767 static const int kFlagsArgumentsCountMask = 0xFFFFFC00; 2768 2769 static const int kFlagsNotUsedInLookup = 2770 (kFlagsICInLoopMask | kFlagsTypeMask); 2771 2772 private: 2773 DISALLOW_IMPLICIT_CONSTRUCTORS(Code); 2774 }; 2775 2776 2777 // All heap objects have a Map that describes their structure. 2778 // A Map contains information about: 2779 // - Size information about the object 2780 // - How to iterate over an object (for garbage collection) 2781 class Map: public HeapObject { 2782 public: 2783 // Instance size. 2784 inline int instance_size(); 2785 inline void set_instance_size(int value); 2786 2787 // Count of properties allocated in the object. 2788 inline int inobject_properties(); 2789 inline void set_inobject_properties(int value); 2790 2791 // Count of property fields pre-allocated in the object when first allocated. 2792 inline int pre_allocated_property_fields(); 2793 inline void set_pre_allocated_property_fields(int value); 2794 2795 // Instance type. 2796 inline InstanceType instance_type(); 2797 inline void set_instance_type(InstanceType value); 2798 2799 // Tells how many unused property fields are available in the 2800 // instance (only used for JSObject in fast mode). 2801 inline int unused_property_fields(); 2802 inline void set_unused_property_fields(int value); 2803 2804 // Bit field. 2805 inline byte bit_field(); 2806 inline void set_bit_field(byte value); 2807 2808 // Bit field 2. 2809 inline byte bit_field2(); 2810 inline void set_bit_field2(byte value); 2811 2812 // Tells whether the object in the prototype property will be used 2813 // for instances created from this function. If the prototype 2814 // property is set to a value that is not a JSObject, the prototype 2815 // property will not be used to create instances of the function. 2816 // See ECMA-262, 13.2.2. 2817 inline void set_non_instance_prototype(bool value); 2818 inline bool has_non_instance_prototype(); 2819 2820 // Tells whether the instance with this map should be ignored by the 2821 // __proto__ accessor. set_is_hidden_prototype()2822 inline void set_is_hidden_prototype() { 2823 set_bit_field(bit_field() | (1 << kIsHiddenPrototype)); 2824 } 2825 is_hidden_prototype()2826 inline bool is_hidden_prototype() { 2827 return ((1 << kIsHiddenPrototype) & bit_field()) != 0; 2828 } 2829 2830 // Records and queries whether the instance has a named interceptor. set_has_named_interceptor()2831 inline void set_has_named_interceptor() { 2832 set_bit_field(bit_field() | (1 << kHasNamedInterceptor)); 2833 } 2834 has_named_interceptor()2835 inline bool has_named_interceptor() { 2836 return ((1 << kHasNamedInterceptor) & bit_field()) != 0; 2837 } 2838 2839 // Records and queries whether the instance has an indexed interceptor. set_has_indexed_interceptor()2840 inline void set_has_indexed_interceptor() { 2841 set_bit_field(bit_field() | (1 << kHasIndexedInterceptor)); 2842 } 2843 has_indexed_interceptor()2844 inline bool has_indexed_interceptor() { 2845 return ((1 << kHasIndexedInterceptor) & bit_field()) != 0; 2846 } 2847 2848 // Tells whether the instance is undetectable. 2849 // An undetectable object is a special class of JSObject: 'typeof' operator 2850 // returns undefined, ToBoolean returns false. Otherwise it behaves like 2851 // a normal JS object. It is useful for implementing undetectable 2852 // document.all in Firefox & Safari. 2853 // See https://bugzilla.mozilla.org/show_bug.cgi?id=248549. set_is_undetectable()2854 inline void set_is_undetectable() { 2855 set_bit_field(bit_field() | (1 << kIsUndetectable)); 2856 } 2857 is_undetectable()2858 inline bool is_undetectable() { 2859 return ((1 << kIsUndetectable) & bit_field()) != 0; 2860 } 2861 2862 // Tells whether the instance has a call-as-function handler. set_has_instance_call_handler()2863 inline void set_has_instance_call_handler() { 2864 set_bit_field(bit_field() | (1 << kHasInstanceCallHandler)); 2865 } 2866 has_instance_call_handler()2867 inline bool has_instance_call_handler() { 2868 return ((1 << kHasInstanceCallHandler) & bit_field()) != 0; 2869 } 2870 set_is_extensible()2871 inline void set_is_extensible() { 2872 set_bit_field2(bit_field2() | (1 << kIsExtensible)); 2873 } 2874 is_extensible()2875 inline bool is_extensible() { 2876 return ((1 << kIsExtensible) & bit_field2()) != 0; 2877 } 2878 2879 // Tells whether the instance needs security checks when accessing its 2880 // properties. 2881 inline void set_is_access_check_needed(bool access_check_needed); 2882 inline bool is_access_check_needed(); 2883 2884 // [prototype]: implicit prototype object. 2885 DECL_ACCESSORS(prototype, Object) 2886 2887 // [constructor]: points back to the function responsible for this map. 2888 DECL_ACCESSORS(constructor, Object) 2889 2890 // [instance descriptors]: describes the object. 2891 DECL_ACCESSORS(instance_descriptors, DescriptorArray) 2892 2893 // [stub cache]: contains stubs compiled for this map. 2894 DECL_ACCESSORS(code_cache, FixedArray) 2895 2896 Object* CopyDropDescriptors(); 2897 2898 // Returns a copy of the map, with all transitions dropped from the 2899 // instance descriptors. 2900 Object* CopyDropTransitions(); 2901 2902 // Returns the property index for name (only valid for FAST MODE). 2903 int PropertyIndexFor(String* name); 2904 2905 // Returns the next free property index (only valid for FAST MODE). 2906 int NextFreePropertyIndex(); 2907 2908 // Returns the number of properties described in instance_descriptors. 2909 int NumberOfDescribedProperties(); 2910 2911 // Casting. 2912 static inline Map* cast(Object* obj); 2913 2914 // Locate an accessor in the instance descriptor. 2915 AccessorDescriptor* FindAccessor(String* name); 2916 2917 // Code cache operations. 2918 2919 // Clears the code cache. 2920 inline void ClearCodeCache(); 2921 2922 // Update code cache. 2923 Object* UpdateCodeCache(String* name, Code* code); 2924 2925 // Returns the found code or undefined if absent. 2926 Object* FindInCodeCache(String* name, Code::Flags flags); 2927 2928 // Returns the non-negative index of the code object if it is in the 2929 // cache and -1 otherwise. 2930 int IndexInCodeCache(Code* code); 2931 2932 // Removes a code object from the code cache at the given index. 2933 void RemoveFromCodeCache(int index); 2934 2935 // For every transition in this map, makes the transition's 2936 // target's prototype pointer point back to this map. 2937 // This is undone in MarkCompactCollector::ClearNonLiveTransitions(). 2938 void CreateBackPointers(); 2939 2940 // Set all map transitions from this map to dead maps to null. 2941 // Also, restore the original prototype on the targets of these 2942 // transitions, so that we do not process this map again while 2943 // following back pointers. 2944 void ClearNonLiveTransitions(Object* real_prototype); 2945 2946 // Dispatched behavior. 2947 void MapIterateBody(ObjectVisitor* v); 2948 #ifdef DEBUG 2949 void MapPrint(); 2950 void MapVerify(); 2951 #endif 2952 2953 static const int kMaxPreAllocatedPropertyFields = 255; 2954 2955 // Layout description. 2956 static const int kInstanceSizesOffset = HeapObject::kHeaderSize; 2957 static const int kInstanceAttributesOffset = kInstanceSizesOffset + kIntSize; 2958 static const int kPrototypeOffset = kInstanceAttributesOffset + kIntSize; 2959 static const int kConstructorOffset = kPrototypeOffset + kPointerSize; 2960 static const int kInstanceDescriptorsOffset = 2961 kConstructorOffset + kPointerSize; 2962 static const int kCodeCacheOffset = kInstanceDescriptorsOffset + kPointerSize; 2963 static const int kPadStart = kCodeCacheOffset + kPointerSize; 2964 static const int kSize = MAP_SIZE_ALIGN(kPadStart); 2965 2966 // Byte offsets within kInstanceSizesOffset. 2967 static const int kInstanceSizeOffset = kInstanceSizesOffset + 0; 2968 static const int kInObjectPropertiesByte = 1; 2969 static const int kInObjectPropertiesOffset = 2970 kInstanceSizesOffset + kInObjectPropertiesByte; 2971 static const int kPreAllocatedPropertyFieldsByte = 2; 2972 static const int kPreAllocatedPropertyFieldsOffset = 2973 kInstanceSizesOffset + kPreAllocatedPropertyFieldsByte; 2974 // The byte at position 3 is not in use at the moment. 2975 2976 // Byte offsets within kInstanceAttributesOffset attributes. 2977 static const int kInstanceTypeOffset = kInstanceAttributesOffset + 0; 2978 static const int kUnusedPropertyFieldsOffset = kInstanceAttributesOffset + 1; 2979 static const int kBitFieldOffset = kInstanceAttributesOffset + 2; 2980 static const int kBitField2Offset = kInstanceAttributesOffset + 3; 2981 2982 STATIC_CHECK(kInstanceTypeOffset == Internals::kMapInstanceTypeOffset); 2983 2984 // Bit positions for bit field. 2985 static const int kUnused = 0; // To be used for marking recently used maps. 2986 static const int kHasNonInstancePrototype = 1; 2987 static const int kIsHiddenPrototype = 2; 2988 static const int kHasNamedInterceptor = 3; 2989 static const int kHasIndexedInterceptor = 4; 2990 static const int kIsUndetectable = 5; 2991 static const int kHasInstanceCallHandler = 6; 2992 static const int kIsAccessCheckNeeded = 7; 2993 2994 // Bit positions for bit field 2 2995 static const int kIsExtensible = 0; 2996 2997 private: 2998 DISALLOW_IMPLICIT_CONSTRUCTORS(Map); 2999 }; 3000 3001 3002 // An abstract superclass, a marker class really, for simple structure classes. 3003 // It doesn't carry much functionality but allows struct classes to me 3004 // identified in the type system. 3005 class Struct: public HeapObject { 3006 public: 3007 inline void InitializeBody(int object_size); 3008 static inline Struct* cast(Object* that); 3009 }; 3010 3011 3012 // Script describes a script which has been added to the VM. 3013 class Script: public Struct { 3014 public: 3015 // Script types. 3016 enum Type { 3017 TYPE_NATIVE = 0, 3018 TYPE_EXTENSION = 1, 3019 TYPE_NORMAL = 2 3020 }; 3021 3022 // Script compilation types. 3023 enum CompilationType { 3024 COMPILATION_TYPE_HOST = 0, 3025 COMPILATION_TYPE_EVAL = 1, 3026 COMPILATION_TYPE_JSON = 2 3027 }; 3028 3029 // [source]: the script source. 3030 DECL_ACCESSORS(source, Object) 3031 3032 // [name]: the script name. 3033 DECL_ACCESSORS(name, Object) 3034 3035 // [id]: the script id. 3036 DECL_ACCESSORS(id, Object) 3037 3038 // [line_offset]: script line offset in resource from where it was extracted. 3039 DECL_ACCESSORS(line_offset, Smi) 3040 3041 // [column_offset]: script column offset in resource from where it was 3042 // extracted. 3043 DECL_ACCESSORS(column_offset, Smi) 3044 3045 // [data]: additional data associated with this script. 3046 DECL_ACCESSORS(data, Object) 3047 3048 // [context_data]: context data for the context this script was compiled in. 3049 DECL_ACCESSORS(context_data, Object) 3050 3051 // [wrapper]: the wrapper cache. 3052 DECL_ACCESSORS(wrapper, Proxy) 3053 3054 // [type]: the script type. 3055 DECL_ACCESSORS(type, Smi) 3056 3057 // [compilation]: how the the script was compiled. 3058 DECL_ACCESSORS(compilation_type, Smi) 3059 3060 // [line_ends]: FixedArray of line ends positions. 3061 DECL_ACCESSORS(line_ends, Object) 3062 3063 // [eval_from_shared]: for eval scripts the shared funcion info for the 3064 // function from which eval was called. 3065 DECL_ACCESSORS(eval_from_shared, Object) 3066 3067 // [eval_from_instructions_offset]: the instruction offset in the code for the 3068 // function from which eval was called where eval was called. 3069 DECL_ACCESSORS(eval_from_instructions_offset, Smi) 3070 3071 static inline Script* cast(Object* obj); 3072 3073 // If script source is an external string, check that the underlying 3074 // resource is accessible. Otherwise, always return true. 3075 inline bool HasValidSource(); 3076 3077 #ifdef DEBUG 3078 void ScriptPrint(); 3079 void ScriptVerify(); 3080 #endif 3081 3082 static const int kSourceOffset = HeapObject::kHeaderSize; 3083 static const int kNameOffset = kSourceOffset + kPointerSize; 3084 static const int kLineOffsetOffset = kNameOffset + kPointerSize; 3085 static const int kColumnOffsetOffset = kLineOffsetOffset + kPointerSize; 3086 static const int kDataOffset = kColumnOffsetOffset + kPointerSize; 3087 static const int kContextOffset = kDataOffset + kPointerSize; 3088 static const int kWrapperOffset = kContextOffset + kPointerSize; 3089 static const int kTypeOffset = kWrapperOffset + kPointerSize; 3090 static const int kCompilationTypeOffset = kTypeOffset + kPointerSize; 3091 static const int kLineEndsOffset = kCompilationTypeOffset + kPointerSize; 3092 static const int kIdOffset = kLineEndsOffset + kPointerSize; 3093 static const int kEvalFromSharedOffset = kIdOffset + kPointerSize; 3094 static const int kEvalFrominstructionsOffsetOffset = 3095 kEvalFromSharedOffset + kPointerSize; 3096 static const int kSize = kEvalFrominstructionsOffsetOffset + kPointerSize; 3097 3098 private: 3099 DISALLOW_IMPLICIT_CONSTRUCTORS(Script); 3100 }; 3101 3102 3103 // SharedFunctionInfo describes the JSFunction information that can be 3104 // shared by multiple instances of the function. 3105 class SharedFunctionInfo: public HeapObject { 3106 public: 3107 // [name]: Function name. 3108 DECL_ACCESSORS(name, Object) 3109 3110 // [code]: Function code. 3111 DECL_ACCESSORS(code, Code) 3112 3113 // [construct stub]: Code stub for constructing instances of this function. 3114 DECL_ACCESSORS(construct_stub, Code) 3115 3116 // Returns if this function has been compiled to native code yet. 3117 inline bool is_compiled(); 3118 3119 // [length]: The function length - usually the number of declared parameters. 3120 // Use up to 2^30 parameters. 3121 inline int length(); 3122 inline void set_length(int value); 3123 3124 // [formal parameter count]: The declared number of parameters. 3125 inline int formal_parameter_count(); 3126 inline void set_formal_parameter_count(int value); 3127 3128 // Set the formal parameter count so the function code will be 3129 // called without using argument adaptor frames. 3130 inline void DontAdaptArguments(); 3131 3132 // [expected_nof_properties]: Expected number of properties for the function. 3133 inline int expected_nof_properties(); 3134 inline void set_expected_nof_properties(int value); 3135 3136 // [instance class name]: class name for instances. 3137 DECL_ACCESSORS(instance_class_name, Object) 3138 3139 // [function data]: This field has been added for make benefit the API. 3140 // In the long run we don't want all functions to have this field but 3141 // we can fix that when we have a better model for storing hidden data 3142 // on objects. 3143 DECL_ACCESSORS(function_data, Object) 3144 3145 // [script info]: Script from which the function originates. 3146 DECL_ACCESSORS(script, Object) 3147 3148 // [start_position_and_type]: Field used to store both the source code 3149 // position, whether or not the function is a function expression, 3150 // and whether or not the function is a toplevel function. The two 3151 // least significants bit indicates whether the function is an 3152 // expression and the rest contains the source code position. 3153 inline int start_position_and_type(); 3154 inline void set_start_position_and_type(int value); 3155 3156 // [debug info]: Debug information. 3157 DECL_ACCESSORS(debug_info, Object) 3158 3159 // [inferred name]: Name inferred from variable or property 3160 // assignment of this function. Used to facilitate debugging and 3161 // profiling of JavaScript code written in OO style, where almost 3162 // all functions are anonymous but are assigned to object 3163 // properties. 3164 DECL_ACCESSORS(inferred_name, String) 3165 3166 // Position of the 'function' token in the script source. 3167 inline int function_token_position(); 3168 inline void set_function_token_position(int function_token_position); 3169 3170 // Position of this function in the script source. 3171 inline int start_position(); 3172 inline void set_start_position(int start_position); 3173 3174 // End position of this function in the script source. 3175 inline int end_position(); 3176 inline void set_end_position(int end_position); 3177 3178 // Is this function a function expression in the source code. 3179 inline bool is_expression(); 3180 inline void set_is_expression(bool value); 3181 3182 // Is this function a top-level function (scripts, evals). 3183 inline bool is_toplevel(); 3184 inline void set_is_toplevel(bool value); 3185 3186 // Bit field containing various information collected by the compiler to 3187 // drive optimization. 3188 inline int compiler_hints(); 3189 inline void set_compiler_hints(int value); 3190 3191 // Add information on assignments of the form this.x = ...; 3192 void SetThisPropertyAssignmentsInfo( 3193 bool has_only_simple_this_property_assignments, 3194 FixedArray* this_property_assignments); 3195 3196 // Clear information on assignments of the form this.x = ...; 3197 void ClearThisPropertyAssignmentsInfo(); 3198 3199 // Indicate that this function only consists of assignments of the form 3200 // this.x = y; where y is either a constant or refers to an argument. 3201 inline bool has_only_simple_this_property_assignments(); 3202 3203 inline bool try_full_codegen(); 3204 inline void set_try_full_codegen(bool flag); 3205 3206 // Check whether a inlined constructor can be generated with the given 3207 // prototype. 3208 bool CanGenerateInlineConstructor(Object* prototype); 3209 3210 // For functions which only contains this property assignments this provides 3211 // access to the names for the properties assigned. 3212 DECL_ACCESSORS(this_property_assignments, Object) 3213 inline int this_property_assignments_count(); 3214 inline void set_this_property_assignments_count(int value); 3215 String* GetThisPropertyAssignmentName(int index); 3216 bool IsThisPropertyAssignmentArgument(int index); 3217 int GetThisPropertyAssignmentArgument(int index); 3218 Object* GetThisPropertyAssignmentConstant(int index); 3219 3220 // [source code]: Source code for the function. 3221 bool HasSourceCode(); 3222 Object* GetSourceCode(); 3223 3224 // Calculate the instance size. 3225 int CalculateInstanceSize(); 3226 3227 // Calculate the number of in-object properties. 3228 int CalculateInObjectProperties(); 3229 3230 // Dispatched behavior. 3231 void SharedFunctionInfoIterateBody(ObjectVisitor* v); 3232 // Set max_length to -1 for unlimited length. 3233 void SourceCodePrint(StringStream* accumulator, int max_length); 3234 #ifdef DEBUG 3235 void SharedFunctionInfoPrint(); 3236 void SharedFunctionInfoVerify(); 3237 #endif 3238 3239 // Casting. 3240 static inline SharedFunctionInfo* cast(Object* obj); 3241 3242 // Constants. 3243 static const int kDontAdaptArgumentsSentinel = -1; 3244 3245 // Layout description. 3246 // (An even number of integers has a size that is a multiple of a pointer.) 3247 static const int kNameOffset = HeapObject::kHeaderSize; 3248 static const int kCodeOffset = kNameOffset + kPointerSize; 3249 static const int kConstructStubOffset = kCodeOffset + kPointerSize; 3250 static const int kLengthOffset = kConstructStubOffset + kPointerSize; 3251 static const int kFormalParameterCountOffset = kLengthOffset + kIntSize; 3252 static const int kExpectedNofPropertiesOffset = 3253 kFormalParameterCountOffset + kIntSize; 3254 static const int kStartPositionAndTypeOffset = 3255 kExpectedNofPropertiesOffset + kIntSize; 3256 static const int kEndPositionOffset = kStartPositionAndTypeOffset + kIntSize; 3257 static const int kFunctionTokenPositionOffset = kEndPositionOffset + kIntSize; 3258 static const int kInstanceClassNameOffset = 3259 kFunctionTokenPositionOffset + kIntSize; 3260 static const int kExternalReferenceDataOffset = 3261 kInstanceClassNameOffset + kPointerSize; 3262 static const int kScriptOffset = kExternalReferenceDataOffset + kPointerSize; 3263 static const int kDebugInfoOffset = kScriptOffset + kPointerSize; 3264 static const int kInferredNameOffset = kDebugInfoOffset + kPointerSize; 3265 static const int kCompilerHintsOffset = kInferredNameOffset + kPointerSize; 3266 static const int kThisPropertyAssignmentsOffset = 3267 kCompilerHintsOffset + kPointerSize; 3268 static const int kThisPropertyAssignmentsCountOffset = 3269 kThisPropertyAssignmentsOffset + kPointerSize; 3270 static const int kSize = kThisPropertyAssignmentsCountOffset + kPointerSize; 3271 3272 private: 3273 // Bit positions in length_and_flg. 3274 // The least significant bit is used as the flag. 3275 static const int kFlagBit = 0; 3276 static const int kLengthShift = 1; 3277 static const int kLengthMask = ~((1 << kLengthShift) - 1); 3278 3279 // Bit positions in start_position_and_type. 3280 // The source code start position is in the 30 most significant bits of 3281 // the start_position_and_type field. 3282 static const int kIsExpressionBit = 0; 3283 static const int kIsTopLevelBit = 1; 3284 static const int kStartPositionShift = 2; 3285 static const int kStartPositionMask = ~((1 << kStartPositionShift) - 1); 3286 3287 // Bit positions in compiler_hints. 3288 static const int kHasOnlySimpleThisPropertyAssignments = 0; 3289 static const int kTryFullCodegen = 1; 3290 3291 DISALLOW_IMPLICIT_CONSTRUCTORS(SharedFunctionInfo); 3292 }; 3293 3294 3295 // JSFunction describes JavaScript functions. 3296 class JSFunction: public JSObject { 3297 public: 3298 // [prototype_or_initial_map]: 3299 DECL_ACCESSORS(prototype_or_initial_map, Object) 3300 3301 // [shared_function_info]: The information about the function that 3302 // can be shared by instances. 3303 DECL_ACCESSORS(shared, SharedFunctionInfo) 3304 3305 // [context]: The context for this function. 3306 inline Context* context(); 3307 inline Object* unchecked_context(); 3308 inline void set_context(Object* context); 3309 3310 // [code]: The generated code object for this function. Executed 3311 // when the function is invoked, e.g. foo() or new foo(). See 3312 // [[Call]] and [[Construct]] description in ECMA-262, section 3313 // 8.6.2, page 27. 3314 inline Code* code(); 3315 inline void set_code(Code* value); 3316 3317 // Tells whether this function is a context-independent boilerplate 3318 // function. 3319 inline bool IsBoilerplate(); 3320 3321 // Tells whether this function is builtin. 3322 inline bool IsBuiltin(); 3323 3324 // [literals]: Fixed array holding the materialized literals. 3325 // 3326 // If the function contains object, regexp or array literals, the 3327 // literals array prefix contains the object, regexp, and array 3328 // function to be used when creating these literals. This is 3329 // necessary so that we do not dynamically lookup the object, regexp 3330 // or array functions. Performing a dynamic lookup, we might end up 3331 // using the functions from a new context that we should not have 3332 // access to. 3333 DECL_ACCESSORS(literals, FixedArray) 3334 3335 // The initial map for an object created by this constructor. 3336 inline Map* initial_map(); 3337 inline void set_initial_map(Map* value); 3338 inline bool has_initial_map(); 3339 3340 // Get and set the prototype property on a JSFunction. If the 3341 // function has an initial map the prototype is set on the initial 3342 // map. Otherwise, the prototype is put in the initial map field 3343 // until an initial map is needed. 3344 inline bool has_prototype(); 3345 inline bool has_instance_prototype(); 3346 inline Object* prototype(); 3347 inline Object* instance_prototype(); 3348 Object* SetInstancePrototype(Object* value); 3349 Object* SetPrototype(Object* value); 3350 3351 // Accessor for this function's initial map's [[class]] 3352 // property. This is primarily used by ECMA native functions. This 3353 // method sets the class_name field of this function's initial map 3354 // to a given value. It creates an initial map if this function does 3355 // not have one. Note that this method does not copy the initial map 3356 // if it has one already, but simply replaces it with the new value. 3357 // Instances created afterwards will have a map whose [[class]] is 3358 // set to 'value', but there is no guarantees on instances created 3359 // before. 3360 Object* SetInstanceClassName(String* name); 3361 3362 // Returns if this function has been compiled to native code yet. 3363 inline bool is_compiled(); 3364 3365 // Casting. 3366 static inline JSFunction* cast(Object* obj); 3367 3368 // Dispatched behavior. 3369 #ifdef DEBUG 3370 void JSFunctionPrint(); 3371 void JSFunctionVerify(); 3372 #endif 3373 3374 // Returns the number of allocated literals. 3375 inline int NumberOfLiterals(); 3376 3377 // Retrieve the global context from a function's literal array. 3378 static Context* GlobalContextFromLiterals(FixedArray* literals); 3379 3380 // Layout descriptors. 3381 static const int kPrototypeOrInitialMapOffset = JSObject::kHeaderSize; 3382 static const int kSharedFunctionInfoOffset = 3383 kPrototypeOrInitialMapOffset + kPointerSize; 3384 static const int kContextOffset = kSharedFunctionInfoOffset + kPointerSize; 3385 static const int kLiteralsOffset = kContextOffset + kPointerSize; 3386 static const int kSize = kLiteralsOffset + kPointerSize; 3387 3388 // Layout of the literals array. 3389 static const int kLiteralsPrefixSize = 1; 3390 static const int kLiteralGlobalContextIndex = 0; 3391 private: 3392 DISALLOW_IMPLICIT_CONSTRUCTORS(JSFunction); 3393 }; 3394 3395 3396 // JSGlobalProxy's prototype must be a JSGlobalObject or null, 3397 // and the prototype is hidden. JSGlobalProxy always delegates 3398 // property accesses to its prototype if the prototype is not null. 3399 // 3400 // A JSGlobalProxy can be reinitialized which will preserve its identity. 3401 // 3402 // Accessing a JSGlobalProxy requires security check. 3403 3404 class JSGlobalProxy : public JSObject { 3405 public: 3406 // [context]: the owner global context of this proxy object. 3407 // It is null value if this object is not used by any context. 3408 DECL_ACCESSORS(context, Object) 3409 3410 // Casting. 3411 static inline JSGlobalProxy* cast(Object* obj); 3412 3413 // Dispatched behavior. 3414 #ifdef DEBUG 3415 void JSGlobalProxyPrint(); 3416 void JSGlobalProxyVerify(); 3417 #endif 3418 3419 // Layout description. 3420 static const int kContextOffset = JSObject::kHeaderSize; 3421 static const int kSize = kContextOffset + kPointerSize; 3422 3423 private: 3424 3425 DISALLOW_IMPLICIT_CONSTRUCTORS(JSGlobalProxy); 3426 }; 3427 3428 3429 // Forward declaration. 3430 class JSBuiltinsObject; 3431 3432 // Common super class for JavaScript global objects and the special 3433 // builtins global objects. 3434 class GlobalObject: public JSObject { 3435 public: 3436 // [builtins]: the object holding the runtime routines written in JS. 3437 DECL_ACCESSORS(builtins, JSBuiltinsObject) 3438 3439 // [global context]: the global context corresponding to this global object. 3440 DECL_ACCESSORS(global_context, Context) 3441 3442 // [global receiver]: the global receiver object of the context 3443 DECL_ACCESSORS(global_receiver, JSObject) 3444 3445 // Retrieve the property cell used to store a property. 3446 Object* GetPropertyCell(LookupResult* result); 3447 3448 // Ensure that the global object has a cell for the given property name. 3449 Object* EnsurePropertyCell(String* name); 3450 3451 // Casting. 3452 static inline GlobalObject* cast(Object* obj); 3453 3454 // Layout description. 3455 static const int kBuiltinsOffset = JSObject::kHeaderSize; 3456 static const int kGlobalContextOffset = kBuiltinsOffset + kPointerSize; 3457 static const int kGlobalReceiverOffset = kGlobalContextOffset + kPointerSize; 3458 static const int kHeaderSize = kGlobalReceiverOffset + kPointerSize; 3459 3460 private: 3461 friend class AGCCVersionRequiresThisClassToHaveAFriendSoHereItIs; 3462 3463 DISALLOW_IMPLICIT_CONSTRUCTORS(GlobalObject); 3464 }; 3465 3466 3467 // JavaScript global object. 3468 class JSGlobalObject: public GlobalObject { 3469 public: 3470 3471 // Casting. 3472 static inline JSGlobalObject* cast(Object* obj); 3473 3474 // Dispatched behavior. 3475 #ifdef DEBUG 3476 void JSGlobalObjectPrint(); 3477 void JSGlobalObjectVerify(); 3478 #endif 3479 3480 // Layout description. 3481 static const int kSize = GlobalObject::kHeaderSize; 3482 3483 private: 3484 DISALLOW_IMPLICIT_CONSTRUCTORS(JSGlobalObject); 3485 }; 3486 3487 3488 // Builtins global object which holds the runtime routines written in 3489 // JavaScript. 3490 class JSBuiltinsObject: public GlobalObject { 3491 public: 3492 // Accessors for the runtime routines written in JavaScript. 3493 inline Object* javascript_builtin(Builtins::JavaScript id); 3494 inline void set_javascript_builtin(Builtins::JavaScript id, Object* value); 3495 3496 // Casting. 3497 static inline JSBuiltinsObject* cast(Object* obj); 3498 3499 // Dispatched behavior. 3500 #ifdef DEBUG 3501 void JSBuiltinsObjectPrint(); 3502 void JSBuiltinsObjectVerify(); 3503 #endif 3504 3505 // Layout description. The size of the builtins object includes 3506 // room for one pointer per runtime routine written in javascript. 3507 static const int kJSBuiltinsCount = Builtins::id_count; 3508 static const int kJSBuiltinsOffset = GlobalObject::kHeaderSize; 3509 static const int kSize = 3510 kJSBuiltinsOffset + (kJSBuiltinsCount * kPointerSize); 3511 private: 3512 DISALLOW_IMPLICIT_CONSTRUCTORS(JSBuiltinsObject); 3513 }; 3514 3515 3516 // Representation for JS Wrapper objects, String, Number, Boolean, Date, etc. 3517 class JSValue: public JSObject { 3518 public: 3519 // [value]: the object being wrapped. 3520 DECL_ACCESSORS(value, Object) 3521 3522 // Casting. 3523 static inline JSValue* cast(Object* obj); 3524 3525 // Dispatched behavior. 3526 #ifdef DEBUG 3527 void JSValuePrint(); 3528 void JSValueVerify(); 3529 #endif 3530 3531 // Layout description. 3532 static const int kValueOffset = JSObject::kHeaderSize; 3533 static const int kSize = kValueOffset + kPointerSize; 3534 3535 private: 3536 DISALLOW_IMPLICIT_CONSTRUCTORS(JSValue); 3537 }; 3538 3539 // Regular expressions 3540 // The regular expression holds a single reference to a FixedArray in 3541 // the kDataOffset field. 3542 // The FixedArray contains the following data: 3543 // - tag : type of regexp implementation (not compiled yet, atom or irregexp) 3544 // - reference to the original source string 3545 // - reference to the original flag string 3546 // If it is an atom regexp 3547 // - a reference to a literal string to search for 3548 // If it is an irregexp regexp: 3549 // - a reference to code for ASCII inputs (bytecode or compiled). 3550 // - a reference to code for UC16 inputs (bytecode or compiled). 3551 // - max number of registers used by irregexp implementations. 3552 // - number of capture registers (output values) of the regexp. 3553 class JSRegExp: public JSObject { 3554 public: 3555 // Meaning of Type: 3556 // NOT_COMPILED: Initial value. No data has been stored in the JSRegExp yet. 3557 // ATOM: A simple string to match against using an indexOf operation. 3558 // IRREGEXP: Compiled with Irregexp. 3559 // IRREGEXP_NATIVE: Compiled to native code with Irregexp. 3560 enum Type { NOT_COMPILED, ATOM, IRREGEXP }; 3561 enum Flag { NONE = 0, GLOBAL = 1, IGNORE_CASE = 2, MULTILINE = 4 }; 3562 3563 class Flags { 3564 public: Flags(uint32_t value)3565 explicit Flags(uint32_t value) : value_(value) { } is_global()3566 bool is_global() { return (value_ & GLOBAL) != 0; } is_ignore_case()3567 bool is_ignore_case() { return (value_ & IGNORE_CASE) != 0; } is_multiline()3568 bool is_multiline() { return (value_ & MULTILINE) != 0; } value()3569 uint32_t value() { return value_; } 3570 private: 3571 uint32_t value_; 3572 }; 3573 3574 DECL_ACCESSORS(data, Object) 3575 3576 inline Type TypeTag(); 3577 inline int CaptureCount(); 3578 inline Flags GetFlags(); 3579 inline String* Pattern(); 3580 inline Object* DataAt(int index); 3581 // Set implementation data after the object has been prepared. 3582 inline void SetDataAt(int index, Object* value); code_index(bool is_ascii)3583 static int code_index(bool is_ascii) { 3584 if (is_ascii) { 3585 return kIrregexpASCIICodeIndex; 3586 } else { 3587 return kIrregexpUC16CodeIndex; 3588 } 3589 } 3590 3591 static inline JSRegExp* cast(Object* obj); 3592 3593 // Dispatched behavior. 3594 #ifdef DEBUG 3595 void JSRegExpVerify(); 3596 #endif 3597 3598 static const int kDataOffset = JSObject::kHeaderSize; 3599 static const int kSize = kDataOffset + kPointerSize; 3600 3601 // Indices in the data array. 3602 static const int kTagIndex = 0; 3603 static const int kSourceIndex = kTagIndex + 1; 3604 static const int kFlagsIndex = kSourceIndex + 1; 3605 static const int kDataIndex = kFlagsIndex + 1; 3606 // The data fields are used in different ways depending on the 3607 // value of the tag. 3608 // Atom regexps (literal strings). 3609 static const int kAtomPatternIndex = kDataIndex; 3610 3611 static const int kAtomDataSize = kAtomPatternIndex + 1; 3612 3613 // Irregexp compiled code or bytecode for ASCII. If compilation 3614 // fails, this fields hold an exception object that should be 3615 // thrown if the regexp is used again. 3616 static const int kIrregexpASCIICodeIndex = kDataIndex; 3617 // Irregexp compiled code or bytecode for UC16. If compilation 3618 // fails, this fields hold an exception object that should be 3619 // thrown if the regexp is used again. 3620 static const int kIrregexpUC16CodeIndex = kDataIndex + 1; 3621 // Maximal number of registers used by either ASCII or UC16. 3622 // Only used to check that there is enough stack space 3623 static const int kIrregexpMaxRegisterCountIndex = kDataIndex + 2; 3624 // Number of captures in the compiled regexp. 3625 static const int kIrregexpCaptureCountIndex = kDataIndex + 3; 3626 3627 static const int kIrregexpDataSize = kIrregexpCaptureCountIndex + 1; 3628 3629 // Offsets directly into the data fixed array. 3630 static const int kDataTagOffset = 3631 FixedArray::kHeaderSize + kTagIndex * kPointerSize; 3632 static const int kDataAsciiCodeOffset = 3633 FixedArray::kHeaderSize + kIrregexpASCIICodeIndex * kPointerSize; 3634 static const int kDataUC16CodeOffset = 3635 FixedArray::kHeaderSize + kIrregexpUC16CodeIndex * kPointerSize; 3636 static const int kIrregexpCaptureCountOffset = 3637 FixedArray::kHeaderSize + kIrregexpCaptureCountIndex * kPointerSize; 3638 }; 3639 3640 3641 class CompilationCacheShape { 3642 public: IsMatch(HashTableKey * key,Object * value)3643 static inline bool IsMatch(HashTableKey* key, Object* value) { 3644 return key->IsMatch(value); 3645 } 3646 Hash(HashTableKey * key)3647 static inline uint32_t Hash(HashTableKey* key) { 3648 return key->Hash(); 3649 } 3650 HashForObject(HashTableKey * key,Object * object)3651 static inline uint32_t HashForObject(HashTableKey* key, Object* object) { 3652 return key->HashForObject(object); 3653 } 3654 AsObject(HashTableKey * key)3655 static Object* AsObject(HashTableKey* key) { 3656 return key->AsObject(); 3657 } 3658 3659 static const int kPrefixSize = 0; 3660 static const int kEntrySize = 2; 3661 }; 3662 3663 3664 class CompilationCacheTable: public HashTable<CompilationCacheShape, 3665 HashTableKey*> { 3666 public: 3667 // Find cached value for a string key, otherwise return null. 3668 Object* Lookup(String* src); 3669 Object* LookupEval(String* src, Context* context); 3670 Object* LookupRegExp(String* source, JSRegExp::Flags flags); 3671 Object* Put(String* src, Object* value); 3672 Object* PutEval(String* src, Context* context, Object* value); 3673 Object* PutRegExp(String* src, JSRegExp::Flags flags, FixedArray* value); 3674 3675 static inline CompilationCacheTable* cast(Object* obj); 3676 3677 private: 3678 DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationCacheTable); 3679 }; 3680 3681 3682 enum AllowNullsFlag {ALLOW_NULLS, DISALLOW_NULLS}; 3683 enum RobustnessFlag {ROBUST_STRING_TRAVERSAL, FAST_STRING_TRAVERSAL}; 3684 3685 3686 class StringHasher { 3687 public: 3688 inline StringHasher(int length); 3689 3690 // Returns true if the hash of this string can be computed without 3691 // looking at the contents. 3692 inline bool has_trivial_hash(); 3693 3694 // Add a character to the hash and update the array index calculation. 3695 inline void AddCharacter(uc32 c); 3696 3697 // Adds a character to the hash but does not update the array index 3698 // calculation. This can only be called when it has been verified 3699 // that the input is not an array index. 3700 inline void AddCharacterNoIndex(uc32 c); 3701 3702 // Returns the value to store in the hash field of a string with 3703 // the given length and contents. 3704 uint32_t GetHashField(); 3705 3706 // Returns true if the characters seen so far make up a legal array 3707 // index. is_array_index()3708 bool is_array_index() { return is_array_index_; } 3709 is_valid()3710 bool is_valid() { return is_valid_; } 3711 invalidate()3712 void invalidate() { is_valid_ = false; } 3713 3714 private: 3715 array_index()3716 uint32_t array_index() { 3717 ASSERT(is_array_index()); 3718 return array_index_; 3719 } 3720 3721 inline uint32_t GetHash(); 3722 3723 int length_; 3724 uint32_t raw_running_hash_; 3725 uint32_t array_index_; 3726 bool is_array_index_; 3727 bool is_first_char_; 3728 bool is_valid_; 3729 friend class TwoCharHashTableKey; 3730 }; 3731 3732 3733 // The characteristics of a string are stored in its map. Retrieving these 3734 // few bits of information is moderately expensive, involving two memory 3735 // loads where the second is dependent on the first. To improve efficiency 3736 // the shape of the string is given its own class so that it can be retrieved 3737 // once and used for several string operations. A StringShape is small enough 3738 // to be passed by value and is immutable, but be aware that flattening a 3739 // string can potentially alter its shape. Also be aware that a GC caused by 3740 // something else can alter the shape of a string due to ConsString 3741 // shortcutting. Keeping these restrictions in mind has proven to be error- 3742 // prone and so we no longer put StringShapes in variables unless there is a 3743 // concrete performance benefit at that particular point in the code. 3744 class StringShape BASE_EMBEDDED { 3745 public: 3746 inline explicit StringShape(String* s); 3747 inline explicit StringShape(Map* s); 3748 inline explicit StringShape(InstanceType t); 3749 inline bool IsSequential(); 3750 inline bool IsExternal(); 3751 inline bool IsCons(); 3752 inline bool IsExternalAscii(); 3753 inline bool IsExternalTwoByte(); 3754 inline bool IsSequentialAscii(); 3755 inline bool IsSequentialTwoByte(); 3756 inline bool IsSymbol(); 3757 inline StringRepresentationTag representation_tag(); 3758 inline uint32_t full_representation_tag(); 3759 inline uint32_t size_tag(); 3760 #ifdef DEBUG type()3761 inline uint32_t type() { return type_; } invalidate()3762 inline void invalidate() { valid_ = false; } valid()3763 inline bool valid() { return valid_; } 3764 #else invalidate()3765 inline void invalidate() { } 3766 #endif 3767 private: 3768 uint32_t type_; 3769 #ifdef DEBUG set_valid()3770 inline void set_valid() { valid_ = true; } 3771 bool valid_; 3772 #else set_valid()3773 inline void set_valid() { } 3774 #endif 3775 }; 3776 3777 3778 // The String abstract class captures JavaScript string values: 3779 // 3780 // Ecma-262: 3781 // 4.3.16 String Value 3782 // A string value is a member of the type String and is a finite 3783 // ordered sequence of zero or more 16-bit unsigned integer values. 3784 // 3785 // All string values have a length field. 3786 class String: public HeapObject { 3787 public: 3788 // Get and set the length of the string. 3789 inline int length(); 3790 inline void set_length(int value); 3791 3792 // Get and set the hash field of the string. 3793 inline uint32_t hash_field(); 3794 inline void set_hash_field(uint32_t value); 3795 3796 inline bool IsAsciiRepresentation(); 3797 inline bool IsTwoByteRepresentation(); 3798 3799 // Get and set individual two byte chars in the string. 3800 inline void Set(int index, uint16_t value); 3801 // Get individual two byte char in the string. Repeated calls 3802 // to this method are not efficient unless the string is flat. 3803 inline uint16_t Get(int index); 3804 3805 // Try to flatten the top level ConsString that is hiding behind this 3806 // string. This is a no-op unless the string is a ConsString. Flatten 3807 // mutates the ConsString and might return a failure. 3808 Object* TryFlatten(); 3809 3810 // Try to flatten the string. Checks first inline to see if it is necessary. 3811 // Do not handle allocation failures. After calling TryFlattenIfNotFlat, the 3812 // string could still be a ConsString, in which case a failure is returned. 3813 // Use FlattenString from Handles.cc to be sure to flatten. 3814 inline Object* TryFlattenIfNotFlat(); 3815 3816 Vector<const char> ToAsciiVector(); 3817 Vector<const uc16> ToUC16Vector(); 3818 3819 // Mark the string as an undetectable object. It only applies to 3820 // ascii and two byte string types. 3821 bool MarkAsUndetectable(); 3822 3823 // Return a substring. 3824 Object* SubString(int from, int to); 3825 3826 // String equality operations. 3827 inline bool Equals(String* other); 3828 bool IsEqualTo(Vector<const char> str); 3829 3830 // Return a UTF8 representation of the string. The string is null 3831 // terminated but may optionally contain nulls. Length is returned 3832 // in length_output if length_output is not a null pointer The string 3833 // should be nearly flat, otherwise the performance of this method may 3834 // be very slow (quadratic in the length). Setting robustness_flag to 3835 // ROBUST_STRING_TRAVERSAL invokes behaviour that is robust This means it 3836 // handles unexpected data without causing assert failures and it does not 3837 // do any heap allocations. This is useful when printing stack traces. 3838 SmartPointer<char> ToCString(AllowNullsFlag allow_nulls, 3839 RobustnessFlag robustness_flag, 3840 int offset, 3841 int length, 3842 int* length_output = 0); 3843 SmartPointer<char> ToCString( 3844 AllowNullsFlag allow_nulls = DISALLOW_NULLS, 3845 RobustnessFlag robustness_flag = FAST_STRING_TRAVERSAL, 3846 int* length_output = 0); 3847 3848 int Utf8Length(); 3849 3850 // Return a 16 bit Unicode representation of the string. 3851 // The string should be nearly flat, otherwise the performance of 3852 // of this method may be very bad. Setting robustness_flag to 3853 // ROBUST_STRING_TRAVERSAL invokes behaviour that is robust This means it 3854 // handles unexpected data without causing assert failures and it does not 3855 // do any heap allocations. This is useful when printing stack traces. 3856 SmartPointer<uc16> ToWideCString( 3857 RobustnessFlag robustness_flag = FAST_STRING_TRAVERSAL); 3858 3859 // Tells whether the hash code has been computed. 3860 inline bool HasHashCode(); 3861 3862 // Returns a hash value used for the property table 3863 inline uint32_t Hash(); 3864 3865 static uint32_t ComputeHashField(unibrow::CharacterStream* buffer, 3866 int length); 3867 3868 static bool ComputeArrayIndex(unibrow::CharacterStream* buffer, 3869 uint32_t* index, 3870 int length); 3871 3872 // Externalization. 3873 bool MakeExternal(v8::String::ExternalStringResource* resource); 3874 bool MakeExternal(v8::String::ExternalAsciiStringResource* resource); 3875 3876 // Conversion. 3877 inline bool AsArrayIndex(uint32_t* index); 3878 3879 // Casting. 3880 static inline String* cast(Object* obj); 3881 3882 void PrintOn(FILE* out); 3883 3884 // For use during stack traces. Performs rudimentary sanity check. 3885 bool LooksValid(); 3886 3887 // Dispatched behavior. 3888 void StringShortPrint(StringStream* accumulator); 3889 #ifdef DEBUG 3890 void StringPrint(); 3891 void StringVerify(); 3892 #endif 3893 inline bool IsFlat(); 3894 3895 // Layout description. 3896 static const int kLengthOffset = HeapObject::kHeaderSize; 3897 static const int kHashFieldOffset = kLengthOffset + kIntSize; 3898 static const int kSize = kHashFieldOffset + kIntSize; 3899 // Notice: kSize is not pointer-size aligned if pointers are 64-bit. 3900 3901 // Maximum number of characters to consider when trying to convert a string 3902 // value into an array index. 3903 static const int kMaxArrayIndexSize = 10; 3904 3905 // Max ascii char code. 3906 static const int kMaxAsciiCharCode = unibrow::Utf8::kMaxOneByteChar; 3907 static const unsigned kMaxAsciiCharCodeU = unibrow::Utf8::kMaxOneByteChar; 3908 static const int kMaxUC16CharCode = 0xffff; 3909 3910 // Minimum length for a cons string. 3911 static const int kMinNonFlatLength = 13; 3912 3913 // Mask constant for checking if a string has a computed hash code 3914 // and if it is an array index. The least significant bit indicates 3915 // whether a hash code has been computed. If the hash code has been 3916 // computed the 2nd bit tells whether the string can be used as an 3917 // array index. 3918 static const int kHashComputedMask = 1; 3919 static const int kIsArrayIndexMask = 1 << 1; 3920 static const int kNofLengthBitFields = 2; 3921 3922 // Shift constant retrieving hash code from hash field. 3923 static const int kHashShift = kNofLengthBitFields; 3924 3925 // Array index strings this short can keep their index in the hash 3926 // field. 3927 static const int kMaxCachedArrayIndexLength = 7; 3928 3929 // For strings which are array indexes the hash value has the string length 3930 // mixed into the hash, mainly to avoid a hash value of zero which would be 3931 // the case for the string '0'. 24 bits are used for the array index value. 3932 static const int kArrayIndexHashLengthShift = 24 + kNofLengthBitFields; 3933 static const int kArrayIndexHashMask = (1 << kArrayIndexHashLengthShift) - 1; 3934 static const int kArrayIndexValueBits = 3935 kArrayIndexHashLengthShift - kHashShift; 3936 3937 // Value of empty hash field indicating that the hash is not computed. 3938 static const int kEmptyHashField = 0; 3939 3940 // Maximal string length. 3941 static const int kMaxLength = (1 << (32 - 2)) - 1; 3942 3943 // Max length for computing hash. For strings longer than this limit the 3944 // string length is used as the hash value. 3945 static const int kMaxHashCalcLength = 16383; 3946 3947 // Limit for truncation in short printing. 3948 static const int kMaxShortPrintLength = 1024; 3949 3950 // Support for regular expressions. 3951 const uc16* GetTwoByteData(); 3952 const uc16* GetTwoByteData(unsigned start); 3953 3954 // Support for StringInputBuffer 3955 static const unibrow::byte* ReadBlock(String* input, 3956 unibrow::byte* util_buffer, 3957 unsigned capacity, 3958 unsigned* remaining, 3959 unsigned* offset); 3960 static const unibrow::byte* ReadBlock(String** input, 3961 unibrow::byte* util_buffer, 3962 unsigned capacity, 3963 unsigned* remaining, 3964 unsigned* offset); 3965 3966 // Helper function for flattening strings. 3967 template <typename sinkchar> 3968 static void WriteToFlat(String* source, 3969 sinkchar* sink, 3970 int from, 3971 int to); 3972 3973 protected: 3974 class ReadBlockBuffer { 3975 public: ReadBlockBuffer(unibrow::byte * util_buffer_,unsigned cursor_,unsigned capacity_,unsigned remaining_)3976 ReadBlockBuffer(unibrow::byte* util_buffer_, 3977 unsigned cursor_, 3978 unsigned capacity_, 3979 unsigned remaining_) : 3980 util_buffer(util_buffer_), 3981 cursor(cursor_), 3982 capacity(capacity_), 3983 remaining(remaining_) { 3984 } 3985 unibrow::byte* util_buffer; 3986 unsigned cursor; 3987 unsigned capacity; 3988 unsigned remaining; 3989 }; 3990 3991 static inline const unibrow::byte* ReadBlock(String* input, 3992 ReadBlockBuffer* buffer, 3993 unsigned* offset, 3994 unsigned max_chars); 3995 static void ReadBlockIntoBuffer(String* input, 3996 ReadBlockBuffer* buffer, 3997 unsigned* offset_ptr, 3998 unsigned max_chars); 3999 4000 private: 4001 // Slow case of String::Equals. This implementation works on any strings 4002 // but it is most efficient on strings that are almost flat. 4003 bool SlowEquals(String* other); 4004 4005 // Slow case of AsArrayIndex. 4006 bool SlowAsArrayIndex(uint32_t* index); 4007 4008 // Compute and set the hash code. 4009 uint32_t ComputeAndSetHash(); 4010 4011 DISALLOW_IMPLICIT_CONSTRUCTORS(String); 4012 }; 4013 4014 4015 // The SeqString abstract class captures sequential string values. 4016 class SeqString: public String { 4017 public: 4018 4019 // Casting. 4020 static inline SeqString* cast(Object* obj); 4021 4022 // Dispatched behaviour. 4023 // For regexp code. 4024 uint16_t* SeqStringGetTwoByteAddress(); 4025 4026 private: 4027 DISALLOW_IMPLICIT_CONSTRUCTORS(SeqString); 4028 }; 4029 4030 4031 // The AsciiString class captures sequential ascii string objects. 4032 // Each character in the AsciiString is an ascii character. 4033 class SeqAsciiString: public SeqString { 4034 public: 4035 // Dispatched behavior. 4036 inline uint16_t SeqAsciiStringGet(int index); 4037 inline void SeqAsciiStringSet(int index, uint16_t value); 4038 4039 // Get the address of the characters in this string. 4040 inline Address GetCharsAddress(); 4041 4042 inline char* GetChars(); 4043 4044 // Casting 4045 static inline SeqAsciiString* cast(Object* obj); 4046 4047 // Garbage collection support. This method is called by the 4048 // garbage collector to compute the actual size of an AsciiString 4049 // instance. 4050 inline int SeqAsciiStringSize(InstanceType instance_type); 4051 4052 // Computes the size for an AsciiString instance of a given length. SizeFor(int length)4053 static int SizeFor(int length) { 4054 return OBJECT_SIZE_ALIGN(kHeaderSize + length * kCharSize); 4055 } 4056 4057 // Layout description. 4058 static const int kHeaderSize = String::kSize; 4059 static const int kAlignedSize = POINTER_SIZE_ALIGN(kHeaderSize); 4060 4061 // Maximal memory usage for a single sequential ASCII string. 4062 static const int kMaxSize = 512 * MB; 4063 // Maximal length of a single sequential ASCII string. 4064 // Q.v. String::kMaxLength which is the maximal size of concatenated strings. 4065 static const int kMaxLength = (kMaxSize - kHeaderSize); 4066 4067 // Support for StringInputBuffer. 4068 inline void SeqAsciiStringReadBlockIntoBuffer(ReadBlockBuffer* buffer, 4069 unsigned* offset, 4070 unsigned chars); 4071 inline const unibrow::byte* SeqAsciiStringReadBlock(unsigned* remaining, 4072 unsigned* offset, 4073 unsigned chars); 4074 4075 private: 4076 DISALLOW_IMPLICIT_CONSTRUCTORS(SeqAsciiString); 4077 }; 4078 4079 4080 // The TwoByteString class captures sequential unicode string objects. 4081 // Each character in the TwoByteString is a two-byte uint16_t. 4082 class SeqTwoByteString: public SeqString { 4083 public: 4084 // Dispatched behavior. 4085 inline uint16_t SeqTwoByteStringGet(int index); 4086 inline void SeqTwoByteStringSet(int index, uint16_t value); 4087 4088 // Get the address of the characters in this string. 4089 inline Address GetCharsAddress(); 4090 4091 inline uc16* GetChars(); 4092 4093 // For regexp code. 4094 const uint16_t* SeqTwoByteStringGetData(unsigned start); 4095 4096 // Casting 4097 static inline SeqTwoByteString* cast(Object* obj); 4098 4099 // Garbage collection support. This method is called by the 4100 // garbage collector to compute the actual size of a TwoByteString 4101 // instance. 4102 inline int SeqTwoByteStringSize(InstanceType instance_type); 4103 4104 // Computes the size for a TwoByteString instance of a given length. SizeFor(int length)4105 static int SizeFor(int length) { 4106 return OBJECT_SIZE_ALIGN(kHeaderSize + length * kShortSize); 4107 } 4108 4109 // Layout description. 4110 static const int kHeaderSize = String::kSize; 4111 static const int kAlignedSize = POINTER_SIZE_ALIGN(kHeaderSize); 4112 4113 // Maximal memory usage for a single sequential two-byte string. 4114 static const int kMaxSize = 512 * MB; 4115 // Maximal length of a single sequential two-byte string. 4116 // Q.v. String::kMaxLength which is the maximal size of concatenated strings. 4117 static const int kMaxLength = (kMaxSize - kHeaderSize) / sizeof(uint16_t); 4118 4119 // Support for StringInputBuffer. 4120 inline void SeqTwoByteStringReadBlockIntoBuffer(ReadBlockBuffer* buffer, 4121 unsigned* offset_ptr, 4122 unsigned chars); 4123 4124 private: 4125 DISALLOW_IMPLICIT_CONSTRUCTORS(SeqTwoByteString); 4126 }; 4127 4128 4129 // The ConsString class describes string values built by using the 4130 // addition operator on strings. A ConsString is a pair where the 4131 // first and second components are pointers to other string values. 4132 // One or both components of a ConsString can be pointers to other 4133 // ConsStrings, creating a binary tree of ConsStrings where the leaves 4134 // are non-ConsString string values. The string value represented by 4135 // a ConsString can be obtained by concatenating the leaf string 4136 // values in a left-to-right depth-first traversal of the tree. 4137 class ConsString: public String { 4138 public: 4139 // First string of the cons cell. 4140 inline String* first(); 4141 // Doesn't check that the result is a string, even in debug mode. This is 4142 // useful during GC where the mark bits confuse the checks. 4143 inline Object* unchecked_first(); 4144 inline void set_first(String* first, 4145 WriteBarrierMode mode = UPDATE_WRITE_BARRIER); 4146 4147 // Second string of the cons cell. 4148 inline String* second(); 4149 // Doesn't check that the result is a string, even in debug mode. This is 4150 // useful during GC where the mark bits confuse the checks. 4151 inline Object* unchecked_second(); 4152 inline void set_second(String* second, 4153 WriteBarrierMode mode = UPDATE_WRITE_BARRIER); 4154 4155 // Dispatched behavior. 4156 uint16_t ConsStringGet(int index); 4157 4158 // Casting. 4159 static inline ConsString* cast(Object* obj); 4160 4161 // Garbage collection support. This method is called during garbage 4162 // collection to iterate through the heap pointers in the body of 4163 // the ConsString. 4164 void ConsStringIterateBody(ObjectVisitor* v); 4165 4166 // Layout description. 4167 static const int kFirstOffset = POINTER_SIZE_ALIGN(String::kSize); 4168 static const int kSecondOffset = kFirstOffset + kPointerSize; 4169 static const int kSize = kSecondOffset + kPointerSize; 4170 4171 // Support for StringInputBuffer. 4172 inline const unibrow::byte* ConsStringReadBlock(ReadBlockBuffer* buffer, 4173 unsigned* offset_ptr, 4174 unsigned chars); 4175 inline void ConsStringReadBlockIntoBuffer(ReadBlockBuffer* buffer, 4176 unsigned* offset_ptr, 4177 unsigned chars); 4178 4179 // Minimum length for a cons string. 4180 static const int kMinLength = 13; 4181 4182 private: 4183 DISALLOW_IMPLICIT_CONSTRUCTORS(ConsString); 4184 }; 4185 4186 4187 // The ExternalString class describes string values that are backed by 4188 // a string resource that lies outside the V8 heap. ExternalStrings 4189 // consist of the length field common to all strings, a pointer to the 4190 // external resource. It is important to ensure (externally) that the 4191 // resource is not deallocated while the ExternalString is live in the 4192 // V8 heap. 4193 // 4194 // The API expects that all ExternalStrings are created through the 4195 // API. Therefore, ExternalStrings should not be used internally. 4196 class ExternalString: public String { 4197 public: 4198 // Casting 4199 static inline ExternalString* cast(Object* obj); 4200 4201 // Layout description. 4202 static const int kResourceOffset = POINTER_SIZE_ALIGN(String::kSize); 4203 static const int kSize = kResourceOffset + kPointerSize; 4204 4205 STATIC_CHECK(kResourceOffset == Internals::kStringResourceOffset); 4206 4207 private: 4208 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalString); 4209 }; 4210 4211 4212 // The ExternalAsciiString class is an external string backed by an 4213 // ASCII string. 4214 class ExternalAsciiString: public ExternalString { 4215 public: 4216 typedef v8::String::ExternalAsciiStringResource Resource; 4217 4218 // The underlying resource. 4219 inline Resource* resource(); 4220 inline void set_resource(Resource* buffer); 4221 4222 // Dispatched behavior. 4223 uint16_t ExternalAsciiStringGet(int index); 4224 4225 // Casting. 4226 static inline ExternalAsciiString* cast(Object* obj); 4227 4228 // Garbage collection support. 4229 void ExternalAsciiStringIterateBody(ObjectVisitor* v); 4230 4231 // Support for StringInputBuffer. 4232 const unibrow::byte* ExternalAsciiStringReadBlock(unsigned* remaining, 4233 unsigned* offset, 4234 unsigned chars); 4235 inline void ExternalAsciiStringReadBlockIntoBuffer(ReadBlockBuffer* buffer, 4236 unsigned* offset, 4237 unsigned chars); 4238 4239 private: 4240 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalAsciiString); 4241 }; 4242 4243 4244 // The ExternalTwoByteString class is an external string backed by a UTF-16 4245 // encoded string. 4246 class ExternalTwoByteString: public ExternalString { 4247 public: 4248 typedef v8::String::ExternalStringResource Resource; 4249 4250 // The underlying string resource. 4251 inline Resource* resource(); 4252 inline void set_resource(Resource* buffer); 4253 4254 // Dispatched behavior. 4255 uint16_t ExternalTwoByteStringGet(int index); 4256 4257 // For regexp code. 4258 const uint16_t* ExternalTwoByteStringGetData(unsigned start); 4259 4260 // Casting. 4261 static inline ExternalTwoByteString* cast(Object* obj); 4262 4263 // Garbage collection support. 4264 void ExternalTwoByteStringIterateBody(ObjectVisitor* v); 4265 4266 // Support for StringInputBuffer. 4267 void ExternalTwoByteStringReadBlockIntoBuffer(ReadBlockBuffer* buffer, 4268 unsigned* offset_ptr, 4269 unsigned chars); 4270 4271 private: 4272 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalTwoByteString); 4273 }; 4274 4275 4276 // Utility superclass for stack-allocated objects that must be updated 4277 // on gc. It provides two ways for the gc to update instances, either 4278 // iterating or updating after gc. 4279 class Relocatable BASE_EMBEDDED { 4280 public: Relocatable()4281 inline Relocatable() : prev_(top_) { top_ = this; } ~Relocatable()4282 virtual ~Relocatable() { 4283 ASSERT_EQ(top_, this); 4284 top_ = prev_; 4285 } IterateInstance(ObjectVisitor * v)4286 virtual void IterateInstance(ObjectVisitor* v) { } PostGarbageCollection()4287 virtual void PostGarbageCollection() { } 4288 4289 static void PostGarbageCollectionProcessing(); 4290 static int ArchiveSpacePerThread(); 4291 static char* ArchiveState(char* to); 4292 static char* RestoreState(char* from); 4293 static void Iterate(ObjectVisitor* v); 4294 static void Iterate(ObjectVisitor* v, Relocatable* top); 4295 static char* Iterate(ObjectVisitor* v, char* t); 4296 private: 4297 static Relocatable* top_; 4298 Relocatable* prev_; 4299 }; 4300 4301 4302 // A flat string reader provides random access to the contents of a 4303 // string independent of the character width of the string. The handle 4304 // must be valid as long as the reader is being used. 4305 class FlatStringReader : public Relocatable { 4306 public: 4307 explicit FlatStringReader(Handle<String> str); 4308 explicit FlatStringReader(Vector<const char> input); 4309 void PostGarbageCollection(); 4310 inline uc32 Get(int index); length()4311 int length() { return length_; } 4312 private: 4313 String** str_; 4314 bool is_ascii_; 4315 int length_; 4316 const void* start_; 4317 }; 4318 4319 4320 // Note that StringInputBuffers are not valid across a GC! To fix this 4321 // it would have to store a String Handle instead of a String* and 4322 // AsciiStringReadBlock would have to be modified to use memcpy. 4323 // 4324 // StringInputBuffer is able to traverse any string regardless of how 4325 // deeply nested a sequence of ConsStrings it is made of. However, 4326 // performance will be better if deep strings are flattened before they 4327 // are traversed. Since flattening requires memory allocation this is 4328 // not always desirable, however (esp. in debugging situations). 4329 class StringInputBuffer: public unibrow::InputBuffer<String, String*, 1024> { 4330 public: 4331 virtual void Seek(unsigned pos); StringInputBuffer()4332 inline StringInputBuffer(): unibrow::InputBuffer<String, String*, 1024>() {} StringInputBuffer(String * backing)4333 inline StringInputBuffer(String* backing): 4334 unibrow::InputBuffer<String, String*, 1024>(backing) {} 4335 }; 4336 4337 4338 class SafeStringInputBuffer 4339 : public unibrow::InputBuffer<String, String**, 256> { 4340 public: 4341 virtual void Seek(unsigned pos); SafeStringInputBuffer()4342 inline SafeStringInputBuffer() 4343 : unibrow::InputBuffer<String, String**, 256>() {} SafeStringInputBuffer(String ** backing)4344 inline SafeStringInputBuffer(String** backing) 4345 : unibrow::InputBuffer<String, String**, 256>(backing) {} 4346 }; 4347 4348 4349 template <typename T> 4350 class VectorIterator { 4351 public: VectorIterator(T * d,int l)4352 VectorIterator(T* d, int l) : data_(Vector<const T>(d, l)), index_(0) { } VectorIterator(Vector<const T> data)4353 explicit VectorIterator(Vector<const T> data) : data_(data), index_(0) { } GetNext()4354 T GetNext() { return data_[index_++]; } has_more()4355 bool has_more() { return index_ < data_.length(); } 4356 private: 4357 Vector<const T> data_; 4358 int index_; 4359 }; 4360 4361 4362 // The Oddball describes objects null, undefined, true, and false. 4363 class Oddball: public HeapObject { 4364 public: 4365 // [to_string]: Cached to_string computed at startup. 4366 DECL_ACCESSORS(to_string, String) 4367 4368 // [to_number]: Cached to_number computed at startup. 4369 DECL_ACCESSORS(to_number, Object) 4370 4371 // Casting. 4372 static inline Oddball* cast(Object* obj); 4373 4374 // Dispatched behavior. 4375 void OddballIterateBody(ObjectVisitor* v); 4376 #ifdef DEBUG 4377 void OddballVerify(); 4378 #endif 4379 4380 // Initialize the fields. 4381 Object* Initialize(const char* to_string, Object* to_number); 4382 4383 // Layout description. 4384 static const int kToStringOffset = HeapObject::kHeaderSize; 4385 static const int kToNumberOffset = kToStringOffset + kPointerSize; 4386 static const int kSize = kToNumberOffset + kPointerSize; 4387 4388 private: 4389 DISALLOW_IMPLICIT_CONSTRUCTORS(Oddball); 4390 }; 4391 4392 4393 class JSGlobalPropertyCell: public HeapObject { 4394 public: 4395 // [value]: value of the global property. 4396 DECL_ACCESSORS(value, Object) 4397 4398 // Casting. 4399 static inline JSGlobalPropertyCell* cast(Object* obj); 4400 4401 // Dispatched behavior. 4402 void JSGlobalPropertyCellIterateBody(ObjectVisitor* v); 4403 #ifdef DEBUG 4404 void JSGlobalPropertyCellVerify(); 4405 void JSGlobalPropertyCellPrint(); 4406 #endif 4407 4408 // Layout description. 4409 static const int kValueOffset = HeapObject::kHeaderSize; 4410 static const int kSize = kValueOffset + kPointerSize; 4411 4412 private: 4413 DISALLOW_IMPLICIT_CONSTRUCTORS(JSGlobalPropertyCell); 4414 }; 4415 4416 4417 4418 // Proxy describes objects pointing from JavaScript to C structures. 4419 // Since they cannot contain references to JS HeapObjects they can be 4420 // placed in old_data_space. 4421 class Proxy: public HeapObject { 4422 public: 4423 // [proxy]: field containing the address. 4424 inline Address proxy(); 4425 inline void set_proxy(Address value); 4426 4427 // Casting. 4428 static inline Proxy* cast(Object* obj); 4429 4430 // Dispatched behavior. 4431 inline void ProxyIterateBody(ObjectVisitor* v); 4432 #ifdef DEBUG 4433 void ProxyPrint(); 4434 void ProxyVerify(); 4435 #endif 4436 4437 // Layout description. 4438 4439 static const int kProxyOffset = HeapObject::kHeaderSize; 4440 static const int kSize = kProxyOffset + kPointerSize; 4441 4442 STATIC_CHECK(kProxyOffset == Internals::kProxyProxyOffset); 4443 4444 private: 4445 DISALLOW_IMPLICIT_CONSTRUCTORS(Proxy); 4446 }; 4447 4448 4449 // The JSArray describes JavaScript Arrays 4450 // Such an array can be in one of two modes: 4451 // - fast, backing storage is a FixedArray and length <= elements.length(); 4452 // Please note: push and pop can be used to grow and shrink the array. 4453 // - slow, backing storage is a HashTable with numbers as keys. 4454 class JSArray: public JSObject { 4455 public: 4456 // [length]: The length property. 4457 DECL_ACCESSORS(length, Object) 4458 4459 // Overload the length setter to skip write barrier when the length 4460 // is set to a smi. This matches the set function on FixedArray. 4461 inline void set_length(Smi* length); 4462 4463 Object* JSArrayUpdateLengthFromIndex(uint32_t index, Object* value); 4464 4465 // Initialize the array with the given capacity. The function may 4466 // fail due to out-of-memory situations, but only if the requested 4467 // capacity is non-zero. 4468 Object* Initialize(int capacity); 4469 4470 // Set the content of the array to the content of storage. 4471 inline void SetContent(FixedArray* storage); 4472 4473 // Casting. 4474 static inline JSArray* cast(Object* obj); 4475 4476 // Uses handles. Ensures that the fixed array backing the JSArray has at 4477 // least the stated size. 4478 inline void EnsureSize(int minimum_size_of_backing_fixed_array); 4479 4480 // Dispatched behavior. 4481 #ifdef DEBUG 4482 void JSArrayPrint(); 4483 void JSArrayVerify(); 4484 #endif 4485 4486 // Number of element slots to pre-allocate for an empty array. 4487 static const int kPreallocatedArrayElements = 4; 4488 4489 // Layout description. 4490 static const int kLengthOffset = JSObject::kHeaderSize; 4491 static const int kSize = kLengthOffset + kPointerSize; 4492 4493 private: 4494 // Expand the fixed array backing of a fast-case JSArray to at least 4495 // the requested size. 4496 void Expand(int minimum_size_of_backing_fixed_array); 4497 4498 DISALLOW_IMPLICIT_CONSTRUCTORS(JSArray); 4499 }; 4500 4501 4502 // An accessor must have a getter, but can have no setter. 4503 // 4504 // When setting a property, V8 searches accessors in prototypes. 4505 // If an accessor was found and it does not have a setter, 4506 // the request is ignored. 4507 // 4508 // If the accessor in the prototype has the READ_ONLY property attribute, then 4509 // a new value is added to the local object when the property is set. 4510 // This shadows the accessor in the prototype. 4511 class AccessorInfo: public Struct { 4512 public: 4513 DECL_ACCESSORS(getter, Object) 4514 DECL_ACCESSORS(setter, Object) 4515 DECL_ACCESSORS(data, Object) 4516 DECL_ACCESSORS(name, Object) 4517 DECL_ACCESSORS(flag, Smi) 4518 DECL_ACCESSORS(load_stub_cache, Object) 4519 4520 inline bool all_can_read(); 4521 inline void set_all_can_read(bool value); 4522 4523 inline bool all_can_write(); 4524 inline void set_all_can_write(bool value); 4525 4526 inline bool prohibits_overwriting(); 4527 inline void set_prohibits_overwriting(bool value); 4528 4529 inline PropertyAttributes property_attributes(); 4530 inline void set_property_attributes(PropertyAttributes attributes); 4531 4532 static inline AccessorInfo* cast(Object* obj); 4533 4534 #ifdef DEBUG 4535 void AccessorInfoPrint(); 4536 void AccessorInfoVerify(); 4537 #endif 4538 4539 static const int kGetterOffset = HeapObject::kHeaderSize; 4540 static const int kSetterOffset = kGetterOffset + kPointerSize; 4541 static const int kDataOffset = kSetterOffset + kPointerSize; 4542 static const int kNameOffset = kDataOffset + kPointerSize; 4543 static const int kFlagOffset = kNameOffset + kPointerSize; 4544 static const int kLoadStubCacheOffset = kFlagOffset + kPointerSize; 4545 static const int kSize = kLoadStubCacheOffset + kPointerSize; 4546 4547 private: 4548 // Bit positions in flag. 4549 static const int kAllCanReadBit = 0; 4550 static const int kAllCanWriteBit = 1; 4551 static const int kProhibitsOverwritingBit = 2; 4552 class AttributesField: public BitField<PropertyAttributes, 3, 3> {}; 4553 4554 DISALLOW_IMPLICIT_CONSTRUCTORS(AccessorInfo); 4555 }; 4556 4557 4558 class AccessCheckInfo: public Struct { 4559 public: 4560 DECL_ACCESSORS(named_callback, Object) 4561 DECL_ACCESSORS(indexed_callback, Object) 4562 DECL_ACCESSORS(data, Object) 4563 4564 static inline AccessCheckInfo* cast(Object* obj); 4565 4566 #ifdef DEBUG 4567 void AccessCheckInfoPrint(); 4568 void AccessCheckInfoVerify(); 4569 #endif 4570 4571 static const int kNamedCallbackOffset = HeapObject::kHeaderSize; 4572 static const int kIndexedCallbackOffset = kNamedCallbackOffset + kPointerSize; 4573 static const int kDataOffset = kIndexedCallbackOffset + kPointerSize; 4574 static const int kSize = kDataOffset + kPointerSize; 4575 4576 private: 4577 DISALLOW_IMPLICIT_CONSTRUCTORS(AccessCheckInfo); 4578 }; 4579 4580 4581 class InterceptorInfo: public Struct { 4582 public: 4583 DECL_ACCESSORS(getter, Object) 4584 DECL_ACCESSORS(setter, Object) 4585 DECL_ACCESSORS(query, Object) 4586 DECL_ACCESSORS(deleter, Object) 4587 DECL_ACCESSORS(enumerator, Object) 4588 DECL_ACCESSORS(data, Object) 4589 4590 static inline InterceptorInfo* cast(Object* obj); 4591 4592 #ifdef DEBUG 4593 void InterceptorInfoPrint(); 4594 void InterceptorInfoVerify(); 4595 #endif 4596 4597 static const int kGetterOffset = HeapObject::kHeaderSize; 4598 static const int kSetterOffset = kGetterOffset + kPointerSize; 4599 static const int kQueryOffset = kSetterOffset + kPointerSize; 4600 static const int kDeleterOffset = kQueryOffset + kPointerSize; 4601 static const int kEnumeratorOffset = kDeleterOffset + kPointerSize; 4602 static const int kDataOffset = kEnumeratorOffset + kPointerSize; 4603 static const int kSize = kDataOffset + kPointerSize; 4604 4605 private: 4606 DISALLOW_IMPLICIT_CONSTRUCTORS(InterceptorInfo); 4607 }; 4608 4609 4610 class CallHandlerInfo: public Struct { 4611 public: 4612 DECL_ACCESSORS(callback, Object) 4613 DECL_ACCESSORS(data, Object) 4614 4615 static inline CallHandlerInfo* cast(Object* obj); 4616 4617 #ifdef DEBUG 4618 void CallHandlerInfoPrint(); 4619 void CallHandlerInfoVerify(); 4620 #endif 4621 4622 static const int kCallbackOffset = HeapObject::kHeaderSize; 4623 static const int kDataOffset = kCallbackOffset + kPointerSize; 4624 static const int kSize = kDataOffset + kPointerSize; 4625 4626 private: 4627 DISALLOW_IMPLICIT_CONSTRUCTORS(CallHandlerInfo); 4628 }; 4629 4630 4631 class TemplateInfo: public Struct { 4632 public: 4633 DECL_ACCESSORS(tag, Object) 4634 DECL_ACCESSORS(property_list, Object) 4635 4636 #ifdef DEBUG 4637 void TemplateInfoVerify(); 4638 #endif 4639 4640 static const int kTagOffset = HeapObject::kHeaderSize; 4641 static const int kPropertyListOffset = kTagOffset + kPointerSize; 4642 static const int kHeaderSize = kPropertyListOffset + kPointerSize; 4643 protected: 4644 friend class AGCCVersionRequiresThisClassToHaveAFriendSoHereItIs; 4645 DISALLOW_IMPLICIT_CONSTRUCTORS(TemplateInfo); 4646 }; 4647 4648 4649 class FunctionTemplateInfo: public TemplateInfo { 4650 public: 4651 DECL_ACCESSORS(serial_number, Object) 4652 DECL_ACCESSORS(call_code, Object) 4653 DECL_ACCESSORS(property_accessors, Object) 4654 DECL_ACCESSORS(prototype_template, Object) 4655 DECL_ACCESSORS(parent_template, Object) 4656 DECL_ACCESSORS(named_property_handler, Object) 4657 DECL_ACCESSORS(indexed_property_handler, Object) 4658 DECL_ACCESSORS(instance_template, Object) 4659 DECL_ACCESSORS(class_name, Object) 4660 DECL_ACCESSORS(signature, Object) 4661 DECL_ACCESSORS(instance_call_handler, Object) 4662 DECL_ACCESSORS(access_check_info, Object) 4663 DECL_ACCESSORS(flag, Smi) 4664 4665 // Following properties use flag bits. 4666 DECL_BOOLEAN_ACCESSORS(hidden_prototype) 4667 DECL_BOOLEAN_ACCESSORS(undetectable) 4668 // If the bit is set, object instances created by this function 4669 // requires access check. 4670 DECL_BOOLEAN_ACCESSORS(needs_access_check) 4671 4672 static inline FunctionTemplateInfo* cast(Object* obj); 4673 4674 #ifdef DEBUG 4675 void FunctionTemplateInfoPrint(); 4676 void FunctionTemplateInfoVerify(); 4677 #endif 4678 4679 static const int kSerialNumberOffset = TemplateInfo::kHeaderSize; 4680 static const int kCallCodeOffset = kSerialNumberOffset + kPointerSize; 4681 static const int kPropertyAccessorsOffset = kCallCodeOffset + kPointerSize; 4682 static const int kPrototypeTemplateOffset = 4683 kPropertyAccessorsOffset + kPointerSize; 4684 static const int kParentTemplateOffset = 4685 kPrototypeTemplateOffset + kPointerSize; 4686 static const int kNamedPropertyHandlerOffset = 4687 kParentTemplateOffset + kPointerSize; 4688 static const int kIndexedPropertyHandlerOffset = 4689 kNamedPropertyHandlerOffset + kPointerSize; 4690 static const int kInstanceTemplateOffset = 4691 kIndexedPropertyHandlerOffset + kPointerSize; 4692 static const int kClassNameOffset = kInstanceTemplateOffset + kPointerSize; 4693 static const int kSignatureOffset = kClassNameOffset + kPointerSize; 4694 static const int kInstanceCallHandlerOffset = kSignatureOffset + kPointerSize; 4695 static const int kAccessCheckInfoOffset = 4696 kInstanceCallHandlerOffset + kPointerSize; 4697 static const int kFlagOffset = kAccessCheckInfoOffset + kPointerSize; 4698 static const int kSize = kFlagOffset + kPointerSize; 4699 4700 private: 4701 // Bit position in the flag, from least significant bit position. 4702 static const int kHiddenPrototypeBit = 0; 4703 static const int kUndetectableBit = 1; 4704 static const int kNeedsAccessCheckBit = 2; 4705 4706 DISALLOW_IMPLICIT_CONSTRUCTORS(FunctionTemplateInfo); 4707 }; 4708 4709 4710 class ObjectTemplateInfo: public TemplateInfo { 4711 public: 4712 DECL_ACCESSORS(constructor, Object) 4713 DECL_ACCESSORS(internal_field_count, Object) 4714 4715 static inline ObjectTemplateInfo* cast(Object* obj); 4716 4717 #ifdef DEBUG 4718 void ObjectTemplateInfoPrint(); 4719 void ObjectTemplateInfoVerify(); 4720 #endif 4721 4722 static const int kConstructorOffset = TemplateInfo::kHeaderSize; 4723 static const int kInternalFieldCountOffset = 4724 kConstructorOffset + kPointerSize; 4725 static const int kSize = kInternalFieldCountOffset + kPointerSize; 4726 }; 4727 4728 4729 class SignatureInfo: public Struct { 4730 public: 4731 DECL_ACCESSORS(receiver, Object) 4732 DECL_ACCESSORS(args, Object) 4733 4734 static inline SignatureInfo* cast(Object* obj); 4735 4736 #ifdef DEBUG 4737 void SignatureInfoPrint(); 4738 void SignatureInfoVerify(); 4739 #endif 4740 4741 static const int kReceiverOffset = Struct::kHeaderSize; 4742 static const int kArgsOffset = kReceiverOffset + kPointerSize; 4743 static const int kSize = kArgsOffset + kPointerSize; 4744 4745 private: 4746 DISALLOW_IMPLICIT_CONSTRUCTORS(SignatureInfo); 4747 }; 4748 4749 4750 class TypeSwitchInfo: public Struct { 4751 public: 4752 DECL_ACCESSORS(types, Object) 4753 4754 static inline TypeSwitchInfo* cast(Object* obj); 4755 4756 #ifdef DEBUG 4757 void TypeSwitchInfoPrint(); 4758 void TypeSwitchInfoVerify(); 4759 #endif 4760 4761 static const int kTypesOffset = Struct::kHeaderSize; 4762 static const int kSize = kTypesOffset + kPointerSize; 4763 }; 4764 4765 4766 #ifdef ENABLE_DEBUGGER_SUPPORT 4767 // The DebugInfo class holds additional information for a function being 4768 // debugged. 4769 class DebugInfo: public Struct { 4770 public: 4771 // The shared function info for the source being debugged. 4772 DECL_ACCESSORS(shared, SharedFunctionInfo) 4773 // Code object for the original code. 4774 DECL_ACCESSORS(original_code, Code) 4775 // Code object for the patched code. This code object is the code object 4776 // currently active for the function. 4777 DECL_ACCESSORS(code, Code) 4778 // Fixed array holding status information for each active break point. 4779 DECL_ACCESSORS(break_points, FixedArray) 4780 4781 // Check if there is a break point at a code position. 4782 bool HasBreakPoint(int code_position); 4783 // Get the break point info object for a code position. 4784 Object* GetBreakPointInfo(int code_position); 4785 // Clear a break point. 4786 static void ClearBreakPoint(Handle<DebugInfo> debug_info, 4787 int code_position, 4788 Handle<Object> break_point_object); 4789 // Set a break point. 4790 static void SetBreakPoint(Handle<DebugInfo> debug_info, int code_position, 4791 int source_position, int statement_position, 4792 Handle<Object> break_point_object); 4793 // Get the break point objects for a code position. 4794 Object* GetBreakPointObjects(int code_position); 4795 // Find the break point info holding this break point object. 4796 static Object* FindBreakPointInfo(Handle<DebugInfo> debug_info, 4797 Handle<Object> break_point_object); 4798 // Get the number of break points for this function. 4799 int GetBreakPointCount(); 4800 4801 static inline DebugInfo* cast(Object* obj); 4802 4803 #ifdef DEBUG 4804 void DebugInfoPrint(); 4805 void DebugInfoVerify(); 4806 #endif 4807 4808 static const int kSharedFunctionInfoIndex = Struct::kHeaderSize; 4809 static const int kOriginalCodeIndex = kSharedFunctionInfoIndex + kPointerSize; 4810 static const int kPatchedCodeIndex = kOriginalCodeIndex + kPointerSize; 4811 static const int kActiveBreakPointsCountIndex = 4812 kPatchedCodeIndex + kPointerSize; 4813 static const int kBreakPointsStateIndex = 4814 kActiveBreakPointsCountIndex + kPointerSize; 4815 static const int kSize = kBreakPointsStateIndex + kPointerSize; 4816 4817 private: 4818 static const int kNoBreakPointInfo = -1; 4819 4820 // Lookup the index in the break_points array for a code position. 4821 int GetBreakPointInfoIndex(int code_position); 4822 4823 DISALLOW_IMPLICIT_CONSTRUCTORS(DebugInfo); 4824 }; 4825 4826 4827 // The BreakPointInfo class holds information for break points set in a 4828 // function. The DebugInfo object holds a BreakPointInfo object for each code 4829 // position with one or more break points. 4830 class BreakPointInfo: public Struct { 4831 public: 4832 // The position in the code for the break point. 4833 DECL_ACCESSORS(code_position, Smi) 4834 // The position in the source for the break position. 4835 DECL_ACCESSORS(source_position, Smi) 4836 // The position in the source for the last statement before this break 4837 // position. 4838 DECL_ACCESSORS(statement_position, Smi) 4839 // List of related JavaScript break points. 4840 DECL_ACCESSORS(break_point_objects, Object) 4841 4842 // Removes a break point. 4843 static void ClearBreakPoint(Handle<BreakPointInfo> info, 4844 Handle<Object> break_point_object); 4845 // Set a break point. 4846 static void SetBreakPoint(Handle<BreakPointInfo> info, 4847 Handle<Object> break_point_object); 4848 // Check if break point info has this break point object. 4849 static bool HasBreakPointObject(Handle<BreakPointInfo> info, 4850 Handle<Object> break_point_object); 4851 // Get the number of break points for this code position. 4852 int GetBreakPointCount(); 4853 4854 static inline BreakPointInfo* cast(Object* obj); 4855 4856 #ifdef DEBUG 4857 void BreakPointInfoPrint(); 4858 void BreakPointInfoVerify(); 4859 #endif 4860 4861 static const int kCodePositionIndex = Struct::kHeaderSize; 4862 static const int kSourcePositionIndex = kCodePositionIndex + kPointerSize; 4863 static const int kStatementPositionIndex = 4864 kSourcePositionIndex + kPointerSize; 4865 static const int kBreakPointObjectsIndex = 4866 kStatementPositionIndex + kPointerSize; 4867 static const int kSize = kBreakPointObjectsIndex + kPointerSize; 4868 4869 private: 4870 DISALLOW_IMPLICIT_CONSTRUCTORS(BreakPointInfo); 4871 }; 4872 #endif // ENABLE_DEBUGGER_SUPPORT 4873 4874 4875 #undef DECL_BOOLEAN_ACCESSORS 4876 #undef DECL_ACCESSORS 4877 4878 4879 // Abstract base class for visiting, and optionally modifying, the 4880 // pointers contained in Objects. Used in GC and serialization/deserialization. 4881 class ObjectVisitor BASE_EMBEDDED { 4882 public: ~ObjectVisitor()4883 virtual ~ObjectVisitor() {} 4884 4885 // Visits a contiguous arrays of pointers in the half-open range 4886 // [start, end). Any or all of the values may be modified on return. 4887 virtual void VisitPointers(Object** start, Object** end) = 0; 4888 4889 // To allow lazy clearing of inline caches the visitor has 4890 // a rich interface for iterating over Code objects.. 4891 4892 // Visits a code target in the instruction stream. 4893 virtual void VisitCodeTarget(RelocInfo* rinfo); 4894 4895 // Visits a runtime entry in the instruction stream. VisitRuntimeEntry(RelocInfo * rinfo)4896 virtual void VisitRuntimeEntry(RelocInfo* rinfo) {} 4897 4898 // Visits the resource of an ASCII or two-byte string. VisitExternalAsciiString(v8::String::ExternalAsciiStringResource ** resource)4899 virtual void VisitExternalAsciiString( 4900 v8::String::ExternalAsciiStringResource** resource) {} VisitExternalTwoByteString(v8::String::ExternalStringResource ** resource)4901 virtual void VisitExternalTwoByteString( 4902 v8::String::ExternalStringResource** resource) {} 4903 4904 // Visits a debug call target in the instruction stream. 4905 virtual void VisitDebugTarget(RelocInfo* rinfo); 4906 4907 // Handy shorthand for visiting a single pointer. VisitPointer(Object ** p)4908 virtual void VisitPointer(Object** p) { VisitPointers(p, p + 1); } 4909 4910 // Visits a contiguous arrays of external references (references to the C++ 4911 // heap) in the half-open range [start, end). Any or all of the values 4912 // may be modified on return. VisitExternalReferences(Address * start,Address * end)4913 virtual void VisitExternalReferences(Address* start, Address* end) {} 4914 VisitExternalReference(Address * p)4915 inline void VisitExternalReference(Address* p) { 4916 VisitExternalReferences(p, p + 1); 4917 } 4918 4919 #ifdef DEBUG 4920 // Intended for serialization/deserialization checking: insert, or 4921 // check for the presence of, a tag at this position in the stream. Synchronize(const char * tag)4922 virtual void Synchronize(const char* tag) {} 4923 #else Synchronize(const char * tag)4924 inline void Synchronize(const char* tag) {} 4925 #endif 4926 }; 4927 4928 4929 // BooleanBit is a helper class for setting and getting a bit in an 4930 // integer or Smi. 4931 class BooleanBit : public AllStatic { 4932 public: get(Smi * smi,int bit_position)4933 static inline bool get(Smi* smi, int bit_position) { 4934 return get(smi->value(), bit_position); 4935 } 4936 get(int value,int bit_position)4937 static inline bool get(int value, int bit_position) { 4938 return (value & (1 << bit_position)) != 0; 4939 } 4940 set(Smi * smi,int bit_position,bool v)4941 static inline Smi* set(Smi* smi, int bit_position, bool v) { 4942 return Smi::FromInt(set(smi->value(), bit_position, v)); 4943 } 4944 set(int value,int bit_position,bool v)4945 static inline int set(int value, int bit_position, bool v) { 4946 if (v) { 4947 value |= (1 << bit_position); 4948 } else { 4949 value &= ~(1 << bit_position); 4950 } 4951 return value; 4952 } 4953 }; 4954 4955 } } // namespace v8::internal 4956 4957 #endif // V8_OBJECTS_H_ 4958