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