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