objects.h revision ac95265630a4e0c317a7a7201d17a57df7d9bcce
1// Copyright 2006-2009 the V8 project authors. All rights reserved. 2// Redistribution and use in source and binary forms, with or without 3// modification, are permitted provided that the following conditions are 4// met: 5// 6// * Redistributions of source code must retain the above copyright 7// notice, this list of conditions and the following disclaimer. 8// * Redistributions in binary form must reproduce the above 9// copyright notice, this list of conditions and the following 10// disclaimer in the documentation and/or other materials provided 11// with the distribution. 12// * Neither the name of Google Inc. nor the names of its 13// contributors may be used to endorse or promote products derived 14// from this software without specific prior written permission. 15// 16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 28#ifndef V8_OBJECTS_H_ 29#define V8_OBJECTS_H_ 30 31#include "builtins.h" 32#include "code-stubs.h" 33#include "smart-pointer.h" 34#include "unicode-inl.h" 35#if V8_TARGET_ARCH_ARM 36#include "arm/constants-arm.h" 37#elif V8_TARGET_ARCH_MIPS 38#include "mips/constants-mips.h" 39#endif 40 41// 42// All object types in the V8 JavaScript are described in this file. 43// 44// Inheritance hierarchy: 45// - Object 46// - Smi (immediate small integer) 47// - Failure (immediate for marking failed operation) 48// - HeapObject (superclass for everything allocated in the heap) 49// - JSObject 50// - JSArray 51// - JSRegExp 52// - JSFunction 53// - GlobalObject 54// - JSGlobalObject 55// - JSBuiltinsObject 56// - JSGlobalProxy 57// - JSValue 58// - 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// - GlobalContext 78// - JSFunctionResultCache 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 -1. 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 2299 2300class NumberDictionaryShape { 2301 public: 2302 static inline bool IsMatch(uint32_t key, Object* other); 2303 static inline uint32_t Hash(uint32_t key); 2304 static inline uint32_t HashForObject(uint32_t key, Object* object); 2305 static inline Object* AsObject(uint32_t key); 2306 static const int kPrefixSize = 2; 2307 static const int kEntrySize = 3; 2308 static const bool kIsEnumerable = false; 2309}; 2310 2311 2312class NumberDictionary: public Dictionary<NumberDictionaryShape, uint32_t> { 2313 public: 2314 static NumberDictionary* cast(Object* obj) { 2315 ASSERT(obj->IsDictionary()); 2316 return reinterpret_cast<NumberDictionary*>(obj); 2317 } 2318 2319 // Type specific at put (default NONE attributes is used when adding). 2320 Object* AtNumberPut(uint32_t key, Object* value); 2321 Object* AddNumberEntry(uint32_t key, 2322 Object* value, 2323 PropertyDetails details); 2324 2325 // Set an existing entry or add a new one if needed. 2326 Object* Set(uint32_t key, Object* value, PropertyDetails details); 2327 2328 void UpdateMaxNumberKey(uint32_t key); 2329 2330 // If slow elements are required we will never go back to fast-case 2331 // for the elements kept in this dictionary. We require slow 2332 // elements if an element has been added at an index larger than 2333 // kRequiresSlowElementsLimit or set_requires_slow_elements() has been called 2334 // when defining a getter or setter with a number key. 2335 inline bool requires_slow_elements(); 2336 inline void set_requires_slow_elements(); 2337 2338 // Get the value of the max number key that has been added to this 2339 // dictionary. max_number_key can only be called if 2340 // requires_slow_elements returns false. 2341 inline uint32_t max_number_key(); 2342 2343 // Remove all entries were key is a number and (from <= key && key < to). 2344 void RemoveNumberEntries(uint32_t from, uint32_t to); 2345 2346 // Bit masks. 2347 static const int kRequiresSlowElementsMask = 1; 2348 static const int kRequiresSlowElementsTagSize = 1; 2349 static const uint32_t kRequiresSlowElementsLimit = (1 << 29) - 1; 2350}; 2351 2352 2353// JSFunctionResultCache caches results of some JSFunction invocation. 2354// It is a fixed array with fixed structure: 2355// [0]: factory function 2356// [1]: finger index 2357// [2]: current cache size 2358// [3]: dummy field. 2359// The rest of array are key/value pairs. 2360class JSFunctionResultCache: public FixedArray { 2361 public: 2362 static const int kFactoryIndex = 0; 2363 static const int kFingerIndex = kFactoryIndex + 1; 2364 static const int kCacheSizeIndex = kFingerIndex + 1; 2365 static const int kDummyIndex = kCacheSizeIndex + 1; 2366 static const int kEntriesIndex = kDummyIndex + 1; 2367 2368 static const int kEntrySize = 2; // key + value 2369 2370 static const int kFactoryOffset = kHeaderSize; 2371 static const int kFingerOffset = kFactoryOffset + kPointerSize; 2372 static const int kCacheSizeOffset = kFingerOffset + kPointerSize; 2373 2374 inline void MakeZeroSize(); 2375 inline void Clear(); 2376 2377 // Casting 2378 static inline JSFunctionResultCache* cast(Object* obj); 2379 2380#ifdef DEBUG 2381 void JSFunctionResultCacheVerify(); 2382#endif 2383}; 2384 2385 2386// ByteArray represents fixed sized byte arrays. Used by the outside world, 2387// such as PCRE, and also by the memory allocator and garbage collector to 2388// fill in free blocks in the heap. 2389class ByteArray: public HeapObject { 2390 public: 2391 // [length]: length of the array. 2392 inline int length(); 2393 inline void set_length(int value); 2394 2395 // Setter and getter. 2396 inline byte get(int index); 2397 inline void set(int index, byte value); 2398 2399 // Treat contents as an int array. 2400 inline int get_int(int index); 2401 2402 static int SizeFor(int length) { 2403 return OBJECT_POINTER_ALIGN(kHeaderSize + length); 2404 } 2405 // We use byte arrays for free blocks in the heap. Given a desired size in 2406 // bytes that is a multiple of the word size and big enough to hold a byte 2407 // array, this function returns the number of elements a byte array should 2408 // have. 2409 static int LengthFor(int size_in_bytes) { 2410 ASSERT(IsAligned(size_in_bytes, kPointerSize)); 2411 ASSERT(size_in_bytes >= kHeaderSize); 2412 return size_in_bytes - kHeaderSize; 2413 } 2414 2415 // Returns data start address. 2416 inline Address GetDataStartAddress(); 2417 2418 // Returns a pointer to the ByteArray object for a given data start address. 2419 static inline ByteArray* FromDataStartAddress(Address address); 2420 2421 // Casting. 2422 static inline ByteArray* cast(Object* obj); 2423 2424 // Dispatched behavior. 2425 int ByteArraySize() { return SizeFor(length()); } 2426#ifdef DEBUG 2427 void ByteArrayPrint(); 2428 void ByteArrayVerify(); 2429#endif 2430 2431 // Layout description. 2432 // Length is smi tagged when it is stored. 2433 static const int kLengthOffset = HeapObject::kHeaderSize; 2434 static const int kHeaderSize = kLengthOffset + kPointerSize; 2435 2436 static const int kAlignedSize = OBJECT_POINTER_ALIGN(kHeaderSize); 2437 2438 // Maximal memory consumption for a single ByteArray. 2439 static const int kMaxSize = 512 * MB; 2440 // Maximal length of a single ByteArray. 2441 static const int kMaxLength = kMaxSize - kHeaderSize; 2442 2443 private: 2444 DISALLOW_IMPLICIT_CONSTRUCTORS(ByteArray); 2445}; 2446 2447 2448// A PixelArray represents a fixed-size byte array with special semantics 2449// used for implementing the CanvasPixelArray object. Please see the 2450// specification at: 2451// http://www.whatwg.org/specs/web-apps/current-work/ 2452// multipage/the-canvas-element.html#canvaspixelarray 2453// In particular, write access clamps the value written to 0 or 255 if the 2454// value written is outside this range. 2455class PixelArray: public HeapObject { 2456 public: 2457 // [length]: length of the array. 2458 inline int length(); 2459 inline void set_length(int value); 2460 2461 // [external_pointer]: The pointer to the external memory area backing this 2462 // pixel array. 2463 DECL_ACCESSORS(external_pointer, uint8_t) // Pointer to the data store. 2464 2465 // Setter and getter. 2466 inline uint8_t get(int index); 2467 inline void set(int index, uint8_t value); 2468 2469 // This accessor applies the correct conversion from Smi, HeapNumber and 2470 // undefined and clamps the converted value between 0 and 255. 2471 Object* SetValue(uint32_t index, Object* value); 2472 2473 // Casting. 2474 static inline PixelArray* cast(Object* obj); 2475 2476#ifdef DEBUG 2477 void PixelArrayPrint(); 2478 void PixelArrayVerify(); 2479#endif // DEBUG 2480 2481 // Maximal acceptable length for a pixel array. 2482 static const int kMaxLength = 0x3fffffff; 2483 2484 // PixelArray headers are not quadword aligned. 2485 static const int kLengthOffset = HeapObject::kHeaderSize; 2486 static const int kExternalPointerOffset = 2487 POINTER_SIZE_ALIGN(kLengthOffset + kIntSize); 2488 static const int kHeaderSize = kExternalPointerOffset + kPointerSize; 2489 static const int kAlignedSize = OBJECT_POINTER_ALIGN(kHeaderSize); 2490 2491 private: 2492 DISALLOW_IMPLICIT_CONSTRUCTORS(PixelArray); 2493}; 2494 2495 2496// An ExternalArray represents a fixed-size array of primitive values 2497// which live outside the JavaScript heap. Its subclasses are used to 2498// implement the CanvasArray types being defined in the WebGL 2499// specification. As of this writing the first public draft is not yet 2500// available, but Khronos members can access the draft at: 2501// https://cvs.khronos.org/svn/repos/3dweb/trunk/doc/spec/WebGL-spec.html 2502// 2503// The semantics of these arrays differ from CanvasPixelArray. 2504// Out-of-range values passed to the setter are converted via a C 2505// cast, not clamping. Out-of-range indices cause exceptions to be 2506// raised rather than being silently ignored. 2507class ExternalArray: public HeapObject { 2508 public: 2509 // [length]: length of the array. 2510 inline int length(); 2511 inline void set_length(int value); 2512 2513 // [external_pointer]: The pointer to the external memory area backing this 2514 // external array. 2515 DECL_ACCESSORS(external_pointer, void) // Pointer to the data store. 2516 2517 // Casting. 2518 static inline ExternalArray* cast(Object* obj); 2519 2520 // Maximal acceptable length for an external array. 2521 static const int kMaxLength = 0x3fffffff; 2522 2523 // ExternalArray headers are not quadword aligned. 2524 static const int kLengthOffset = HeapObject::kHeaderSize; 2525 static const int kExternalPointerOffset = 2526 POINTER_SIZE_ALIGN(kLengthOffset + kIntSize); 2527 static const int kHeaderSize = kExternalPointerOffset + kPointerSize; 2528 static const int kAlignedSize = OBJECT_POINTER_ALIGN(kHeaderSize); 2529 2530 private: 2531 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalArray); 2532}; 2533 2534 2535class ExternalByteArray: public ExternalArray { 2536 public: 2537 // Setter and getter. 2538 inline int8_t get(int index); 2539 inline void set(int index, int8_t value); 2540 2541 // This accessor applies the correct conversion from Smi, HeapNumber 2542 // and undefined. 2543 Object* SetValue(uint32_t index, Object* value); 2544 2545 // Casting. 2546 static inline ExternalByteArray* cast(Object* obj); 2547 2548#ifdef DEBUG 2549 void ExternalByteArrayPrint(); 2550 void ExternalByteArrayVerify(); 2551#endif // DEBUG 2552 2553 private: 2554 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalByteArray); 2555}; 2556 2557 2558class ExternalUnsignedByteArray: public ExternalArray { 2559 public: 2560 // Setter and getter. 2561 inline uint8_t get(int index); 2562 inline void set(int index, uint8_t value); 2563 2564 // This accessor applies the correct conversion from Smi, HeapNumber 2565 // and undefined. 2566 Object* SetValue(uint32_t index, Object* value); 2567 2568 // Casting. 2569 static inline ExternalUnsignedByteArray* cast(Object* obj); 2570 2571#ifdef DEBUG 2572 void ExternalUnsignedByteArrayPrint(); 2573 void ExternalUnsignedByteArrayVerify(); 2574#endif // DEBUG 2575 2576 private: 2577 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalUnsignedByteArray); 2578}; 2579 2580 2581class ExternalShortArray: public ExternalArray { 2582 public: 2583 // Setter and getter. 2584 inline int16_t get(int index); 2585 inline void set(int index, int16_t value); 2586 2587 // This accessor applies the correct conversion from Smi, HeapNumber 2588 // and undefined. 2589 Object* SetValue(uint32_t index, Object* value); 2590 2591 // Casting. 2592 static inline ExternalShortArray* cast(Object* obj); 2593 2594#ifdef DEBUG 2595 void ExternalShortArrayPrint(); 2596 void ExternalShortArrayVerify(); 2597#endif // DEBUG 2598 2599 private: 2600 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalShortArray); 2601}; 2602 2603 2604class ExternalUnsignedShortArray: public ExternalArray { 2605 public: 2606 // Setter and getter. 2607 inline uint16_t get(int index); 2608 inline void set(int index, uint16_t value); 2609 2610 // This accessor applies the correct conversion from Smi, HeapNumber 2611 // and undefined. 2612 Object* SetValue(uint32_t index, Object* value); 2613 2614 // Casting. 2615 static inline ExternalUnsignedShortArray* cast(Object* obj); 2616 2617#ifdef DEBUG 2618 void ExternalUnsignedShortArrayPrint(); 2619 void ExternalUnsignedShortArrayVerify(); 2620#endif // DEBUG 2621 2622 private: 2623 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalUnsignedShortArray); 2624}; 2625 2626 2627class ExternalIntArray: public ExternalArray { 2628 public: 2629 // Setter and getter. 2630 inline int32_t get(int index); 2631 inline void set(int index, int32_t value); 2632 2633 // This accessor applies the correct conversion from Smi, HeapNumber 2634 // and undefined. 2635 Object* SetValue(uint32_t index, Object* value); 2636 2637 // Casting. 2638 static inline ExternalIntArray* cast(Object* obj); 2639 2640#ifdef DEBUG 2641 void ExternalIntArrayPrint(); 2642 void ExternalIntArrayVerify(); 2643#endif // DEBUG 2644 2645 private: 2646 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalIntArray); 2647}; 2648 2649 2650class ExternalUnsignedIntArray: public ExternalArray { 2651 public: 2652 // Setter and getter. 2653 inline uint32_t get(int index); 2654 inline void set(int index, uint32_t value); 2655 2656 // This accessor applies the correct conversion from Smi, HeapNumber 2657 // and undefined. 2658 Object* SetValue(uint32_t index, Object* value); 2659 2660 // Casting. 2661 static inline ExternalUnsignedIntArray* cast(Object* obj); 2662 2663#ifdef DEBUG 2664 void ExternalUnsignedIntArrayPrint(); 2665 void ExternalUnsignedIntArrayVerify(); 2666#endif // DEBUG 2667 2668 private: 2669 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalUnsignedIntArray); 2670}; 2671 2672 2673class ExternalFloatArray: public ExternalArray { 2674 public: 2675 // Setter and getter. 2676 inline float get(int index); 2677 inline void set(int index, float value); 2678 2679 // This accessor applies the correct conversion from Smi, HeapNumber 2680 // and undefined. 2681 Object* SetValue(uint32_t index, Object* value); 2682 2683 // Casting. 2684 static inline ExternalFloatArray* cast(Object* obj); 2685 2686#ifdef DEBUG 2687 void ExternalFloatArrayPrint(); 2688 void ExternalFloatArrayVerify(); 2689#endif // DEBUG 2690 2691 private: 2692 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalFloatArray); 2693}; 2694 2695 2696// Code describes objects with on-the-fly generated machine code. 2697class Code: public HeapObject { 2698 public: 2699 // Opaque data type for encapsulating code flags like kind, inline 2700 // cache state, and arguments count. 2701 enum Flags { }; 2702 2703 enum Kind { 2704 FUNCTION, 2705 STUB, 2706 BUILTIN, 2707 LOAD_IC, 2708 KEYED_LOAD_IC, 2709 CALL_IC, 2710 KEYED_CALL_IC, 2711 STORE_IC, 2712 KEYED_STORE_IC, 2713 BINARY_OP_IC, 2714 // No more than 16 kinds. The value currently encoded in four bits in 2715 // Flags. 2716 2717 // Pseudo-kinds. 2718 REGEXP = BUILTIN, 2719 FIRST_IC_KIND = LOAD_IC, 2720 LAST_IC_KIND = BINARY_OP_IC 2721 }; 2722 2723 enum { 2724 NUMBER_OF_KINDS = KEYED_STORE_IC + 1 2725 }; 2726 2727#ifdef ENABLE_DISASSEMBLER 2728 // Printing 2729 static const char* Kind2String(Kind kind); 2730 static const char* ICState2String(InlineCacheState state); 2731 static const char* PropertyType2String(PropertyType type); 2732 void Disassemble(const char* name); 2733#endif // ENABLE_DISASSEMBLER 2734 2735 // [instruction_size]: Size of the native instructions 2736 inline int instruction_size(); 2737 inline void set_instruction_size(int value); 2738 2739 // [relocation_info]: Code relocation information 2740 DECL_ACCESSORS(relocation_info, ByteArray) 2741 2742 // Unchecked accessor to be used during GC. 2743 inline ByteArray* unchecked_relocation_info(); 2744 2745 inline int relocation_size(); 2746 2747 // [sinfo_size]: Size of scope information. 2748 inline int sinfo_size(); 2749 inline void set_sinfo_size(int value); 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 // Returns the address of the scope information. 2820 inline byte* sinfo_start(); 2821 2822 // Relocate the code by delta bytes. Called to signal that this code 2823 // object has been moved by delta bytes. 2824 void Relocate(intptr_t delta); 2825 2826 // Migrate code described by desc. 2827 void CopyFrom(const CodeDesc& desc); 2828 2829 // Returns the object size for a given body and sinfo size (Used for 2830 // allocation). 2831 static int SizeFor(int body_size, int sinfo_size) { 2832 ASSERT_SIZE_TAG_ALIGNED(body_size); 2833 ASSERT_SIZE_TAG_ALIGNED(sinfo_size); 2834 return RoundUp(kHeaderSize + body_size + sinfo_size, kCodeAlignment); 2835 } 2836 2837 // Calculate the size of the code object to report for log events. This takes 2838 // the layout of the code object into account. 2839 int ExecutableSize() { 2840 // Check that the assumptions about the layout of the code object holds. 2841 ASSERT_EQ(static_cast<int>(instruction_start() - address()), 2842 Code::kHeaderSize); 2843 return instruction_size() + Code::kHeaderSize; 2844 } 2845 2846 // Locating source position. 2847 int SourcePosition(Address pc); 2848 int SourceStatementPosition(Address pc); 2849 2850 // Casting. 2851 static inline Code* cast(Object* obj); 2852 2853 // Dispatched behavior. 2854 int CodeSize() { return SizeFor(body_size(), sinfo_size()); } 2855 void CodeIterateBody(ObjectVisitor* v); 2856#ifdef DEBUG 2857 void CodePrint(); 2858 void CodeVerify(); 2859#endif 2860 // Code entry points are aligned to 32 bytes. 2861 static const int kCodeAlignmentBits = 5; 2862 static const int kCodeAlignment = 1 << kCodeAlignmentBits; 2863 static const int kCodeAlignmentMask = kCodeAlignment - 1; 2864 2865 // Layout description. 2866 static const int kInstructionSizeOffset = HeapObject::kHeaderSize; 2867 static const int kRelocationInfoOffset = kInstructionSizeOffset + kIntSize; 2868 static const int kSInfoSizeOffset = kRelocationInfoOffset + kPointerSize; 2869 static const int kFlagsOffset = kSInfoSizeOffset + kIntSize; 2870 static const int kKindSpecificFlagsOffset = kFlagsOffset + kIntSize; 2871 // Add padding to align the instruction start following right after 2872 // the Code object header. 2873 static const int kHeaderSize = 2874 (kKindSpecificFlagsOffset + kIntSize + kCodeAlignmentMask) & 2875 ~kCodeAlignmentMask; 2876 2877 // Byte offsets within kKindSpecificFlagsOffset. 2878 static const int kStubMajorKeyOffset = kKindSpecificFlagsOffset + 1; 2879 2880 // Flags layout. 2881 static const int kFlagsICStateShift = 0; 2882 static const int kFlagsICInLoopShift = 3; 2883 static const int kFlagsTypeShift = 4; 2884 static const int kFlagsKindShift = 7; 2885 static const int kFlagsICHolderShift = 11; 2886 static const int kFlagsArgumentsCountShift = 12; 2887 2888 static const int kFlagsICStateMask = 0x00000007; // 00000000111 2889 static const int kFlagsICInLoopMask = 0x00000008; // 00000001000 2890 static const int kFlagsTypeMask = 0x00000070; // 00001110000 2891 static const int kFlagsKindMask = 0x00000780; // 11110000000 2892 static const int kFlagsCacheInPrototypeMapMask = 0x00000800; 2893 static const int kFlagsArgumentsCountMask = 0xFFFFF000; 2894 2895 static const int kFlagsNotUsedInLookup = 2896 (kFlagsICInLoopMask | kFlagsTypeMask | kFlagsCacheInPrototypeMapMask); 2897 2898 private: 2899 DISALLOW_IMPLICIT_CONSTRUCTORS(Code); 2900}; 2901 2902 2903// All heap objects have a Map that describes their structure. 2904// A Map contains information about: 2905// - Size information about the object 2906// - How to iterate over an object (for garbage collection) 2907class Map: public HeapObject { 2908 public: 2909 // Instance size. 2910 inline int instance_size(); 2911 inline void set_instance_size(int value); 2912 2913 // Count of properties allocated in the object. 2914 inline int inobject_properties(); 2915 inline void set_inobject_properties(int value); 2916 2917 // Count of property fields pre-allocated in the object when first allocated. 2918 inline int pre_allocated_property_fields(); 2919 inline void set_pre_allocated_property_fields(int value); 2920 2921 // Instance type. 2922 inline InstanceType instance_type(); 2923 inline void set_instance_type(InstanceType value); 2924 2925 // Tells how many unused property fields are available in the 2926 // instance (only used for JSObject in fast mode). 2927 inline int unused_property_fields(); 2928 inline void set_unused_property_fields(int value); 2929 2930 // Bit field. 2931 inline byte bit_field(); 2932 inline void set_bit_field(byte value); 2933 2934 // Bit field 2. 2935 inline byte bit_field2(); 2936 inline void set_bit_field2(byte value); 2937 2938 // Tells whether the object in the prototype property will be used 2939 // for instances created from this function. If the prototype 2940 // property is set to a value that is not a JSObject, the prototype 2941 // property will not be used to create instances of the function. 2942 // See ECMA-262, 13.2.2. 2943 inline void set_non_instance_prototype(bool value); 2944 inline bool has_non_instance_prototype(); 2945 2946 // Tells whether function has special prototype property. If not, prototype 2947 // property will not be created when accessed (will return undefined), 2948 // and construction from this function will not be allowed. 2949 inline void set_function_with_prototype(bool value); 2950 inline bool function_with_prototype(); 2951 2952 // Tells whether the instance with this map should be ignored by the 2953 // __proto__ accessor. 2954 inline void set_is_hidden_prototype() { 2955 set_bit_field(bit_field() | (1 << kIsHiddenPrototype)); 2956 } 2957 2958 inline bool is_hidden_prototype() { 2959 return ((1 << kIsHiddenPrototype) & bit_field()) != 0; 2960 } 2961 2962 // Records and queries whether the instance has a named interceptor. 2963 inline void set_has_named_interceptor() { 2964 set_bit_field(bit_field() | (1 << kHasNamedInterceptor)); 2965 } 2966 2967 inline bool has_named_interceptor() { 2968 return ((1 << kHasNamedInterceptor) & bit_field()) != 0; 2969 } 2970 2971 // Records and queries whether the instance has an indexed interceptor. 2972 inline void set_has_indexed_interceptor() { 2973 set_bit_field(bit_field() | (1 << kHasIndexedInterceptor)); 2974 } 2975 2976 inline bool has_indexed_interceptor() { 2977 return ((1 << kHasIndexedInterceptor) & bit_field()) != 0; 2978 } 2979 2980 // Tells whether the instance is undetectable. 2981 // An undetectable object is a special class of JSObject: 'typeof' operator 2982 // returns undefined, ToBoolean returns false. Otherwise it behaves like 2983 // a normal JS object. It is useful for implementing undetectable 2984 // document.all in Firefox & Safari. 2985 // See https://bugzilla.mozilla.org/show_bug.cgi?id=248549. 2986 inline void set_is_undetectable() { 2987 set_bit_field(bit_field() | (1 << kIsUndetectable)); 2988 } 2989 2990 inline bool is_undetectable() { 2991 return ((1 << kIsUndetectable) & bit_field()) != 0; 2992 } 2993 2994 // Tells whether the instance has a call-as-function handler. 2995 inline void set_has_instance_call_handler() { 2996 set_bit_field(bit_field() | (1 << kHasInstanceCallHandler)); 2997 } 2998 2999 inline bool has_instance_call_handler() { 3000 return ((1 << kHasInstanceCallHandler) & bit_field()) != 0; 3001 } 3002 3003 inline void set_is_extensible(bool value); 3004 inline bool is_extensible(); 3005 3006 // Tells whether the instance has fast elements. 3007 void set_has_fast_elements(bool value) { 3008 if (value) { 3009 set_bit_field2(bit_field2() | (1 << kHasFastElements)); 3010 } else { 3011 set_bit_field2(bit_field2() & ~(1 << kHasFastElements)); 3012 } 3013 } 3014 3015 bool has_fast_elements() { 3016 return ((1 << kHasFastElements) & bit_field2()) != 0; 3017 } 3018 3019 // Tells whether the instance needs security checks when accessing its 3020 // properties. 3021 inline void set_is_access_check_needed(bool access_check_needed); 3022 inline bool is_access_check_needed(); 3023 3024 // [prototype]: implicit prototype object. 3025 DECL_ACCESSORS(prototype, Object) 3026 3027 // [constructor]: points back to the function responsible for this map. 3028 DECL_ACCESSORS(constructor, Object) 3029 3030 // [instance descriptors]: describes the object. 3031 DECL_ACCESSORS(instance_descriptors, DescriptorArray) 3032 3033 // [stub cache]: contains stubs compiled for this map. 3034 DECL_ACCESSORS(code_cache, Object) 3035 3036 Object* CopyDropDescriptors(); 3037 3038 // Returns a copy of the map, with all transitions dropped from the 3039 // instance descriptors. 3040 Object* CopyDropTransitions(); 3041 3042 // Returns this map if it has the fast elements bit set, otherwise 3043 // returns a copy of the map, with all transitions dropped from the 3044 // descriptors and the fast elements bit set. 3045 inline Object* GetFastElementsMap(); 3046 3047 // Returns this map if it has the fast elements bit cleared, 3048 // otherwise returns a copy of the map, with all transitions dropped 3049 // from the descriptors and the fast elements bit cleared. 3050 inline Object* GetSlowElementsMap(); 3051 3052 // Returns the property index for name (only valid for FAST MODE). 3053 int PropertyIndexFor(String* name); 3054 3055 // Returns the next free property index (only valid for FAST MODE). 3056 int NextFreePropertyIndex(); 3057 3058 // Returns the number of properties described in instance_descriptors. 3059 int NumberOfDescribedProperties(); 3060 3061 // Casting. 3062 static inline Map* cast(Object* obj); 3063 3064 // Locate an accessor in the instance descriptor. 3065 AccessorDescriptor* FindAccessor(String* name); 3066 3067 // Code cache operations. 3068 3069 // Clears the code cache. 3070 inline void ClearCodeCache(); 3071 3072 // Update code cache. 3073 Object* UpdateCodeCache(String* name, Code* code); 3074 3075 // Returns the found code or undefined if absent. 3076 Object* FindInCodeCache(String* name, Code::Flags flags); 3077 3078 // Returns the non-negative index of the code object if it is in the 3079 // cache and -1 otherwise. 3080 int IndexInCodeCache(Object* name, Code* code); 3081 3082 // Removes a code object from the code cache at the given index. 3083 void RemoveFromCodeCache(String* name, Code* code, int index); 3084 3085 // For every transition in this map, makes the transition's 3086 // target's prototype pointer point back to this map. 3087 // This is undone in MarkCompactCollector::ClearNonLiveTransitions(). 3088 void CreateBackPointers(); 3089 3090 // Set all map transitions from this map to dead maps to null. 3091 // Also, restore the original prototype on the targets of these 3092 // transitions, so that we do not process this map again while 3093 // following back pointers. 3094 void ClearNonLiveTransitions(Object* real_prototype); 3095 3096 // Dispatched behavior. 3097 void MapIterateBody(ObjectVisitor* v); 3098#ifdef DEBUG 3099 void MapPrint(); 3100 void MapVerify(); 3101#endif 3102 3103 static const int kMaxPreAllocatedPropertyFields = 255; 3104 3105 // Layout description. 3106 static const int kInstanceSizesOffset = HeapObject::kHeaderSize; 3107 static const int kInstanceAttributesOffset = kInstanceSizesOffset + kIntSize; 3108 static const int kPrototypeOffset = kInstanceAttributesOffset + kIntSize; 3109 static const int kConstructorOffset = kPrototypeOffset + kPointerSize; 3110 static const int kInstanceDescriptorsOffset = 3111 kConstructorOffset + kPointerSize; 3112 static const int kCodeCacheOffset = kInstanceDescriptorsOffset + kPointerSize; 3113 static const int kPadStart = kCodeCacheOffset + kPointerSize; 3114 static const int kSize = MAP_POINTER_ALIGN(kPadStart); 3115 3116 // Layout of pointer fields. Heap iteration code relies on them 3117 // being continiously allocated. 3118 static const int kPointerFieldsBeginOffset = Map::kPrototypeOffset; 3119 static const int kPointerFieldsEndOffset = 3120 Map::kCodeCacheOffset + kPointerSize; 3121 3122 // Byte offsets within kInstanceSizesOffset. 3123 static const int kInstanceSizeOffset = kInstanceSizesOffset + 0; 3124 static const int kInObjectPropertiesByte = 1; 3125 static const int kInObjectPropertiesOffset = 3126 kInstanceSizesOffset + kInObjectPropertiesByte; 3127 static const int kPreAllocatedPropertyFieldsByte = 2; 3128 static const int kPreAllocatedPropertyFieldsOffset = 3129 kInstanceSizesOffset + kPreAllocatedPropertyFieldsByte; 3130 // The byte at position 3 is not in use at the moment. 3131 3132 // Byte offsets within kInstanceAttributesOffset attributes. 3133 static const int kInstanceTypeOffset = kInstanceAttributesOffset + 0; 3134 static const int kUnusedPropertyFieldsOffset = kInstanceAttributesOffset + 1; 3135 static const int kBitFieldOffset = kInstanceAttributesOffset + 2; 3136 static const int kBitField2Offset = kInstanceAttributesOffset + 3; 3137 3138 STATIC_CHECK(kInstanceTypeOffset == Internals::kMapInstanceTypeOffset); 3139 3140 // Bit positions for bit field. 3141 static const int kUnused = 0; // To be used for marking recently used maps. 3142 static const int kHasNonInstancePrototype = 1; 3143 static const int kIsHiddenPrototype = 2; 3144 static const int kHasNamedInterceptor = 3; 3145 static const int kHasIndexedInterceptor = 4; 3146 static const int kIsUndetectable = 5; 3147 static const int kHasInstanceCallHandler = 6; 3148 static const int kIsAccessCheckNeeded = 7; 3149 3150 // Bit positions for bit field 2 3151 static const int kIsExtensible = 0; 3152 static const int kFunctionWithPrototype = 1; 3153 static const int kHasFastElements = 2; 3154 3155 // Layout of the default cache. It holds alternating name and code objects. 3156 static const int kCodeCacheEntrySize = 2; 3157 static const int kCodeCacheEntryNameOffset = 0; 3158 static const int kCodeCacheEntryCodeOffset = 1; 3159 3160 private: 3161 DISALLOW_IMPLICIT_CONSTRUCTORS(Map); 3162}; 3163 3164 3165// An abstract superclass, a marker class really, for simple structure classes. 3166// It doesn't carry much functionality but allows struct classes to me 3167// identified in the type system. 3168class Struct: public HeapObject { 3169 public: 3170 inline void InitializeBody(int object_size); 3171 static inline Struct* cast(Object* that); 3172}; 3173 3174 3175// Script describes a script which has been added to the VM. 3176class Script: public Struct { 3177 public: 3178 // Script types. 3179 enum Type { 3180 TYPE_NATIVE = 0, 3181 TYPE_EXTENSION = 1, 3182 TYPE_NORMAL = 2 3183 }; 3184 3185 // Script compilation types. 3186 enum CompilationType { 3187 COMPILATION_TYPE_HOST = 0, 3188 COMPILATION_TYPE_EVAL = 1, 3189 COMPILATION_TYPE_JSON = 2 3190 }; 3191 3192 // [source]: the script source. 3193 DECL_ACCESSORS(source, Object) 3194 3195 // [name]: the script name. 3196 DECL_ACCESSORS(name, Object) 3197 3198 // [id]: the script id. 3199 DECL_ACCESSORS(id, Object) 3200 3201 // [line_offset]: script line offset in resource from where it was extracted. 3202 DECL_ACCESSORS(line_offset, Smi) 3203 3204 // [column_offset]: script column offset in resource from where it was 3205 // extracted. 3206 DECL_ACCESSORS(column_offset, Smi) 3207 3208 // [data]: additional data associated with this script. 3209 DECL_ACCESSORS(data, Object) 3210 3211 // [context_data]: context data for the context this script was compiled in. 3212 DECL_ACCESSORS(context_data, Object) 3213 3214 // [wrapper]: the wrapper cache. 3215 DECL_ACCESSORS(wrapper, Proxy) 3216 3217 // [type]: the script type. 3218 DECL_ACCESSORS(type, Smi) 3219 3220 // [compilation]: how the the script was compiled. 3221 DECL_ACCESSORS(compilation_type, Smi) 3222 3223 // [line_ends]: FixedArray of line ends positions. 3224 DECL_ACCESSORS(line_ends, Object) 3225 3226 // [eval_from_shared]: for eval scripts the shared funcion info for the 3227 // function from which eval was called. 3228 DECL_ACCESSORS(eval_from_shared, Object) 3229 3230 // [eval_from_instructions_offset]: the instruction offset in the code for the 3231 // function from which eval was called where eval was called. 3232 DECL_ACCESSORS(eval_from_instructions_offset, Smi) 3233 3234 static inline Script* cast(Object* obj); 3235 3236 // If script source is an external string, check that the underlying 3237 // resource is accessible. Otherwise, always return true. 3238 inline bool HasValidSource(); 3239 3240#ifdef DEBUG 3241 void ScriptPrint(); 3242 void ScriptVerify(); 3243#endif 3244 3245 static const int kSourceOffset = HeapObject::kHeaderSize; 3246 static const int kNameOffset = kSourceOffset + kPointerSize; 3247 static const int kLineOffsetOffset = kNameOffset + kPointerSize; 3248 static const int kColumnOffsetOffset = kLineOffsetOffset + kPointerSize; 3249 static const int kDataOffset = kColumnOffsetOffset + kPointerSize; 3250 static const int kContextOffset = kDataOffset + kPointerSize; 3251 static const int kWrapperOffset = kContextOffset + kPointerSize; 3252 static const int kTypeOffset = kWrapperOffset + kPointerSize; 3253 static const int kCompilationTypeOffset = kTypeOffset + kPointerSize; 3254 static const int kLineEndsOffset = kCompilationTypeOffset + kPointerSize; 3255 static const int kIdOffset = kLineEndsOffset + kPointerSize; 3256 static const int kEvalFromSharedOffset = kIdOffset + kPointerSize; 3257 static const int kEvalFrominstructionsOffsetOffset = 3258 kEvalFromSharedOffset + kPointerSize; 3259 static const int kSize = kEvalFrominstructionsOffsetOffset + kPointerSize; 3260 3261 private: 3262 DISALLOW_IMPLICIT_CONSTRUCTORS(Script); 3263}; 3264 3265 3266// SharedFunctionInfo describes the JSFunction information that can be 3267// shared by multiple instances of the function. 3268class SharedFunctionInfo: public HeapObject { 3269 public: 3270 // [name]: Function name. 3271 DECL_ACCESSORS(name, Object) 3272 3273 // [code]: Function code. 3274 DECL_ACCESSORS(code, Code) 3275 3276 // [construct stub]: Code stub for constructing instances of this function. 3277 DECL_ACCESSORS(construct_stub, Code) 3278 3279 // Returns if this function has been compiled to native code yet. 3280 inline bool is_compiled(); 3281 3282 // [length]: The function length - usually the number of declared parameters. 3283 // Use up to 2^30 parameters. 3284 inline int length(); 3285 inline void set_length(int value); 3286 3287 // [formal parameter count]: The declared number of parameters. 3288 inline int formal_parameter_count(); 3289 inline void set_formal_parameter_count(int value); 3290 3291 // Set the formal parameter count so the function code will be 3292 // called without using argument adaptor frames. 3293 inline void DontAdaptArguments(); 3294 3295 // [expected_nof_properties]: Expected number of properties for the function. 3296 inline int expected_nof_properties(); 3297 inline void set_expected_nof_properties(int value); 3298 3299 // [instance class name]: class name for instances. 3300 DECL_ACCESSORS(instance_class_name, Object) 3301 3302 // [function data]: This field holds some additional data for function. 3303 // Currently it either has FunctionTemplateInfo to make benefit the API 3304 // or Smi identifying a custom call generator. 3305 // In the long run we don't want all functions to have this field but 3306 // we can fix that when we have a better model for storing hidden data 3307 // on objects. 3308 DECL_ACCESSORS(function_data, Object) 3309 3310 inline bool IsApiFunction(); 3311 inline FunctionTemplateInfo* get_api_func_data(); 3312 inline bool HasCustomCallGenerator(); 3313 inline int custom_call_generator_id(); 3314 3315 // [script info]: Script from which the function originates. 3316 DECL_ACCESSORS(script, Object) 3317 3318 // [num_literals]: Number of literals used by this function. 3319 inline int num_literals(); 3320 inline void set_num_literals(int value); 3321 3322 // [start_position_and_type]: Field used to store both the source code 3323 // position, whether or not the function is a function expression, 3324 // and whether or not the function is a toplevel function. The two 3325 // least significants bit indicates whether the function is an 3326 // expression and the rest contains the source code position. 3327 inline int start_position_and_type(); 3328 inline void set_start_position_and_type(int value); 3329 3330 // [debug info]: Debug information. 3331 DECL_ACCESSORS(debug_info, Object) 3332 3333 // [inferred name]: Name inferred from variable or property 3334 // assignment of this function. Used to facilitate debugging and 3335 // profiling of JavaScript code written in OO style, where almost 3336 // all functions are anonymous but are assigned to object 3337 // properties. 3338 DECL_ACCESSORS(inferred_name, String) 3339 3340 // Position of the 'function' token in the script source. 3341 inline int function_token_position(); 3342 inline void set_function_token_position(int function_token_position); 3343 3344 // Position of this function in the script source. 3345 inline int start_position(); 3346 inline void set_start_position(int start_position); 3347 3348 // End position of this function in the script source. 3349 inline int end_position(); 3350 inline void set_end_position(int end_position); 3351 3352 // Is this function a function expression in the source code. 3353 inline bool is_expression(); 3354 inline void set_is_expression(bool value); 3355 3356 // Is this function a top-level function (scripts, evals). 3357 inline bool is_toplevel(); 3358 inline void set_is_toplevel(bool value); 3359 3360 // Bit field containing various information collected by the compiler to 3361 // drive optimization. 3362 inline int compiler_hints(); 3363 inline void set_compiler_hints(int value); 3364 3365 // Add information on assignments of the form this.x = ...; 3366 void SetThisPropertyAssignmentsInfo( 3367 bool has_only_simple_this_property_assignments, 3368 FixedArray* this_property_assignments); 3369 3370 // Clear information on assignments of the form this.x = ...; 3371 void ClearThisPropertyAssignmentsInfo(); 3372 3373 // Indicate that this function only consists of assignments of the form 3374 // this.x = y; where y is either a constant or refers to an argument. 3375 inline bool has_only_simple_this_property_assignments(); 3376 3377 inline bool try_full_codegen(); 3378 inline void set_try_full_codegen(bool flag); 3379 3380 // Indicates if this function can be lazy compiled. 3381 // This is used to determine if we can safely flush code from a function 3382 // when doing GC if we expect that the function will no longer be used. 3383 inline bool allows_lazy_compilation(); 3384 inline void set_allows_lazy_compilation(bool flag); 3385 3386 // Check whether a inlined constructor can be generated with the given 3387 // prototype. 3388 bool CanGenerateInlineConstructor(Object* prototype); 3389 3390 // For functions which only contains this property assignments this provides 3391 // access to the names for the properties assigned. 3392 DECL_ACCESSORS(this_property_assignments, Object) 3393 inline int this_property_assignments_count(); 3394 inline void set_this_property_assignments_count(int value); 3395 String* GetThisPropertyAssignmentName(int index); 3396 bool IsThisPropertyAssignmentArgument(int index); 3397 int GetThisPropertyAssignmentArgument(int index); 3398 Object* GetThisPropertyAssignmentConstant(int index); 3399 3400 // [source code]: Source code for the function. 3401 bool HasSourceCode(); 3402 Object* GetSourceCode(); 3403 3404 // Calculate the instance size. 3405 int CalculateInstanceSize(); 3406 3407 // Calculate the number of in-object properties. 3408 int CalculateInObjectProperties(); 3409 3410 // Dispatched behavior. 3411 void SharedFunctionInfoIterateBody(ObjectVisitor* v); 3412 // Set max_length to -1 for unlimited length. 3413 void SourceCodePrint(StringStream* accumulator, int max_length); 3414#ifdef DEBUG 3415 void SharedFunctionInfoPrint(); 3416 void SharedFunctionInfoVerify(); 3417#endif 3418 3419 // Casting. 3420 static inline SharedFunctionInfo* cast(Object* obj); 3421 3422 // Constants. 3423 static const int kDontAdaptArgumentsSentinel = -1; 3424 3425 // Layout description. 3426 // Pointer fields. 3427 static const int kNameOffset = HeapObject::kHeaderSize; 3428 static const int kCodeOffset = kNameOffset + kPointerSize; 3429 static const int kConstructStubOffset = kCodeOffset + kPointerSize; 3430 static const int kInstanceClassNameOffset = 3431 kConstructStubOffset + kPointerSize; 3432 static const int kFunctionDataOffset = 3433 kInstanceClassNameOffset + kPointerSize; 3434 static const int kScriptOffset = kFunctionDataOffset + kPointerSize; 3435 static const int kDebugInfoOffset = kScriptOffset + kPointerSize; 3436 static const int kInferredNameOffset = kDebugInfoOffset + kPointerSize; 3437 static const int kThisPropertyAssignmentsOffset = 3438 kInferredNameOffset + kPointerSize; 3439#if V8_HOST_ARCH_32_BIT 3440 // Smi fields. 3441 static const int kLengthOffset = 3442 kThisPropertyAssignmentsOffset + kPointerSize; 3443 static const int kFormalParameterCountOffset = kLengthOffset + kPointerSize; 3444 static const int kExpectedNofPropertiesOffset = 3445 kFormalParameterCountOffset + kPointerSize; 3446 static const int kNumLiteralsOffset = 3447 kExpectedNofPropertiesOffset + kPointerSize; 3448 static const int kStartPositionAndTypeOffset = 3449 kNumLiteralsOffset + kPointerSize; 3450 static const int kEndPositionOffset = 3451 kStartPositionAndTypeOffset + kPointerSize; 3452 static const int kFunctionTokenPositionOffset = 3453 kEndPositionOffset + kPointerSize; 3454 static const int kCompilerHintsOffset = 3455 kFunctionTokenPositionOffset + kPointerSize; 3456 static const int kThisPropertyAssignmentsCountOffset = 3457 kCompilerHintsOffset + kPointerSize; 3458 // Total size. 3459 static const int kSize = kThisPropertyAssignmentsCountOffset + kPointerSize; 3460#else 3461 // The only reason to use smi fields instead of int fields 3462 // is to allow interation without maps decoding during 3463 // garbage collections. 3464 // To avoid wasting space on 64-bit architectures we use 3465 // the following trick: we group integer fields into pairs 3466 // First integer in each pair is shifted left by 1. 3467 // By doing this we guarantee that LSB of each kPointerSize aligned 3468 // word is not set and thus this word cannot be treated as pointer 3469 // to HeapObject during old space traversal. 3470 static const int kLengthOffset = 3471 kThisPropertyAssignmentsOffset + kPointerSize; 3472 static const int kFormalParameterCountOffset = 3473 kLengthOffset + kIntSize; 3474 3475 static const int kExpectedNofPropertiesOffset = 3476 kFormalParameterCountOffset + kIntSize; 3477 static const int kNumLiteralsOffset = 3478 kExpectedNofPropertiesOffset + kIntSize; 3479 3480 static const int kEndPositionOffset = 3481 kNumLiteralsOffset + kIntSize; 3482 static const int kStartPositionAndTypeOffset = 3483 kEndPositionOffset + kIntSize; 3484 3485 static const int kFunctionTokenPositionOffset = 3486 kStartPositionAndTypeOffset + kIntSize; 3487 static const int kCompilerHintsOffset = 3488 kFunctionTokenPositionOffset + kIntSize; 3489 3490 static const int kThisPropertyAssignmentsCountOffset = 3491 kCompilerHintsOffset + kIntSize; 3492 3493 // Total size. 3494 static const int kSize = kThisPropertyAssignmentsCountOffset + kIntSize; 3495 3496#endif 3497 static const int kAlignedSize = POINTER_SIZE_ALIGN(kSize); 3498 3499 private: 3500 // Bit positions in start_position_and_type. 3501 // The source code start position is in the 30 most significant bits of 3502 // the start_position_and_type field. 3503 static const int kIsExpressionBit = 0; 3504 static const int kIsTopLevelBit = 1; 3505 static const int kStartPositionShift = 2; 3506 static const int kStartPositionMask = ~((1 << kStartPositionShift) - 1); 3507 3508 // Bit positions in compiler_hints. 3509 static const int kHasOnlySimpleThisPropertyAssignments = 0; 3510 static const int kTryFullCodegen = 1; 3511 static const int kAllowLazyCompilation = 2; 3512 3513 DISALLOW_IMPLICIT_CONSTRUCTORS(SharedFunctionInfo); 3514}; 3515 3516 3517// JSFunction describes JavaScript functions. 3518class JSFunction: public JSObject { 3519 public: 3520 // [prototype_or_initial_map]: 3521 DECL_ACCESSORS(prototype_or_initial_map, Object) 3522 3523 // [shared_function_info]: The information about the function that 3524 // can be shared by instances. 3525 DECL_ACCESSORS(shared, SharedFunctionInfo) 3526 3527 // [context]: The context for this function. 3528 inline Context* context(); 3529 inline Object* unchecked_context(); 3530 inline void set_context(Object* context); 3531 3532 // [code]: The generated code object for this function. Executed 3533 // when the function is invoked, e.g. foo() or new foo(). See 3534 // [[Call]] and [[Construct]] description in ECMA-262, section 3535 // 8.6.2, page 27. 3536 inline Code* code(); 3537 inline void set_code(Code* value); 3538 3539 // Tells whether this function is builtin. 3540 inline bool IsBuiltin(); 3541 3542 // [literals]: Fixed array holding the materialized literals. 3543 // 3544 // If the function contains object, regexp or array literals, the 3545 // literals array prefix contains the object, regexp, and array 3546 // function to be used when creating these literals. This is 3547 // necessary so that we do not dynamically lookup the object, regexp 3548 // or array functions. Performing a dynamic lookup, we might end up 3549 // using the functions from a new context that we should not have 3550 // access to. 3551 DECL_ACCESSORS(literals, FixedArray) 3552 3553 // The initial map for an object created by this constructor. 3554 inline Map* initial_map(); 3555 inline void set_initial_map(Map* value); 3556 inline bool has_initial_map(); 3557 3558 // Get and set the prototype property on a JSFunction. If the 3559 // function has an initial map the prototype is set on the initial 3560 // map. Otherwise, the prototype is put in the initial map field 3561 // until an initial map is needed. 3562 inline bool has_prototype(); 3563 inline bool has_instance_prototype(); 3564 inline Object* prototype(); 3565 inline Object* instance_prototype(); 3566 Object* SetInstancePrototype(Object* value); 3567 Object* SetPrototype(Object* value); 3568 3569 // After prototype is removed, it will not be created when accessed, and 3570 // [[Construct]] from this function will not be allowed. 3571 Object* RemovePrototype(); 3572 inline bool should_have_prototype(); 3573 3574 // Accessor for this function's initial map's [[class]] 3575 // property. This is primarily used by ECMA native functions. This 3576 // method sets the class_name field of this function's initial map 3577 // to a given value. It creates an initial map if this function does 3578 // not have one. Note that this method does not copy the initial map 3579 // if it has one already, but simply replaces it with the new value. 3580 // Instances created afterwards will have a map whose [[class]] is 3581 // set to 'value', but there is no guarantees on instances created 3582 // before. 3583 Object* SetInstanceClassName(String* name); 3584 3585 // Returns if this function has been compiled to native code yet. 3586 inline bool is_compiled(); 3587 3588 // Casting. 3589 static inline JSFunction* cast(Object* obj); 3590 3591 // Dispatched behavior. 3592#ifdef DEBUG 3593 void JSFunctionPrint(); 3594 void JSFunctionVerify(); 3595#endif 3596 3597 // Returns the number of allocated literals. 3598 inline int NumberOfLiterals(); 3599 3600 // Retrieve the global context from a function's literal array. 3601 static Context* GlobalContextFromLiterals(FixedArray* literals); 3602 3603 // Layout descriptors. 3604 static const int kPrototypeOrInitialMapOffset = JSObject::kHeaderSize; 3605 static const int kSharedFunctionInfoOffset = 3606 kPrototypeOrInitialMapOffset + kPointerSize; 3607 static const int kContextOffset = kSharedFunctionInfoOffset + kPointerSize; 3608 static const int kLiteralsOffset = kContextOffset + kPointerSize; 3609 static const int kSize = kLiteralsOffset + kPointerSize; 3610 3611 // Layout of the literals array. 3612 static const int kLiteralsPrefixSize = 1; 3613 static const int kLiteralGlobalContextIndex = 0; 3614 private: 3615 DISALLOW_IMPLICIT_CONSTRUCTORS(JSFunction); 3616}; 3617 3618 3619// JSGlobalProxy's prototype must be a JSGlobalObject or null, 3620// and the prototype is hidden. JSGlobalProxy always delegates 3621// property accesses to its prototype if the prototype is not null. 3622// 3623// A JSGlobalProxy can be reinitialized which will preserve its identity. 3624// 3625// Accessing a JSGlobalProxy requires security check. 3626 3627class JSGlobalProxy : public JSObject { 3628 public: 3629 // [context]: the owner global context of this proxy object. 3630 // It is null value if this object is not used by any context. 3631 DECL_ACCESSORS(context, Object) 3632 3633 // Casting. 3634 static inline JSGlobalProxy* cast(Object* obj); 3635 3636 // Dispatched behavior. 3637#ifdef DEBUG 3638 void JSGlobalProxyPrint(); 3639 void JSGlobalProxyVerify(); 3640#endif 3641 3642 // Layout description. 3643 static const int kContextOffset = JSObject::kHeaderSize; 3644 static const int kSize = kContextOffset + kPointerSize; 3645 3646 private: 3647 3648 DISALLOW_IMPLICIT_CONSTRUCTORS(JSGlobalProxy); 3649}; 3650 3651 3652// Forward declaration. 3653class JSBuiltinsObject; 3654 3655// Common super class for JavaScript global objects and the special 3656// builtins global objects. 3657class GlobalObject: public JSObject { 3658 public: 3659 // [builtins]: the object holding the runtime routines written in JS. 3660 DECL_ACCESSORS(builtins, JSBuiltinsObject) 3661 3662 // [global context]: the global context corresponding to this global object. 3663 DECL_ACCESSORS(global_context, Context) 3664 3665 // [global receiver]: the global receiver object of the context 3666 DECL_ACCESSORS(global_receiver, JSObject) 3667 3668 // Retrieve the property cell used to store a property. 3669 Object* GetPropertyCell(LookupResult* result); 3670 3671 // Ensure that the global object has a cell for the given property name. 3672 Object* EnsurePropertyCell(String* name); 3673 3674 // Casting. 3675 static inline GlobalObject* cast(Object* obj); 3676 3677 // Layout description. 3678 static const int kBuiltinsOffset = JSObject::kHeaderSize; 3679 static const int kGlobalContextOffset = kBuiltinsOffset + kPointerSize; 3680 static const int kGlobalReceiverOffset = kGlobalContextOffset + kPointerSize; 3681 static const int kHeaderSize = kGlobalReceiverOffset + kPointerSize; 3682 3683 private: 3684 friend class AGCCVersionRequiresThisClassToHaveAFriendSoHereItIs; 3685 3686 DISALLOW_IMPLICIT_CONSTRUCTORS(GlobalObject); 3687}; 3688 3689 3690// JavaScript global object. 3691class JSGlobalObject: public GlobalObject { 3692 public: 3693 3694 // Casting. 3695 static inline JSGlobalObject* cast(Object* obj); 3696 3697 // Dispatched behavior. 3698#ifdef DEBUG 3699 void JSGlobalObjectPrint(); 3700 void JSGlobalObjectVerify(); 3701#endif 3702 3703 // Layout description. 3704 static const int kSize = GlobalObject::kHeaderSize; 3705 3706 private: 3707 DISALLOW_IMPLICIT_CONSTRUCTORS(JSGlobalObject); 3708}; 3709 3710 3711// Builtins global object which holds the runtime routines written in 3712// JavaScript. 3713class JSBuiltinsObject: public GlobalObject { 3714 public: 3715 // Accessors for the runtime routines written in JavaScript. 3716 inline Object* javascript_builtin(Builtins::JavaScript id); 3717 inline void set_javascript_builtin(Builtins::JavaScript id, Object* value); 3718 3719 // Accessors for code of the runtime routines written in JavaScript. 3720 inline Code* javascript_builtin_code(Builtins::JavaScript id); 3721 inline void set_javascript_builtin_code(Builtins::JavaScript id, Code* value); 3722 3723 // Casting. 3724 static inline JSBuiltinsObject* cast(Object* obj); 3725 3726 // Dispatched behavior. 3727#ifdef DEBUG 3728 void JSBuiltinsObjectPrint(); 3729 void JSBuiltinsObjectVerify(); 3730#endif 3731 3732 // Layout description. The size of the builtins object includes 3733 // room for two pointers per runtime routine written in javascript 3734 // (function and code object). 3735 static const int kJSBuiltinsCount = Builtins::id_count; 3736 static const int kJSBuiltinsOffset = GlobalObject::kHeaderSize; 3737 static const int kJSBuiltinsCodeOffset = 3738 GlobalObject::kHeaderSize + (kJSBuiltinsCount * kPointerSize); 3739 static const int kSize = 3740 kJSBuiltinsCodeOffset + (kJSBuiltinsCount * kPointerSize); 3741 3742 static int OffsetOfFunctionWithId(Builtins::JavaScript id) { 3743 return kJSBuiltinsOffset + id * kPointerSize; 3744 } 3745 3746 static int OffsetOfCodeWithId(Builtins::JavaScript id) { 3747 return kJSBuiltinsCodeOffset + id * kPointerSize; 3748 } 3749 3750 private: 3751 DISALLOW_IMPLICIT_CONSTRUCTORS(JSBuiltinsObject); 3752}; 3753 3754 3755// Representation for JS Wrapper objects, String, Number, Boolean, Date, etc. 3756class JSValue: public JSObject { 3757 public: 3758 // [value]: the object being wrapped. 3759 DECL_ACCESSORS(value, Object) 3760 3761 // Casting. 3762 static inline JSValue* cast(Object* obj); 3763 3764 // Dispatched behavior. 3765#ifdef DEBUG 3766 void JSValuePrint(); 3767 void JSValueVerify(); 3768#endif 3769 3770 // Layout description. 3771 static const int kValueOffset = JSObject::kHeaderSize; 3772 static const int kSize = kValueOffset + kPointerSize; 3773 3774 private: 3775 DISALLOW_IMPLICIT_CONSTRUCTORS(JSValue); 3776}; 3777 3778// Regular expressions 3779// The regular expression holds a single reference to a FixedArray in 3780// the kDataOffset field. 3781// The FixedArray contains the following data: 3782// - tag : type of regexp implementation (not compiled yet, atom or irregexp) 3783// - reference to the original source string 3784// - reference to the original flag string 3785// If it is an atom regexp 3786// - a reference to a literal string to search for 3787// If it is an irregexp regexp: 3788// - a reference to code for ASCII inputs (bytecode or compiled). 3789// - a reference to code for UC16 inputs (bytecode or compiled). 3790// - max number of registers used by irregexp implementations. 3791// - number of capture registers (output values) of the regexp. 3792class JSRegExp: public JSObject { 3793 public: 3794 // Meaning of Type: 3795 // NOT_COMPILED: Initial value. No data has been stored in the JSRegExp yet. 3796 // ATOM: A simple string to match against using an indexOf operation. 3797 // IRREGEXP: Compiled with Irregexp. 3798 // IRREGEXP_NATIVE: Compiled to native code with Irregexp. 3799 enum Type { NOT_COMPILED, ATOM, IRREGEXP }; 3800 enum Flag { NONE = 0, GLOBAL = 1, IGNORE_CASE = 2, MULTILINE = 4 }; 3801 3802 class Flags { 3803 public: 3804 explicit Flags(uint32_t value) : value_(value) { } 3805 bool is_global() { return (value_ & GLOBAL) != 0; } 3806 bool is_ignore_case() { return (value_ & IGNORE_CASE) != 0; } 3807 bool is_multiline() { return (value_ & MULTILINE) != 0; } 3808 uint32_t value() { return value_; } 3809 private: 3810 uint32_t value_; 3811 }; 3812 3813 DECL_ACCESSORS(data, Object) 3814 3815 inline Type TypeTag(); 3816 inline int CaptureCount(); 3817 inline Flags GetFlags(); 3818 inline String* Pattern(); 3819 inline Object* DataAt(int index); 3820 // Set implementation data after the object has been prepared. 3821 inline void SetDataAt(int index, Object* value); 3822 static int code_index(bool is_ascii) { 3823 if (is_ascii) { 3824 return kIrregexpASCIICodeIndex; 3825 } else { 3826 return kIrregexpUC16CodeIndex; 3827 } 3828 } 3829 3830 static inline JSRegExp* cast(Object* obj); 3831 3832 // Dispatched behavior. 3833#ifdef DEBUG 3834 void JSRegExpVerify(); 3835#endif 3836 3837 static const int kDataOffset = JSObject::kHeaderSize; 3838 static const int kSize = kDataOffset + kPointerSize; 3839 3840 // Indices in the data array. 3841 static const int kTagIndex = 0; 3842 static const int kSourceIndex = kTagIndex + 1; 3843 static const int kFlagsIndex = kSourceIndex + 1; 3844 static const int kDataIndex = kFlagsIndex + 1; 3845 // The data fields are used in different ways depending on the 3846 // value of the tag. 3847 // Atom regexps (literal strings). 3848 static const int kAtomPatternIndex = kDataIndex; 3849 3850 static const int kAtomDataSize = kAtomPatternIndex + 1; 3851 3852 // Irregexp compiled code or bytecode for ASCII. If compilation 3853 // fails, this fields hold an exception object that should be 3854 // thrown if the regexp is used again. 3855 static const int kIrregexpASCIICodeIndex = kDataIndex; 3856 // Irregexp compiled code or bytecode for UC16. If compilation 3857 // fails, this fields hold an exception object that should be 3858 // thrown if the regexp is used again. 3859 static const int kIrregexpUC16CodeIndex = kDataIndex + 1; 3860 // Maximal number of registers used by either ASCII or UC16. 3861 // Only used to check that there is enough stack space 3862 static const int kIrregexpMaxRegisterCountIndex = kDataIndex + 2; 3863 // Number of captures in the compiled regexp. 3864 static const int kIrregexpCaptureCountIndex = kDataIndex + 3; 3865 3866 static const int kIrregexpDataSize = kIrregexpCaptureCountIndex + 1; 3867 3868 // Offsets directly into the data fixed array. 3869 static const int kDataTagOffset = 3870 FixedArray::kHeaderSize + kTagIndex * kPointerSize; 3871 static const int kDataAsciiCodeOffset = 3872 FixedArray::kHeaderSize + kIrregexpASCIICodeIndex * kPointerSize; 3873 static const int kDataUC16CodeOffset = 3874 FixedArray::kHeaderSize + kIrregexpUC16CodeIndex * kPointerSize; 3875 static const int kIrregexpCaptureCountOffset = 3876 FixedArray::kHeaderSize + kIrregexpCaptureCountIndex * kPointerSize; 3877 3878 // In-object fields. 3879 static const int kSourceFieldIndex = 0; 3880 static const int kGlobalFieldIndex = 1; 3881 static const int kIgnoreCaseFieldIndex = 2; 3882 static const int kMultilineFieldIndex = 3; 3883 static const int kLastIndexFieldIndex = 4; 3884}; 3885 3886 3887class CompilationCacheShape { 3888 public: 3889 static inline bool IsMatch(HashTableKey* key, Object* value) { 3890 return key->IsMatch(value); 3891 } 3892 3893 static inline uint32_t Hash(HashTableKey* key) { 3894 return key->Hash(); 3895 } 3896 3897 static inline uint32_t HashForObject(HashTableKey* key, Object* object) { 3898 return key->HashForObject(object); 3899 } 3900 3901 static Object* AsObject(HashTableKey* key) { 3902 return key->AsObject(); 3903 } 3904 3905 static const int kPrefixSize = 0; 3906 static const int kEntrySize = 2; 3907}; 3908 3909 3910class CompilationCacheTable: public HashTable<CompilationCacheShape, 3911 HashTableKey*> { 3912 public: 3913 // Find cached value for a string key, otherwise return null. 3914 Object* Lookup(String* src); 3915 Object* LookupEval(String* src, Context* context); 3916 Object* LookupRegExp(String* source, JSRegExp::Flags flags); 3917 Object* Put(String* src, Object* value); 3918 Object* PutEval(String* src, Context* context, Object* value); 3919 Object* PutRegExp(String* src, JSRegExp::Flags flags, FixedArray* value); 3920 3921 static inline CompilationCacheTable* cast(Object* obj); 3922 3923 private: 3924 DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationCacheTable); 3925}; 3926 3927 3928class CodeCache: public Struct { 3929 public: 3930 DECL_ACCESSORS(default_cache, FixedArray) 3931 DECL_ACCESSORS(normal_type_cache, Object) 3932 3933 // Add the code object to the cache. 3934 Object* Update(String* name, Code* code); 3935 3936 // Lookup code object in the cache. Returns code object if found and undefined 3937 // if not. 3938 Object* Lookup(String* name, Code::Flags flags); 3939 3940 // Get the internal index of a code object in the cache. Returns -1 if the 3941 // code object is not in that cache. This index can be used to later call 3942 // RemoveByIndex. The cache cannot be modified between a call to GetIndex and 3943 // RemoveByIndex. 3944 int GetIndex(Object* name, Code* code); 3945 3946 // Remove an object from the cache with the provided internal index. 3947 void RemoveByIndex(Object* name, Code* code, int index); 3948 3949 static inline CodeCache* cast(Object* obj); 3950 3951#ifdef DEBUG 3952 void CodeCachePrint(); 3953 void CodeCacheVerify(); 3954#endif 3955 3956 static const int kDefaultCacheOffset = HeapObject::kHeaderSize; 3957 static const int kNormalTypeCacheOffset = 3958 kDefaultCacheOffset + kPointerSize; 3959 static const int kSize = kNormalTypeCacheOffset + kPointerSize; 3960 3961 private: 3962 Object* UpdateDefaultCache(String* name, Code* code); 3963 Object* UpdateNormalTypeCache(String* name, Code* code); 3964 Object* LookupDefaultCache(String* name, Code::Flags flags); 3965 Object* LookupNormalTypeCache(String* name, Code::Flags flags); 3966 3967 // Code cache layout of the default cache. Elements are alternating name and 3968 // code objects for non normal load/store/call IC's. 3969 static const int kCodeCacheEntrySize = 2; 3970 static const int kCodeCacheEntryNameOffset = 0; 3971 static const int kCodeCacheEntryCodeOffset = 1; 3972 3973 DISALLOW_IMPLICIT_CONSTRUCTORS(CodeCache); 3974}; 3975 3976 3977class CodeCacheHashTableShape { 3978 public: 3979 static inline bool IsMatch(HashTableKey* key, Object* value) { 3980 return key->IsMatch(value); 3981 } 3982 3983 static inline uint32_t Hash(HashTableKey* key) { 3984 return key->Hash(); 3985 } 3986 3987 static inline uint32_t HashForObject(HashTableKey* key, Object* object) { 3988 return key->HashForObject(object); 3989 } 3990 3991 static Object* AsObject(HashTableKey* key) { 3992 return key->AsObject(); 3993 } 3994 3995 static const int kPrefixSize = 0; 3996 static const int kEntrySize = 2; 3997}; 3998 3999 4000class CodeCacheHashTable: public HashTable<CodeCacheHashTableShape, 4001 HashTableKey*> { 4002 public: 4003 Object* Lookup(String* name, Code::Flags flags); 4004 Object* Put(String* name, Code* code); 4005 4006 int GetIndex(String* name, Code::Flags flags); 4007 void RemoveByIndex(int index); 4008 4009 static inline CodeCacheHashTable* cast(Object* obj); 4010 4011 // Initial size of the fixed array backing the hash table. 4012 static const int kInitialSize = 64; 4013 4014 private: 4015 DISALLOW_IMPLICIT_CONSTRUCTORS(CodeCacheHashTable); 4016}; 4017 4018 4019enum AllowNullsFlag {ALLOW_NULLS, DISALLOW_NULLS}; 4020enum RobustnessFlag {ROBUST_STRING_TRAVERSAL, FAST_STRING_TRAVERSAL}; 4021 4022 4023class StringHasher { 4024 public: 4025 inline StringHasher(int length); 4026 4027 // Returns true if the hash of this string can be computed without 4028 // looking at the contents. 4029 inline bool has_trivial_hash(); 4030 4031 // Add a character to the hash and update the array index calculation. 4032 inline void AddCharacter(uc32 c); 4033 4034 // Adds a character to the hash but does not update the array index 4035 // calculation. This can only be called when it has been verified 4036 // that the input is not an array index. 4037 inline void AddCharacterNoIndex(uc32 c); 4038 4039 // Returns the value to store in the hash field of a string with 4040 // the given length and contents. 4041 uint32_t GetHashField(); 4042 4043 // Returns true if the characters seen so far make up a legal array 4044 // index. 4045 bool is_array_index() { return is_array_index_; } 4046 4047 bool is_valid() { return is_valid_; } 4048 4049 void invalidate() { is_valid_ = false; } 4050 4051 private: 4052 4053 uint32_t array_index() { 4054 ASSERT(is_array_index()); 4055 return array_index_; 4056 } 4057 4058 inline uint32_t GetHash(); 4059 4060 int length_; 4061 uint32_t raw_running_hash_; 4062 uint32_t array_index_; 4063 bool is_array_index_; 4064 bool is_first_char_; 4065 bool is_valid_; 4066 friend class TwoCharHashTableKey; 4067}; 4068 4069 4070// The characteristics of a string are stored in its map. Retrieving these 4071// few bits of information is moderately expensive, involving two memory 4072// loads where the second is dependent on the first. To improve efficiency 4073// the shape of the string is given its own class so that it can be retrieved 4074// once and used for several string operations. A StringShape is small enough 4075// to be passed by value and is immutable, but be aware that flattening a 4076// string can potentially alter its shape. Also be aware that a GC caused by 4077// something else can alter the shape of a string due to ConsString 4078// shortcutting. Keeping these restrictions in mind has proven to be error- 4079// prone and so we no longer put StringShapes in variables unless there is a 4080// concrete performance benefit at that particular point in the code. 4081class StringShape BASE_EMBEDDED { 4082 public: 4083 inline explicit StringShape(String* s); 4084 inline explicit StringShape(Map* s); 4085 inline explicit StringShape(InstanceType t); 4086 inline bool IsSequential(); 4087 inline bool IsExternal(); 4088 inline bool IsCons(); 4089 inline bool IsExternalAscii(); 4090 inline bool IsExternalTwoByte(); 4091 inline bool IsSequentialAscii(); 4092 inline bool IsSequentialTwoByte(); 4093 inline bool IsSymbol(); 4094 inline StringRepresentationTag representation_tag(); 4095 inline uint32_t full_representation_tag(); 4096 inline uint32_t size_tag(); 4097#ifdef DEBUG 4098 inline uint32_t type() { return type_; } 4099 inline void invalidate() { valid_ = false; } 4100 inline bool valid() { return valid_; } 4101#else 4102 inline void invalidate() { } 4103#endif 4104 private: 4105 uint32_t type_; 4106#ifdef DEBUG 4107 inline void set_valid() { valid_ = true; } 4108 bool valid_; 4109#else 4110 inline void set_valid() { } 4111#endif 4112}; 4113 4114 4115// The String abstract class captures JavaScript string values: 4116// 4117// Ecma-262: 4118// 4.3.16 String Value 4119// A string value is a member of the type String and is a finite 4120// ordered sequence of zero or more 16-bit unsigned integer values. 4121// 4122// All string values have a length field. 4123class String: public HeapObject { 4124 public: 4125 // Get and set the length of the string. 4126 inline int length(); 4127 inline void set_length(int value); 4128 4129 // Get and set the hash field of the string. 4130 inline uint32_t hash_field(); 4131 inline void set_hash_field(uint32_t value); 4132 4133 inline bool IsAsciiRepresentation(); 4134 inline bool IsTwoByteRepresentation(); 4135 4136 // Returns whether this string has ascii chars, i.e. all of them can 4137 // be ascii encoded. This might be the case even if the string is 4138 // two-byte. Such strings may appear when the embedder prefers 4139 // two-byte external representations even for ascii data. 4140 // 4141 // NOTE: this should be considered only a hint. False negatives are 4142 // possible. 4143 inline bool HasOnlyAsciiChars(); 4144 4145 // Get and set individual two byte chars in the string. 4146 inline void Set(int index, uint16_t value); 4147 // Get individual two byte char in the string. Repeated calls 4148 // to this method are not efficient unless the string is flat. 4149 inline uint16_t Get(int index); 4150 4151 // Try to flatten the string. Checks first inline to see if it is 4152 // necessary. Does nothing if the string is not a cons string. 4153 // Flattening allocates a sequential string with the same data as 4154 // the given string and mutates the cons string to a degenerate 4155 // form, where the first component is the new sequential string and 4156 // the second component is the empty string. If allocation fails, 4157 // this function returns a failure. If flattening succeeds, this 4158 // function returns the sequential string that is now the first 4159 // component of the cons string. 4160 // 4161 // Degenerate cons strings are handled specially by the garbage 4162 // collector (see IsShortcutCandidate). 4163 // 4164 // Use FlattenString from Handles.cc to flatten even in case an 4165 // allocation failure happens. 4166 inline Object* TryFlatten(PretenureFlag pretenure = NOT_TENURED); 4167 4168 // Convenience function. Has exactly the same behavior as 4169 // TryFlatten(), except in the case of failure returns the original 4170 // string. 4171 inline String* TryFlattenGetString(PretenureFlag pretenure = NOT_TENURED); 4172 4173 Vector<const char> ToAsciiVector(); 4174 Vector<const uc16> ToUC16Vector(); 4175 4176 // Mark the string as an undetectable object. It only applies to 4177 // ascii and two byte string types. 4178 bool MarkAsUndetectable(); 4179 4180 // Return a substring. 4181 Object* SubString(int from, int to, PretenureFlag pretenure = NOT_TENURED); 4182 4183 // String equality operations. 4184 inline bool Equals(String* other); 4185 bool IsEqualTo(Vector<const char> str); 4186 4187 // Return a UTF8 representation of the string. The string is null 4188 // terminated but may optionally contain nulls. Length is returned 4189 // in length_output if length_output is not a null pointer The string 4190 // should be nearly flat, otherwise the performance of this method may 4191 // be very slow (quadratic in the length). Setting robustness_flag to 4192 // ROBUST_STRING_TRAVERSAL invokes behaviour that is robust This means it 4193 // handles unexpected data without causing assert failures and it does not 4194 // do any heap allocations. This is useful when printing stack traces. 4195 SmartPointer<char> ToCString(AllowNullsFlag allow_nulls, 4196 RobustnessFlag robustness_flag, 4197 int offset, 4198 int length, 4199 int* length_output = 0); 4200 SmartPointer<char> ToCString( 4201 AllowNullsFlag allow_nulls = DISALLOW_NULLS, 4202 RobustnessFlag robustness_flag = FAST_STRING_TRAVERSAL, 4203 int* length_output = 0); 4204 4205 int Utf8Length(); 4206 4207 // Return a 16 bit Unicode representation of the string. 4208 // The string should be nearly flat, otherwise the performance of 4209 // of this method may be very bad. Setting robustness_flag to 4210 // ROBUST_STRING_TRAVERSAL invokes behaviour that is robust This means it 4211 // handles unexpected data without causing assert failures and it does not 4212 // do any heap allocations. This is useful when printing stack traces. 4213 SmartPointer<uc16> ToWideCString( 4214 RobustnessFlag robustness_flag = FAST_STRING_TRAVERSAL); 4215 4216 // Tells whether the hash code has been computed. 4217 inline bool HasHashCode(); 4218 4219 // Returns a hash value used for the property table 4220 inline uint32_t Hash(); 4221 4222 static uint32_t ComputeHashField(unibrow::CharacterStream* buffer, 4223 int length); 4224 4225 static bool ComputeArrayIndex(unibrow::CharacterStream* buffer, 4226 uint32_t* index, 4227 int length); 4228 4229 // Externalization. 4230 bool MakeExternal(v8::String::ExternalStringResource* resource); 4231 bool MakeExternal(v8::String::ExternalAsciiStringResource* resource); 4232 4233 // Conversion. 4234 inline bool AsArrayIndex(uint32_t* index); 4235 4236 // Casting. 4237 static inline String* cast(Object* obj); 4238 4239 void PrintOn(FILE* out); 4240 4241 // For use during stack traces. Performs rudimentary sanity check. 4242 bool LooksValid(); 4243 4244 // Dispatched behavior. 4245 void StringShortPrint(StringStream* accumulator); 4246#ifdef DEBUG 4247 void StringPrint(); 4248 void StringVerify(); 4249#endif 4250 inline bool IsFlat(); 4251 4252 // Layout description. 4253 static const int kLengthOffset = HeapObject::kHeaderSize; 4254 static const int kHashFieldOffset = kLengthOffset + kPointerSize; 4255 static const int kSize = kHashFieldOffset + kPointerSize; 4256 4257 // Maximum number of characters to consider when trying to convert a string 4258 // value into an array index. 4259 static const int kMaxArrayIndexSize = 10; 4260 4261 // Max ascii char code. 4262 static const int kMaxAsciiCharCode = unibrow::Utf8::kMaxOneByteChar; 4263 static const unsigned kMaxAsciiCharCodeU = unibrow::Utf8::kMaxOneByteChar; 4264 static const int kMaxUC16CharCode = 0xffff; 4265 4266 // Minimum length for a cons string. 4267 static const int kMinNonFlatLength = 13; 4268 4269 // Mask constant for checking if a string has a computed hash code 4270 // and if it is an array index. The least significant bit indicates 4271 // whether a hash code has been computed. If the hash code has been 4272 // computed the 2nd bit tells whether the string can be used as an 4273 // array index. 4274 static const int kHashNotComputedMask = 1; 4275 static const int kIsNotArrayIndexMask = 1 << 1; 4276 static const int kNofHashBitFields = 2; 4277 4278 // Shift constant retrieving hash code from hash field. 4279 static const int kHashShift = kNofHashBitFields; 4280 4281 // Array index strings this short can keep their index in the hash 4282 // field. 4283 static const int kMaxCachedArrayIndexLength = 7; 4284 4285 // For strings which are array indexes the hash value has the string length 4286 // mixed into the hash, mainly to avoid a hash value of zero which would be 4287 // the case for the string '0'. 24 bits are used for the array index value. 4288 static const int kArrayIndexValueBits = 24; 4289 static const int kArrayIndexLengthBits = 4290 kBitsPerInt - kArrayIndexValueBits - kNofHashBitFields; 4291 4292 STATIC_CHECK((kArrayIndexLengthBits > 0)); 4293 4294 static const int kArrayIndexHashLengthShift = 4295 kArrayIndexValueBits + kNofHashBitFields; 4296 4297 static const int kArrayIndexHashMask = (1 << kArrayIndexHashLengthShift) - 1; 4298 4299 static const int kArrayIndexValueMask = 4300 ((1 << kArrayIndexValueBits) - 1) << kHashShift; 4301 4302 // Check that kMaxCachedArrayIndexLength + 1 is a power of two so we 4303 // could use a mask to test if the length of string is less than or equal to 4304 // kMaxCachedArrayIndexLength. 4305 STATIC_CHECK(IS_POWER_OF_TWO(kMaxCachedArrayIndexLength + 1)); 4306 4307 static const int kContainsCachedArrayIndexMask = 4308 (~kMaxCachedArrayIndexLength << kArrayIndexHashLengthShift) | 4309 kIsNotArrayIndexMask; 4310 4311 // Value of empty hash field indicating that the hash is not computed. 4312 static const int kEmptyHashField = 4313 kIsNotArrayIndexMask | kHashNotComputedMask; 4314 4315 // Value of hash field containing computed hash equal to zero. 4316 static const int kZeroHash = kIsNotArrayIndexMask; 4317 4318 // Maximal string length. 4319 static const int kMaxLength = (1 << (32 - 2)) - 1; 4320 4321 // Max length for computing hash. For strings longer than this limit the 4322 // string length is used as the hash value. 4323 static const int kMaxHashCalcLength = 16383; 4324 4325 // Limit for truncation in short printing. 4326 static const int kMaxShortPrintLength = 1024; 4327 4328 // Support for regular expressions. 4329 const uc16* GetTwoByteData(); 4330 const uc16* GetTwoByteData(unsigned start); 4331 4332 // Support for StringInputBuffer 4333 static const unibrow::byte* ReadBlock(String* input, 4334 unibrow::byte* util_buffer, 4335 unsigned capacity, 4336 unsigned* remaining, 4337 unsigned* offset); 4338 static const unibrow::byte* ReadBlock(String** input, 4339 unibrow::byte* util_buffer, 4340 unsigned capacity, 4341 unsigned* remaining, 4342 unsigned* offset); 4343 4344 // Helper function for flattening strings. 4345 template <typename sinkchar> 4346 static void WriteToFlat(String* source, 4347 sinkchar* sink, 4348 int from, 4349 int to); 4350 4351 protected: 4352 class ReadBlockBuffer { 4353 public: 4354 ReadBlockBuffer(unibrow::byte* util_buffer_, 4355 unsigned cursor_, 4356 unsigned capacity_, 4357 unsigned remaining_) : 4358 util_buffer(util_buffer_), 4359 cursor(cursor_), 4360 capacity(capacity_), 4361 remaining(remaining_) { 4362 } 4363 unibrow::byte* util_buffer; 4364 unsigned cursor; 4365 unsigned capacity; 4366 unsigned remaining; 4367 }; 4368 4369 static inline const unibrow::byte* ReadBlock(String* input, 4370 ReadBlockBuffer* buffer, 4371 unsigned* offset, 4372 unsigned max_chars); 4373 static void ReadBlockIntoBuffer(String* input, 4374 ReadBlockBuffer* buffer, 4375 unsigned* offset_ptr, 4376 unsigned max_chars); 4377 4378 private: 4379 // Try to flatten the top level ConsString that is hiding behind this 4380 // string. This is a no-op unless the string is a ConsString. Flatten 4381 // mutates the ConsString and might return a failure. 4382 Object* SlowTryFlatten(PretenureFlag pretenure); 4383 4384 static inline bool IsHashFieldComputed(uint32_t field); 4385 4386 // Slow case of String::Equals. This implementation works on any strings 4387 // but it is most efficient on strings that are almost flat. 4388 bool SlowEquals(String* other); 4389 4390 // Slow case of AsArrayIndex. 4391 bool SlowAsArrayIndex(uint32_t* index); 4392 4393 // Compute and set the hash code. 4394 uint32_t ComputeAndSetHash(); 4395 4396 DISALLOW_IMPLICIT_CONSTRUCTORS(String); 4397}; 4398 4399 4400// The SeqString abstract class captures sequential string values. 4401class SeqString: public String { 4402 public: 4403 4404 // Casting. 4405 static inline SeqString* cast(Object* obj); 4406 4407 private: 4408 DISALLOW_IMPLICIT_CONSTRUCTORS(SeqString); 4409}; 4410 4411 4412// The AsciiString class captures sequential ascii string objects. 4413// Each character in the AsciiString is an ascii character. 4414class SeqAsciiString: public SeqString { 4415 public: 4416 static const bool kHasAsciiEncoding = true; 4417 4418 // Dispatched behavior. 4419 inline uint16_t SeqAsciiStringGet(int index); 4420 inline void SeqAsciiStringSet(int index, uint16_t value); 4421 4422 // Get the address of the characters in this string. 4423 inline Address GetCharsAddress(); 4424 4425 inline char* GetChars(); 4426 4427 // Casting 4428 static inline SeqAsciiString* cast(Object* obj); 4429 4430 // Garbage collection support. This method is called by the 4431 // garbage collector to compute the actual size of an AsciiString 4432 // instance. 4433 inline int SeqAsciiStringSize(InstanceType instance_type); 4434 4435 // Computes the size for an AsciiString instance of a given length. 4436 static int SizeFor(int length) { 4437 return OBJECT_POINTER_ALIGN(kHeaderSize + length * kCharSize); 4438 } 4439 4440 // Layout description. 4441 static const int kHeaderSize = String::kSize; 4442 static const int kAlignedSize = POINTER_SIZE_ALIGN(kHeaderSize); 4443 4444 // Maximal memory usage for a single sequential ASCII string. 4445 static const int kMaxSize = 512 * MB; 4446 // Maximal length of a single sequential ASCII string. 4447 // Q.v. String::kMaxLength which is the maximal size of concatenated strings. 4448 static const int kMaxLength = (kMaxSize - kHeaderSize); 4449 4450 // Support for StringInputBuffer. 4451 inline void SeqAsciiStringReadBlockIntoBuffer(ReadBlockBuffer* buffer, 4452 unsigned* offset, 4453 unsigned chars); 4454 inline const unibrow::byte* SeqAsciiStringReadBlock(unsigned* remaining, 4455 unsigned* offset, 4456 unsigned chars); 4457 4458 private: 4459 DISALLOW_IMPLICIT_CONSTRUCTORS(SeqAsciiString); 4460}; 4461 4462 4463// The TwoByteString class captures sequential unicode string objects. 4464// Each character in the TwoByteString is a two-byte uint16_t. 4465class SeqTwoByteString: public SeqString { 4466 public: 4467 static const bool kHasAsciiEncoding = false; 4468 4469 // Dispatched behavior. 4470 inline uint16_t SeqTwoByteStringGet(int index); 4471 inline void SeqTwoByteStringSet(int index, uint16_t value); 4472 4473 // Get the address of the characters in this string. 4474 inline Address GetCharsAddress(); 4475 4476 inline uc16* GetChars(); 4477 4478 // For regexp code. 4479 const uint16_t* SeqTwoByteStringGetData(unsigned start); 4480 4481 // Casting 4482 static inline SeqTwoByteString* cast(Object* obj); 4483 4484 // Garbage collection support. This method is called by the 4485 // garbage collector to compute the actual size of a TwoByteString 4486 // instance. 4487 inline int SeqTwoByteStringSize(InstanceType instance_type); 4488 4489 // Computes the size for a TwoByteString instance of a given length. 4490 static int SizeFor(int length) { 4491 return OBJECT_POINTER_ALIGN(kHeaderSize + length * kShortSize); 4492 } 4493 4494 // Layout description. 4495 static const int kHeaderSize = String::kSize; 4496 static const int kAlignedSize = POINTER_SIZE_ALIGN(kHeaderSize); 4497 4498 // Maximal memory usage for a single sequential two-byte string. 4499 static const int kMaxSize = 512 * MB; 4500 // Maximal length of a single sequential two-byte string. 4501 // Q.v. String::kMaxLength which is the maximal size of concatenated strings. 4502 static const int kMaxLength = (kMaxSize - kHeaderSize) / sizeof(uint16_t); 4503 4504 // Support for StringInputBuffer. 4505 inline void SeqTwoByteStringReadBlockIntoBuffer(ReadBlockBuffer* buffer, 4506 unsigned* offset_ptr, 4507 unsigned chars); 4508 4509 private: 4510 DISALLOW_IMPLICIT_CONSTRUCTORS(SeqTwoByteString); 4511}; 4512 4513 4514// The ConsString class describes string values built by using the 4515// addition operator on strings. A ConsString is a pair where the 4516// first and second components are pointers to other string values. 4517// One or both components of a ConsString can be pointers to other 4518// ConsStrings, creating a binary tree of ConsStrings where the leaves 4519// are non-ConsString string values. The string value represented by 4520// a ConsString can be obtained by concatenating the leaf string 4521// values in a left-to-right depth-first traversal of the tree. 4522class ConsString: public String { 4523 public: 4524 // First string of the cons cell. 4525 inline String* first(); 4526 // Doesn't check that the result is a string, even in debug mode. This is 4527 // useful during GC where the mark bits confuse the checks. 4528 inline Object* unchecked_first(); 4529 inline void set_first(String* first, 4530 WriteBarrierMode mode = UPDATE_WRITE_BARRIER); 4531 4532 // Second string of the cons cell. 4533 inline String* second(); 4534 // Doesn't check that the result is a string, even in debug mode. This is 4535 // useful during GC where the mark bits confuse the checks. 4536 inline Object* unchecked_second(); 4537 inline void set_second(String* second, 4538 WriteBarrierMode mode = UPDATE_WRITE_BARRIER); 4539 4540 // Dispatched behavior. 4541 uint16_t ConsStringGet(int index); 4542 4543 // Casting. 4544 static inline ConsString* cast(Object* obj); 4545 4546 // Garbage collection support. This method is called during garbage 4547 // collection to iterate through the heap pointers in the body of 4548 // the ConsString. 4549 void ConsStringIterateBody(ObjectVisitor* v); 4550 4551 // Layout description. 4552 static const int kFirstOffset = POINTER_SIZE_ALIGN(String::kSize); 4553 static const int kSecondOffset = kFirstOffset + kPointerSize; 4554 static const int kSize = kSecondOffset + kPointerSize; 4555 4556 // Support for StringInputBuffer. 4557 inline const unibrow::byte* ConsStringReadBlock(ReadBlockBuffer* buffer, 4558 unsigned* offset_ptr, 4559 unsigned chars); 4560 inline void ConsStringReadBlockIntoBuffer(ReadBlockBuffer* buffer, 4561 unsigned* offset_ptr, 4562 unsigned chars); 4563 4564 // Minimum length for a cons string. 4565 static const int kMinLength = 13; 4566 4567 private: 4568 DISALLOW_IMPLICIT_CONSTRUCTORS(ConsString); 4569}; 4570 4571 4572// The ExternalString class describes string values that are backed by 4573// a string resource that lies outside the V8 heap. ExternalStrings 4574// consist of the length field common to all strings, a pointer to the 4575// external resource. It is important to ensure (externally) that the 4576// resource is not deallocated while the ExternalString is live in the 4577// V8 heap. 4578// 4579// The API expects that all ExternalStrings are created through the 4580// API. Therefore, ExternalStrings should not be used internally. 4581class ExternalString: public String { 4582 public: 4583 // Casting 4584 static inline ExternalString* cast(Object* obj); 4585 4586 // Layout description. 4587 static const int kResourceOffset = POINTER_SIZE_ALIGN(String::kSize); 4588 static const int kSize = kResourceOffset + kPointerSize; 4589 4590 STATIC_CHECK(kResourceOffset == Internals::kStringResourceOffset); 4591 4592 private: 4593 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalString); 4594}; 4595 4596 4597// The ExternalAsciiString class is an external string backed by an 4598// ASCII string. 4599class ExternalAsciiString: public ExternalString { 4600 public: 4601 static const bool kHasAsciiEncoding = true; 4602 4603 typedef v8::String::ExternalAsciiStringResource Resource; 4604 4605 // The underlying resource. 4606 inline Resource* resource(); 4607 inline void set_resource(Resource* buffer); 4608 4609 // Dispatched behavior. 4610 uint16_t ExternalAsciiStringGet(int index); 4611 4612 // Casting. 4613 static inline ExternalAsciiString* cast(Object* obj); 4614 4615 // Garbage collection support. 4616 void ExternalAsciiStringIterateBody(ObjectVisitor* v); 4617 4618 // Support for StringInputBuffer. 4619 const unibrow::byte* ExternalAsciiStringReadBlock(unsigned* remaining, 4620 unsigned* offset, 4621 unsigned chars); 4622 inline void ExternalAsciiStringReadBlockIntoBuffer(ReadBlockBuffer* buffer, 4623 unsigned* offset, 4624 unsigned chars); 4625 4626 private: 4627 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalAsciiString); 4628}; 4629 4630 4631// The ExternalTwoByteString class is an external string backed by a UTF-16 4632// encoded string. 4633class ExternalTwoByteString: public ExternalString { 4634 public: 4635 static const bool kHasAsciiEncoding = false; 4636 4637 typedef v8::String::ExternalStringResource Resource; 4638 4639 // The underlying string resource. 4640 inline Resource* resource(); 4641 inline void set_resource(Resource* buffer); 4642 4643 // Dispatched behavior. 4644 uint16_t ExternalTwoByteStringGet(int index); 4645 4646 // For regexp code. 4647 const uint16_t* ExternalTwoByteStringGetData(unsigned start); 4648 4649 // Casting. 4650 static inline ExternalTwoByteString* cast(Object* obj); 4651 4652 // Garbage collection support. 4653 void ExternalTwoByteStringIterateBody(ObjectVisitor* v); 4654 4655 // Support for StringInputBuffer. 4656 void ExternalTwoByteStringReadBlockIntoBuffer(ReadBlockBuffer* buffer, 4657 unsigned* offset_ptr, 4658 unsigned chars); 4659 4660 private: 4661 DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalTwoByteString); 4662}; 4663 4664 4665// Utility superclass for stack-allocated objects that must be updated 4666// on gc. It provides two ways for the gc to update instances, either 4667// iterating or updating after gc. 4668class Relocatable BASE_EMBEDDED { 4669 public: 4670 inline Relocatable() : prev_(top_) { top_ = this; } 4671 virtual ~Relocatable() { 4672 ASSERT_EQ(top_, this); 4673 top_ = prev_; 4674 } 4675 virtual void IterateInstance(ObjectVisitor* v) { } 4676 virtual void PostGarbageCollection() { } 4677 4678 static void PostGarbageCollectionProcessing(); 4679 static int ArchiveSpacePerThread(); 4680 static char* ArchiveState(char* to); 4681 static char* RestoreState(char* from); 4682 static void Iterate(ObjectVisitor* v); 4683 static void Iterate(ObjectVisitor* v, Relocatable* top); 4684 static char* Iterate(ObjectVisitor* v, char* t); 4685 private: 4686 static Relocatable* top_; 4687 Relocatable* prev_; 4688}; 4689 4690 4691// A flat string reader provides random access to the contents of a 4692// string independent of the character width of the string. The handle 4693// must be valid as long as the reader is being used. 4694class FlatStringReader : public Relocatable { 4695 public: 4696 explicit FlatStringReader(Handle<String> str); 4697 explicit FlatStringReader(Vector<const char> input); 4698 void PostGarbageCollection(); 4699 inline uc32 Get(int index); 4700 int length() { return length_; } 4701 private: 4702 String** str_; 4703 bool is_ascii_; 4704 int length_; 4705 const void* start_; 4706}; 4707 4708 4709// Note that StringInputBuffers are not valid across a GC! To fix this 4710// it would have to store a String Handle instead of a String* and 4711// AsciiStringReadBlock would have to be modified to use memcpy. 4712// 4713// StringInputBuffer is able to traverse any string regardless of how 4714// deeply nested a sequence of ConsStrings it is made of. However, 4715// performance will be better if deep strings are flattened before they 4716// are traversed. Since flattening requires memory allocation this is 4717// not always desirable, however (esp. in debugging situations). 4718class StringInputBuffer: public unibrow::InputBuffer<String, String*, 1024> { 4719 public: 4720 virtual void Seek(unsigned pos); 4721 inline StringInputBuffer(): unibrow::InputBuffer<String, String*, 1024>() {} 4722 inline StringInputBuffer(String* backing): 4723 unibrow::InputBuffer<String, String*, 1024>(backing) {} 4724}; 4725 4726 4727class SafeStringInputBuffer 4728 : public unibrow::InputBuffer<String, String**, 256> { 4729 public: 4730 virtual void Seek(unsigned pos); 4731 inline SafeStringInputBuffer() 4732 : unibrow::InputBuffer<String, String**, 256>() {} 4733 inline SafeStringInputBuffer(String** backing) 4734 : unibrow::InputBuffer<String, String**, 256>(backing) {} 4735}; 4736 4737 4738template <typename T> 4739class VectorIterator { 4740 public: 4741 VectorIterator(T* d, int l) : data_(Vector<const T>(d, l)), index_(0) { } 4742 explicit VectorIterator(Vector<const T> data) : data_(data), index_(0) { } 4743 T GetNext() { return data_[index_++]; } 4744 bool has_more() { return index_ < data_.length(); } 4745 private: 4746 Vector<const T> data_; 4747 int index_; 4748}; 4749 4750 4751// The Oddball describes objects null, undefined, true, and false. 4752class Oddball: public HeapObject { 4753 public: 4754 // [to_string]: Cached to_string computed at startup. 4755 DECL_ACCESSORS(to_string, String) 4756 4757 // [to_number]: Cached to_number computed at startup. 4758 DECL_ACCESSORS(to_number, Object) 4759 4760 // Casting. 4761 static inline Oddball* cast(Object* obj); 4762 4763 // Dispatched behavior. 4764 void OddballIterateBody(ObjectVisitor* v); 4765#ifdef DEBUG 4766 void OddballVerify(); 4767#endif 4768 4769 // Initialize the fields. 4770 Object* Initialize(const char* to_string, Object* to_number); 4771 4772 // Layout description. 4773 static const int kToStringOffset = HeapObject::kHeaderSize; 4774 static const int kToNumberOffset = kToStringOffset + kPointerSize; 4775 static const int kSize = kToNumberOffset + kPointerSize; 4776 4777 private: 4778 DISALLOW_IMPLICIT_CONSTRUCTORS(Oddball); 4779}; 4780 4781 4782class JSGlobalPropertyCell: public HeapObject { 4783 public: 4784 // [value]: value of the global property. 4785 DECL_ACCESSORS(value, Object) 4786 4787 // Casting. 4788 static inline JSGlobalPropertyCell* cast(Object* obj); 4789 4790 // Dispatched behavior. 4791 void JSGlobalPropertyCellIterateBody(ObjectVisitor* v); 4792#ifdef DEBUG 4793 void JSGlobalPropertyCellVerify(); 4794 void JSGlobalPropertyCellPrint(); 4795#endif 4796 4797 // Layout description. 4798 static const int kValueOffset = HeapObject::kHeaderSize; 4799 static const int kSize = kValueOffset + kPointerSize; 4800 4801 private: 4802 DISALLOW_IMPLICIT_CONSTRUCTORS(JSGlobalPropertyCell); 4803}; 4804 4805 4806 4807// Proxy describes objects pointing from JavaScript to C structures. 4808// Since they cannot contain references to JS HeapObjects they can be 4809// placed in old_data_space. 4810class Proxy: public HeapObject { 4811 public: 4812 // [proxy]: field containing the address. 4813 inline Address proxy(); 4814 inline void set_proxy(Address value); 4815 4816 // Casting. 4817 static inline Proxy* cast(Object* obj); 4818 4819 // Dispatched behavior. 4820 inline void ProxyIterateBody(ObjectVisitor* v); 4821#ifdef DEBUG 4822 void ProxyPrint(); 4823 void ProxyVerify(); 4824#endif 4825 4826 // Layout description. 4827 4828 static const int kProxyOffset = HeapObject::kHeaderSize; 4829 static const int kSize = kProxyOffset + kPointerSize; 4830 4831 STATIC_CHECK(kProxyOffset == Internals::kProxyProxyOffset); 4832 4833 private: 4834 DISALLOW_IMPLICIT_CONSTRUCTORS(Proxy); 4835}; 4836 4837 4838// The JSArray describes JavaScript Arrays 4839// Such an array can be in one of two modes: 4840// - fast, backing storage is a FixedArray and length <= elements.length(); 4841// Please note: push and pop can be used to grow and shrink the array. 4842// - slow, backing storage is a HashTable with numbers as keys. 4843class JSArray: public JSObject { 4844 public: 4845 // [length]: The length property. 4846 DECL_ACCESSORS(length, Object) 4847 4848 // Overload the length setter to skip write barrier when the length 4849 // is set to a smi. This matches the set function on FixedArray. 4850 inline void set_length(Smi* length); 4851 4852 Object* JSArrayUpdateLengthFromIndex(uint32_t index, Object* value); 4853 4854 // Initialize the array with the given capacity. The function may 4855 // fail due to out-of-memory situations, but only if the requested 4856 // capacity is non-zero. 4857 Object* Initialize(int capacity); 4858 4859 // Set the content of the array to the content of storage. 4860 inline void SetContent(FixedArray* storage); 4861 4862 // Casting. 4863 static inline JSArray* cast(Object* obj); 4864 4865 // Uses handles. Ensures that the fixed array backing the JSArray has at 4866 // least the stated size. 4867 inline void EnsureSize(int minimum_size_of_backing_fixed_array); 4868 4869 // Dispatched behavior. 4870#ifdef DEBUG 4871 void JSArrayPrint(); 4872 void JSArrayVerify(); 4873#endif 4874 4875 // Number of element slots to pre-allocate for an empty array. 4876 static const int kPreallocatedArrayElements = 4; 4877 4878 // Layout description. 4879 static const int kLengthOffset = JSObject::kHeaderSize; 4880 static const int kSize = kLengthOffset + kPointerSize; 4881 4882 private: 4883 // Expand the fixed array backing of a fast-case JSArray to at least 4884 // the requested size. 4885 void Expand(int minimum_size_of_backing_fixed_array); 4886 4887 DISALLOW_IMPLICIT_CONSTRUCTORS(JSArray); 4888}; 4889 4890 4891// JSRegExpResult is just a JSArray with a specific initial map. 4892// This initial map adds in-object properties for "index" and "input" 4893// properties, as assigned by RegExp.prototype.exec, which allows 4894// faster creation of RegExp exec results. 4895// This class just holds constants used when creating the result. 4896// After creation the result must be treated as a JSArray in all regards. 4897class JSRegExpResult: public JSArray { 4898 public: 4899 // Offsets of object fields. 4900 static const int kIndexOffset = JSArray::kSize; 4901 static const int kInputOffset = kIndexOffset + kPointerSize; 4902 static const int kSize = kInputOffset + kPointerSize; 4903 // Indices of in-object properties. 4904 static const int kIndexIndex = 0; 4905 static const int kInputIndex = 1; 4906 private: 4907 DISALLOW_IMPLICIT_CONSTRUCTORS(JSRegExpResult); 4908}; 4909 4910 4911// An accessor must have a getter, but can have no setter. 4912// 4913// When setting a property, V8 searches accessors in prototypes. 4914// If an accessor was found and it does not have a setter, 4915// the request is ignored. 4916// 4917// If the accessor in the prototype has the READ_ONLY property attribute, then 4918// a new value is added to the local object when the property is set. 4919// This shadows the accessor in the prototype. 4920class AccessorInfo: public Struct { 4921 public: 4922 DECL_ACCESSORS(getter, Object) 4923 DECL_ACCESSORS(setter, Object) 4924 DECL_ACCESSORS(data, Object) 4925 DECL_ACCESSORS(name, Object) 4926 DECL_ACCESSORS(flag, Smi) 4927 DECL_ACCESSORS(load_stub_cache, Object) 4928 4929 inline bool all_can_read(); 4930 inline void set_all_can_read(bool value); 4931 4932 inline bool all_can_write(); 4933 inline void set_all_can_write(bool value); 4934 4935 inline bool prohibits_overwriting(); 4936 inline void set_prohibits_overwriting(bool value); 4937 4938 inline PropertyAttributes property_attributes(); 4939 inline void set_property_attributes(PropertyAttributes attributes); 4940 4941 static inline AccessorInfo* cast(Object* obj); 4942 4943#ifdef DEBUG 4944 void AccessorInfoPrint(); 4945 void AccessorInfoVerify(); 4946#endif 4947 4948 static const int kGetterOffset = HeapObject::kHeaderSize; 4949 static const int kSetterOffset = kGetterOffset + kPointerSize; 4950 static const int kDataOffset = kSetterOffset + kPointerSize; 4951 static const int kNameOffset = kDataOffset + kPointerSize; 4952 static const int kFlagOffset = kNameOffset + kPointerSize; 4953 static const int kLoadStubCacheOffset = kFlagOffset + kPointerSize; 4954 static const int kSize = kLoadStubCacheOffset + kPointerSize; 4955 4956 private: 4957 // Bit positions in flag. 4958 static const int kAllCanReadBit = 0; 4959 static const int kAllCanWriteBit = 1; 4960 static const int kProhibitsOverwritingBit = 2; 4961 class AttributesField: public BitField<PropertyAttributes, 3, 3> {}; 4962 4963 DISALLOW_IMPLICIT_CONSTRUCTORS(AccessorInfo); 4964}; 4965 4966 4967class AccessCheckInfo: public Struct { 4968 public: 4969 DECL_ACCESSORS(named_callback, Object) 4970 DECL_ACCESSORS(indexed_callback, Object) 4971 DECL_ACCESSORS(data, Object) 4972 4973 static inline AccessCheckInfo* cast(Object* obj); 4974 4975#ifdef DEBUG 4976 void AccessCheckInfoPrint(); 4977 void AccessCheckInfoVerify(); 4978#endif 4979 4980 static const int kNamedCallbackOffset = HeapObject::kHeaderSize; 4981 static const int kIndexedCallbackOffset = kNamedCallbackOffset + kPointerSize; 4982 static const int kDataOffset = kIndexedCallbackOffset + kPointerSize; 4983 static const int kSize = kDataOffset + kPointerSize; 4984 4985 private: 4986 DISALLOW_IMPLICIT_CONSTRUCTORS(AccessCheckInfo); 4987}; 4988 4989 4990class InterceptorInfo: public Struct { 4991 public: 4992 DECL_ACCESSORS(getter, Object) 4993 DECL_ACCESSORS(setter, Object) 4994 DECL_ACCESSORS(query, Object) 4995 DECL_ACCESSORS(deleter, Object) 4996 DECL_ACCESSORS(enumerator, Object) 4997 DECL_ACCESSORS(data, Object) 4998 4999 static inline InterceptorInfo* cast(Object* obj); 5000 5001#ifdef DEBUG 5002 void InterceptorInfoPrint(); 5003 void InterceptorInfoVerify(); 5004#endif 5005 5006 static const int kGetterOffset = HeapObject::kHeaderSize; 5007 static const int kSetterOffset = kGetterOffset + kPointerSize; 5008 static const int kQueryOffset = kSetterOffset + kPointerSize; 5009 static const int kDeleterOffset = kQueryOffset + kPointerSize; 5010 static const int kEnumeratorOffset = kDeleterOffset + kPointerSize; 5011 static const int kDataOffset = kEnumeratorOffset + kPointerSize; 5012 static const int kSize = kDataOffset + kPointerSize; 5013 5014 private: 5015 DISALLOW_IMPLICIT_CONSTRUCTORS(InterceptorInfo); 5016}; 5017 5018 5019class CallHandlerInfo: public Struct { 5020 public: 5021 DECL_ACCESSORS(callback, Object) 5022 DECL_ACCESSORS(data, Object) 5023 5024 static inline CallHandlerInfo* cast(Object* obj); 5025 5026#ifdef DEBUG 5027 void CallHandlerInfoPrint(); 5028 void CallHandlerInfoVerify(); 5029#endif 5030 5031 static const int kCallbackOffset = HeapObject::kHeaderSize; 5032 static const int kDataOffset = kCallbackOffset + kPointerSize; 5033 static const int kSize = kDataOffset + kPointerSize; 5034 5035 private: 5036 DISALLOW_IMPLICIT_CONSTRUCTORS(CallHandlerInfo); 5037}; 5038 5039 5040class TemplateInfo: public Struct { 5041 public: 5042 DECL_ACCESSORS(tag, Object) 5043 DECL_ACCESSORS(property_list, Object) 5044 5045#ifdef DEBUG 5046 void TemplateInfoVerify(); 5047#endif 5048 5049 static const int kTagOffset = HeapObject::kHeaderSize; 5050 static const int kPropertyListOffset = kTagOffset + kPointerSize; 5051 static const int kHeaderSize = kPropertyListOffset + kPointerSize; 5052 protected: 5053 friend class AGCCVersionRequiresThisClassToHaveAFriendSoHereItIs; 5054 DISALLOW_IMPLICIT_CONSTRUCTORS(TemplateInfo); 5055}; 5056 5057 5058class FunctionTemplateInfo: public TemplateInfo { 5059 public: 5060 DECL_ACCESSORS(serial_number, Object) 5061 DECL_ACCESSORS(call_code, Object) 5062 DECL_ACCESSORS(property_accessors, Object) 5063 DECL_ACCESSORS(prototype_template, Object) 5064 DECL_ACCESSORS(parent_template, Object) 5065 DECL_ACCESSORS(named_property_handler, Object) 5066 DECL_ACCESSORS(indexed_property_handler, Object) 5067 DECL_ACCESSORS(instance_template, Object) 5068 DECL_ACCESSORS(class_name, Object) 5069 DECL_ACCESSORS(signature, Object) 5070 DECL_ACCESSORS(instance_call_handler, Object) 5071 DECL_ACCESSORS(access_check_info, Object) 5072 DECL_ACCESSORS(flag, Smi) 5073 5074 // Following properties use flag bits. 5075 DECL_BOOLEAN_ACCESSORS(hidden_prototype) 5076 DECL_BOOLEAN_ACCESSORS(undetectable) 5077 // If the bit is set, object instances created by this function 5078 // requires access check. 5079 DECL_BOOLEAN_ACCESSORS(needs_access_check) 5080 5081 static inline FunctionTemplateInfo* cast(Object* obj); 5082 5083#ifdef DEBUG 5084 void FunctionTemplateInfoPrint(); 5085 void FunctionTemplateInfoVerify(); 5086#endif 5087 5088 static const int kSerialNumberOffset = TemplateInfo::kHeaderSize; 5089 static const int kCallCodeOffset = kSerialNumberOffset + kPointerSize; 5090 static const int kPropertyAccessorsOffset = kCallCodeOffset + kPointerSize; 5091 static const int kPrototypeTemplateOffset = 5092 kPropertyAccessorsOffset + kPointerSize; 5093 static const int kParentTemplateOffset = 5094 kPrototypeTemplateOffset + kPointerSize; 5095 static const int kNamedPropertyHandlerOffset = 5096 kParentTemplateOffset + kPointerSize; 5097 static const int kIndexedPropertyHandlerOffset = 5098 kNamedPropertyHandlerOffset + kPointerSize; 5099 static const int kInstanceTemplateOffset = 5100 kIndexedPropertyHandlerOffset + kPointerSize; 5101 static const int kClassNameOffset = kInstanceTemplateOffset + kPointerSize; 5102 static const int kSignatureOffset = kClassNameOffset + kPointerSize; 5103 static const int kInstanceCallHandlerOffset = kSignatureOffset + kPointerSize; 5104 static const int kAccessCheckInfoOffset = 5105 kInstanceCallHandlerOffset + kPointerSize; 5106 static const int kFlagOffset = kAccessCheckInfoOffset + kPointerSize; 5107 static const int kSize = kFlagOffset + kPointerSize; 5108 5109 private: 5110 // Bit position in the flag, from least significant bit position. 5111 static const int kHiddenPrototypeBit = 0; 5112 static const int kUndetectableBit = 1; 5113 static const int kNeedsAccessCheckBit = 2; 5114 5115 DISALLOW_IMPLICIT_CONSTRUCTORS(FunctionTemplateInfo); 5116}; 5117 5118 5119class ObjectTemplateInfo: public TemplateInfo { 5120 public: 5121 DECL_ACCESSORS(constructor, Object) 5122 DECL_ACCESSORS(internal_field_count, Object) 5123 5124 static inline ObjectTemplateInfo* cast(Object* obj); 5125 5126#ifdef DEBUG 5127 void ObjectTemplateInfoPrint(); 5128 void ObjectTemplateInfoVerify(); 5129#endif 5130 5131 static const int kConstructorOffset = TemplateInfo::kHeaderSize; 5132 static const int kInternalFieldCountOffset = 5133 kConstructorOffset + kPointerSize; 5134 static const int kSize = kInternalFieldCountOffset + kPointerSize; 5135}; 5136 5137 5138class SignatureInfo: public Struct { 5139 public: 5140 DECL_ACCESSORS(receiver, Object) 5141 DECL_ACCESSORS(args, Object) 5142 5143 static inline SignatureInfo* cast(Object* obj); 5144 5145#ifdef DEBUG 5146 void SignatureInfoPrint(); 5147 void SignatureInfoVerify(); 5148#endif 5149 5150 static const int kReceiverOffset = Struct::kHeaderSize; 5151 static const int kArgsOffset = kReceiverOffset + kPointerSize; 5152 static const int kSize = kArgsOffset + kPointerSize; 5153 5154 private: 5155 DISALLOW_IMPLICIT_CONSTRUCTORS(SignatureInfo); 5156}; 5157 5158 5159class TypeSwitchInfo: public Struct { 5160 public: 5161 DECL_ACCESSORS(types, Object) 5162 5163 static inline TypeSwitchInfo* cast(Object* obj); 5164 5165#ifdef DEBUG 5166 void TypeSwitchInfoPrint(); 5167 void TypeSwitchInfoVerify(); 5168#endif 5169 5170 static const int kTypesOffset = Struct::kHeaderSize; 5171 static const int kSize = kTypesOffset + kPointerSize; 5172}; 5173 5174 5175#ifdef ENABLE_DEBUGGER_SUPPORT 5176// The DebugInfo class holds additional information for a function being 5177// debugged. 5178class DebugInfo: public Struct { 5179 public: 5180 // The shared function info for the source being debugged. 5181 DECL_ACCESSORS(shared, SharedFunctionInfo) 5182 // Code object for the original code. 5183 DECL_ACCESSORS(original_code, Code) 5184 // Code object for the patched code. This code object is the code object 5185 // currently active for the function. 5186 DECL_ACCESSORS(code, Code) 5187 // Fixed array holding status information for each active break point. 5188 DECL_ACCESSORS(break_points, FixedArray) 5189 5190 // Check if there is a break point at a code position. 5191 bool HasBreakPoint(int code_position); 5192 // Get the break point info object for a code position. 5193 Object* GetBreakPointInfo(int code_position); 5194 // Clear a break point. 5195 static void ClearBreakPoint(Handle<DebugInfo> debug_info, 5196 int code_position, 5197 Handle<Object> break_point_object); 5198 // Set a break point. 5199 static void SetBreakPoint(Handle<DebugInfo> debug_info, int code_position, 5200 int source_position, int statement_position, 5201 Handle<Object> break_point_object); 5202 // Get the break point objects for a code position. 5203 Object* GetBreakPointObjects(int code_position); 5204 // Find the break point info holding this break point object. 5205 static Object* FindBreakPointInfo(Handle<DebugInfo> debug_info, 5206 Handle<Object> break_point_object); 5207 // Get the number of break points for this function. 5208 int GetBreakPointCount(); 5209 5210 static inline DebugInfo* cast(Object* obj); 5211 5212#ifdef DEBUG 5213 void DebugInfoPrint(); 5214 void DebugInfoVerify(); 5215#endif 5216 5217 static const int kSharedFunctionInfoIndex = Struct::kHeaderSize; 5218 static const int kOriginalCodeIndex = kSharedFunctionInfoIndex + kPointerSize; 5219 static const int kPatchedCodeIndex = kOriginalCodeIndex + kPointerSize; 5220 static const int kActiveBreakPointsCountIndex = 5221 kPatchedCodeIndex + kPointerSize; 5222 static const int kBreakPointsStateIndex = 5223 kActiveBreakPointsCountIndex + kPointerSize; 5224 static const int kSize = kBreakPointsStateIndex + kPointerSize; 5225 5226 private: 5227 static const int kNoBreakPointInfo = -1; 5228 5229 // Lookup the index in the break_points array for a code position. 5230 int GetBreakPointInfoIndex(int code_position); 5231 5232 DISALLOW_IMPLICIT_CONSTRUCTORS(DebugInfo); 5233}; 5234 5235 5236// The BreakPointInfo class holds information for break points set in a 5237// function. The DebugInfo object holds a BreakPointInfo object for each code 5238// position with one or more break points. 5239class BreakPointInfo: public Struct { 5240 public: 5241 // The position in the code for the break point. 5242 DECL_ACCESSORS(code_position, Smi) 5243 // The position in the source for the break position. 5244 DECL_ACCESSORS(source_position, Smi) 5245 // The position in the source for the last statement before this break 5246 // position. 5247 DECL_ACCESSORS(statement_position, Smi) 5248 // List of related JavaScript break points. 5249 DECL_ACCESSORS(break_point_objects, Object) 5250 5251 // Removes a break point. 5252 static void ClearBreakPoint(Handle<BreakPointInfo> info, 5253 Handle<Object> break_point_object); 5254 // Set a break point. 5255 static void SetBreakPoint(Handle<BreakPointInfo> info, 5256 Handle<Object> break_point_object); 5257 // Check if break point info has this break point object. 5258 static bool HasBreakPointObject(Handle<BreakPointInfo> info, 5259 Handle<Object> break_point_object); 5260 // Get the number of break points for this code position. 5261 int GetBreakPointCount(); 5262 5263 static inline BreakPointInfo* cast(Object* obj); 5264 5265#ifdef DEBUG 5266 void BreakPointInfoPrint(); 5267 void BreakPointInfoVerify(); 5268#endif 5269 5270 static const int kCodePositionIndex = Struct::kHeaderSize; 5271 static const int kSourcePositionIndex = kCodePositionIndex + kPointerSize; 5272 static const int kStatementPositionIndex = 5273 kSourcePositionIndex + kPointerSize; 5274 static const int kBreakPointObjectsIndex = 5275 kStatementPositionIndex + kPointerSize; 5276 static const int kSize = kBreakPointObjectsIndex + kPointerSize; 5277 5278 private: 5279 DISALLOW_IMPLICIT_CONSTRUCTORS(BreakPointInfo); 5280}; 5281#endif // ENABLE_DEBUGGER_SUPPORT 5282 5283 5284#undef DECL_BOOLEAN_ACCESSORS 5285#undef DECL_ACCESSORS 5286 5287 5288// Abstract base class for visiting, and optionally modifying, the 5289// pointers contained in Objects. Used in GC and serialization/deserialization. 5290class ObjectVisitor BASE_EMBEDDED { 5291 public: 5292 virtual ~ObjectVisitor() {} 5293 5294 // Visits a contiguous arrays of pointers in the half-open range 5295 // [start, end). Any or all of the values may be modified on return. 5296 virtual void VisitPointers(Object** start, Object** end) = 0; 5297 5298 // To allow lazy clearing of inline caches the visitor has 5299 // a rich interface for iterating over Code objects.. 5300 5301 // Visits a code target in the instruction stream. 5302 virtual void VisitCodeTarget(RelocInfo* rinfo); 5303 5304 // Visits a runtime entry in the instruction stream. 5305 virtual void VisitRuntimeEntry(RelocInfo* rinfo) {} 5306 5307 // Visits the resource of an ASCII or two-byte string. 5308 virtual void VisitExternalAsciiString( 5309 v8::String::ExternalAsciiStringResource** resource) {} 5310 virtual void VisitExternalTwoByteString( 5311 v8::String::ExternalStringResource** resource) {} 5312 5313 // Visits a debug call target in the instruction stream. 5314 virtual void VisitDebugTarget(RelocInfo* rinfo); 5315 5316 // Handy shorthand for visiting a single pointer. 5317 virtual void VisitPointer(Object** p) { VisitPointers(p, p + 1); } 5318 5319 // Visits a contiguous arrays of external references (references to the C++ 5320 // heap) in the half-open range [start, end). Any or all of the values 5321 // may be modified on return. 5322 virtual void VisitExternalReferences(Address* start, Address* end) {} 5323 5324 inline void VisitExternalReference(Address* p) { 5325 VisitExternalReferences(p, p + 1); 5326 } 5327 5328#ifdef DEBUG 5329 // Intended for serialization/deserialization checking: insert, or 5330 // check for the presence of, a tag at this position in the stream. 5331 virtual void Synchronize(const char* tag) {} 5332#else 5333 inline void Synchronize(const char* tag) {} 5334#endif 5335}; 5336 5337 5338// BooleanBit is a helper class for setting and getting a bit in an 5339// integer or Smi. 5340class BooleanBit : public AllStatic { 5341 public: 5342 static inline bool get(Smi* smi, int bit_position) { 5343 return get(smi->value(), bit_position); 5344 } 5345 5346 static inline bool get(int value, int bit_position) { 5347 return (value & (1 << bit_position)) != 0; 5348 } 5349 5350 static inline Smi* set(Smi* smi, int bit_position, bool v) { 5351 return Smi::FromInt(set(smi->value(), bit_position, v)); 5352 } 5353 5354 static inline int set(int value, int bit_position, bool v) { 5355 if (v) { 5356 value |= (1 << bit_position); 5357 } else { 5358 value &= ~(1 << bit_position); 5359 } 5360 return value; 5361 } 5362}; 5363 5364} } // namespace v8::internal 5365 5366#endif // V8_OBJECTS_H_ 5367