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