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