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