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