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