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