1// Copyright 2012 the V8 project authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "src/objects.h" 6 7#include "src/disasm.h" 8#include "src/disassembler.h" 9#include "src/interpreter/bytecodes.h" 10#include "src/objects-inl.h" 11#include "src/ostreams.h" 12#include "src/regexp/jsregexp.h" 13 14namespace v8 { 15namespace internal { 16 17#ifdef OBJECT_PRINT 18 19void Object::Print() { 20 OFStream os(stdout); 21 this->Print(os); 22 os << std::flush; 23} 24 25 26void Object::Print(std::ostream& os) { // NOLINT 27 if (IsSmi()) { 28 Smi::cast(this)->SmiPrint(os); 29 } else { 30 HeapObject::cast(this)->HeapObjectPrint(os); 31 } 32} 33 34 35void HeapObject::PrintHeader(std::ostream& os, const char* id) { // NOLINT 36 os << reinterpret_cast<void*>(this) << ": ["; 37 if (id != nullptr) { 38 os << id; 39 } else { 40 os << map()->instance_type(); 41 } 42 os << "]"; 43} 44 45 46void HeapObject::HeapObjectPrint(std::ostream& os) { // NOLINT 47 InstanceType instance_type = map()->instance_type(); 48 49 HandleScope scope(GetIsolate()); 50 if (instance_type < FIRST_NONSTRING_TYPE) { 51 String::cast(this)->StringPrint(os); 52 return; 53 } 54 55 switch (instance_type) { 56 case SYMBOL_TYPE: 57 Symbol::cast(this)->SymbolPrint(os); 58 break; 59 case MAP_TYPE: 60 Map::cast(this)->MapPrint(os); 61 break; 62 case HEAP_NUMBER_TYPE: 63 HeapNumber::cast(this)->HeapNumberPrint(os); 64 break; 65 case MUTABLE_HEAP_NUMBER_TYPE: 66 os << "<mutable "; 67 HeapNumber::cast(this)->HeapNumberPrint(os); 68 os << ">"; 69 break; 70 case SIMD128_VALUE_TYPE: 71 Simd128Value::cast(this)->Simd128ValuePrint(os); 72 break; 73 case FIXED_DOUBLE_ARRAY_TYPE: 74 FixedDoubleArray::cast(this)->FixedDoubleArrayPrint(os); 75 break; 76 case FIXED_ARRAY_TYPE: 77 FixedArray::cast(this)->FixedArrayPrint(os); 78 break; 79 case BYTE_ARRAY_TYPE: 80 ByteArray::cast(this)->ByteArrayPrint(os); 81 break; 82 case BYTECODE_ARRAY_TYPE: 83 BytecodeArray::cast(this)->BytecodeArrayPrint(os); 84 break; 85 case TRANSITION_ARRAY_TYPE: 86 TransitionArray::cast(this)->TransitionArrayPrint(os); 87 break; 88 case FREE_SPACE_TYPE: 89 FreeSpace::cast(this)->FreeSpacePrint(os); 90 break; 91 92#define PRINT_FIXED_TYPED_ARRAY(Type, type, TYPE, ctype, size) \ 93 case Fixed##Type##Array::kInstanceType: \ 94 Fixed##Type##Array::cast(this)->FixedTypedArrayPrint(os); \ 95 break; 96 97 TYPED_ARRAYS(PRINT_FIXED_TYPED_ARRAY) 98#undef PRINT_FIXED_TYPED_ARRAY 99 100 case FILLER_TYPE: 101 os << "filler"; 102 break; 103 case JS_OBJECT_TYPE: // fall through 104 case JS_API_OBJECT_TYPE: 105 case JS_SPECIAL_API_OBJECT_TYPE: 106 case JS_CONTEXT_EXTENSION_OBJECT_TYPE: 107 case JS_GENERATOR_OBJECT_TYPE: 108 case JS_PROMISE_TYPE: 109 case JS_ARGUMENTS_TYPE: 110 case JS_ERROR_TYPE: 111 JSObject::cast(this)->JSObjectPrint(os); 112 break; 113 case JS_ARRAY_TYPE: 114 JSArray::cast(this)->JSArrayPrint(os); 115 break; 116 case JS_REGEXP_TYPE: 117 JSRegExp::cast(this)->JSRegExpPrint(os); 118 break; 119 case ODDBALL_TYPE: 120 Oddball::cast(this)->to_string()->Print(os); 121 break; 122 case JS_MODULE_TYPE: 123 JSModule::cast(this)->JSModulePrint(os); 124 break; 125 case JS_BOUND_FUNCTION_TYPE: 126 JSBoundFunction::cast(this)->JSBoundFunctionPrint(os); 127 break; 128 case JS_FUNCTION_TYPE: 129 JSFunction::cast(this)->JSFunctionPrint(os); 130 break; 131 case JS_GLOBAL_PROXY_TYPE: 132 JSGlobalProxy::cast(this)->JSGlobalProxyPrint(os); 133 break; 134 case JS_GLOBAL_OBJECT_TYPE: 135 JSGlobalObject::cast(this)->JSGlobalObjectPrint(os); 136 break; 137 case JS_VALUE_TYPE: 138 JSValue::cast(this)->JSValuePrint(os); 139 break; 140 case JS_DATE_TYPE: 141 JSDate::cast(this)->JSDatePrint(os); 142 break; 143 case CODE_TYPE: 144 Code::cast(this)->CodePrint(os); 145 break; 146 case JS_PROXY_TYPE: 147 JSProxy::cast(this)->JSProxyPrint(os); 148 break; 149 case JS_SET_TYPE: 150 JSSet::cast(this)->JSSetPrint(os); 151 break; 152 case JS_MAP_TYPE: 153 JSMap::cast(this)->JSMapPrint(os); 154 break; 155 case JS_SET_ITERATOR_TYPE: 156 JSSetIterator::cast(this)->JSSetIteratorPrint(os); 157 break; 158 case JS_MAP_ITERATOR_TYPE: 159 JSMapIterator::cast(this)->JSMapIteratorPrint(os); 160 break; 161 case JS_WEAK_MAP_TYPE: 162 JSWeakMap::cast(this)->JSWeakMapPrint(os); 163 break; 164 case JS_WEAK_SET_TYPE: 165 JSWeakSet::cast(this)->JSWeakSetPrint(os); 166 break; 167 case FOREIGN_TYPE: 168 Foreign::cast(this)->ForeignPrint(os); 169 break; 170 case SHARED_FUNCTION_INFO_TYPE: 171 SharedFunctionInfo::cast(this)->SharedFunctionInfoPrint(os); 172 break; 173 case JS_MESSAGE_OBJECT_TYPE: 174 JSMessageObject::cast(this)->JSMessageObjectPrint(os); 175 break; 176 case CELL_TYPE: 177 Cell::cast(this)->CellPrint(os); 178 break; 179 case PROPERTY_CELL_TYPE: 180 PropertyCell::cast(this)->PropertyCellPrint(os); 181 break; 182 case WEAK_CELL_TYPE: 183 WeakCell::cast(this)->WeakCellPrint(os); 184 break; 185 case JS_ARRAY_BUFFER_TYPE: 186 JSArrayBuffer::cast(this)->JSArrayBufferPrint(os); 187 break; 188 case JS_TYPED_ARRAY_TYPE: 189 JSTypedArray::cast(this)->JSTypedArrayPrint(os); 190 break; 191 case JS_DATA_VIEW_TYPE: 192 JSDataView::cast(this)->JSDataViewPrint(os); 193 break; 194#define MAKE_STRUCT_CASE(NAME, Name, name) \ 195 case NAME##_TYPE: \ 196 Name::cast(this)->Name##Print(os); \ 197 break; 198 STRUCT_LIST(MAKE_STRUCT_CASE) 199#undef MAKE_STRUCT_CASE 200 201 default: 202 os << "UNKNOWN TYPE " << map()->instance_type(); 203 UNREACHABLE(); 204 break; 205 } 206} 207 208 209void Simd128Value::Simd128ValuePrint(std::ostream& os) { // NOLINT 210#define PRINT_SIMD128_VALUE(TYPE, Type, type, lane_count, lane_type) \ 211 if (Is##Type()) return Type::cast(this)->Type##Print(os); 212 SIMD128_TYPES(PRINT_SIMD128_VALUE) 213#undef PRINT_SIMD128_VALUE 214 UNREACHABLE(); 215} 216 217 218void Float32x4::Float32x4Print(std::ostream& os) { // NOLINT 219 char arr[100]; 220 Vector<char> buffer(arr, arraysize(arr)); 221 os << std::string(DoubleToCString(get_lane(0), buffer)) << ", " 222 << std::string(DoubleToCString(get_lane(1), buffer)) << ", " 223 << std::string(DoubleToCString(get_lane(2), buffer)) << ", " 224 << std::string(DoubleToCString(get_lane(3), buffer)); 225} 226 227 228#define SIMD128_INT_PRINT_FUNCTION(type, lane_count) \ 229 void type::type##Print(std::ostream& os) { \ 230 char arr[100]; \ 231 Vector<char> buffer(arr, arraysize(arr)); \ 232 os << std::string(IntToCString(get_lane(0), buffer)); \ 233 for (int i = 1; i < lane_count; i++) { \ 234 os << ", " << std::string(IntToCString(get_lane(i), buffer)); \ 235 } \ 236 } 237SIMD128_INT_PRINT_FUNCTION(Int32x4, 4) 238SIMD128_INT_PRINT_FUNCTION(Uint32x4, 4) 239SIMD128_INT_PRINT_FUNCTION(Int16x8, 8) 240SIMD128_INT_PRINT_FUNCTION(Uint16x8, 8) 241SIMD128_INT_PRINT_FUNCTION(Int8x16, 16) 242SIMD128_INT_PRINT_FUNCTION(Uint8x16, 16) 243#undef SIMD128_INT_PRINT_FUNCTION 244 245 246#define SIMD128_BOOL_PRINT_FUNCTION(type, lane_count) \ 247 void type::type##Print(std::ostream& os) { \ 248 char arr[100]; \ 249 Vector<char> buffer(arr, arraysize(arr)); \ 250 os << std::string(get_lane(0) ? "true" : "false"); \ 251 for (int i = 1; i < lane_count; i++) { \ 252 os << ", " << std::string(get_lane(i) ? "true" : "false"); \ 253 } \ 254 } 255SIMD128_BOOL_PRINT_FUNCTION(Bool32x4, 4) 256SIMD128_BOOL_PRINT_FUNCTION(Bool16x8, 8) 257SIMD128_BOOL_PRINT_FUNCTION(Bool8x16, 16) 258#undef SIMD128_BOOL_PRINT_FUNCTION 259 260 261void ByteArray::ByteArrayPrint(std::ostream& os) { // NOLINT 262 os << "byte array, data starts at " << GetDataStartAddress(); 263} 264 265 266void BytecodeArray::BytecodeArrayPrint(std::ostream& os) { // NOLINT 267 Disassemble(os); 268} 269 270 271void FreeSpace::FreeSpacePrint(std::ostream& os) { // NOLINT 272 os << "free space, size " << Size(); 273} 274 275 276template <class Traits> 277void FixedTypedArray<Traits>::FixedTypedArrayPrint( 278 std::ostream& os) { // NOLINT 279 os << "fixed " << Traits::Designator(); 280} 281 282 283void JSObject::PrintProperties(std::ostream& os) { // NOLINT 284 if (HasFastProperties()) { 285 DescriptorArray* descs = map()->instance_descriptors(); 286 for (int i = 0; i < map()->NumberOfOwnDescriptors(); i++) { 287 os << "\n "; 288 descs->GetKey(i)->NamePrint(os); 289 os << ": "; 290 switch (descs->GetType(i)) { 291 case DATA: { 292 FieldIndex index = FieldIndex::ForDescriptor(map(), i); 293 if (IsUnboxedDoubleField(index)) { 294 os << "<unboxed double> " << RawFastDoublePropertyAt(index); 295 } else { 296 os << Brief(RawFastPropertyAt(index)); 297 } 298 os << " (data field at offset " << index.property_index() << ")"; 299 break; 300 } 301 case ACCESSOR: { 302 FieldIndex index = FieldIndex::ForDescriptor(map(), i); 303 os << " (accessor field at offset " << index.property_index() << ")"; 304 break; 305 } 306 case DATA_CONSTANT: 307 os << Brief(descs->GetConstant(i)) << " (data constant)"; 308 break; 309 case ACCESSOR_CONSTANT: 310 os << Brief(descs->GetCallbacksObject(i)) << " (accessor constant)"; 311 break; 312 } 313 } 314 } else if (IsJSGlobalObject()) { 315 global_dictionary()->Print(os); 316 } else { 317 property_dictionary()->Print(os); 318 } 319} 320 321 322template <class T> 323static void DoPrintElements(std::ostream& os, Object* object) { // NOLINT 324 T* p = T::cast(object); 325 for (int i = 0; i < p->length(); i++) { 326 os << "\n " << i << ": " << p->get_scalar(i); 327 } 328} 329 330 331void JSObject::PrintElements(std::ostream& os) { // NOLINT 332 // Don't call GetElementsKind, its validation code can cause the printer to 333 // fail when debugging. 334 switch (map()->elements_kind()) { 335 case FAST_HOLEY_SMI_ELEMENTS: 336 case FAST_SMI_ELEMENTS: 337 case FAST_HOLEY_ELEMENTS: 338 case FAST_ELEMENTS: 339 case FAST_STRING_WRAPPER_ELEMENTS: { 340 // Print in array notation for non-sparse arrays. 341 FixedArray* p = FixedArray::cast(elements()); 342 for (int i = 0; i < p->length(); i++) { 343 os << "\n " << i << ": " << Brief(p->get(i)); 344 } 345 break; 346 } 347 case FAST_HOLEY_DOUBLE_ELEMENTS: 348 case FAST_DOUBLE_ELEMENTS: { 349 // Print in array notation for non-sparse arrays. 350 if (elements()->length() > 0) { 351 FixedDoubleArray* p = FixedDoubleArray::cast(elements()); 352 for (int i = 0; i < p->length(); i++) { 353 os << "\n " << i << ": "; 354 if (p->is_the_hole(i)) { 355 os << "<the hole>"; 356 } else { 357 os << p->get_scalar(i); 358 } 359 } 360 } 361 break; 362 } 363 364 365#define PRINT_ELEMENTS(Kind, Type) \ 366 case Kind: { \ 367 DoPrintElements<Type>(os, elements()); \ 368 break; \ 369 } 370 371 PRINT_ELEMENTS(UINT8_ELEMENTS, FixedUint8Array) 372 PRINT_ELEMENTS(UINT8_CLAMPED_ELEMENTS, FixedUint8ClampedArray) 373 PRINT_ELEMENTS(INT8_ELEMENTS, FixedInt8Array) 374 PRINT_ELEMENTS(UINT16_ELEMENTS, FixedUint16Array) 375 PRINT_ELEMENTS(INT16_ELEMENTS, FixedInt16Array) 376 PRINT_ELEMENTS(UINT32_ELEMENTS, FixedUint32Array) 377 PRINT_ELEMENTS(INT32_ELEMENTS, FixedInt32Array) 378 PRINT_ELEMENTS(FLOAT32_ELEMENTS, FixedFloat32Array) 379 PRINT_ELEMENTS(FLOAT64_ELEMENTS, FixedFloat64Array) 380 381#undef PRINT_ELEMENTS 382 383 case DICTIONARY_ELEMENTS: 384 case SLOW_STRING_WRAPPER_ELEMENTS: 385 SeededNumberDictionary::cast(elements())->Print(os); 386 break; 387 case FAST_SLOPPY_ARGUMENTS_ELEMENTS: 388 case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: { 389 FixedArray* p = FixedArray::cast(elements()); 390 os << "\n parameter map:"; 391 for (int i = 2; i < p->length(); i++) { 392 os << " " << (i - 2) << ":" << Brief(p->get(i)); 393 } 394 os << "\n context: " << Brief(p->get(0)) 395 << "\n arguments: " << Brief(p->get(1)); 396 break; 397 } 398 case NO_ELEMENTS: 399 break; 400 } 401} 402 403 404static void JSObjectPrintHeader(std::ostream& os, JSObject* obj, 405 const char* id) { // NOLINT 406 obj->PrintHeader(os, id); 407 // Don't call GetElementsKind, its validation code can cause the printer to 408 // fail when debugging. 409 os << "\n - map = " << reinterpret_cast<void*>(obj->map()) << " ["; 410 if (obj->HasFastProperties()) { 411 os << "FastProperties"; 412 } else { 413 os << "DictionaryProperties"; 414 } 415 PrototypeIterator iter(obj->GetIsolate(), obj); 416 os << "]\n - prototype = " << reinterpret_cast<void*>(iter.GetCurrent()); 417 os << "\n - elements = " << Brief(obj->elements()) << " [" 418 << ElementsKindToString(obj->map()->elements_kind()); 419 if (obj->elements()->map() == obj->GetHeap()->fixed_cow_array_map()) { 420 os << " (COW)"; 421 } 422 os << "]"; 423} 424 425 426static void JSObjectPrintBody(std::ostream& os, JSObject* obj, // NOLINT 427 bool print_elements = true) { 428 os << "\n - properties = {"; 429 obj->PrintProperties(os); 430 os << "\n }\n"; 431 if (print_elements && obj->elements()->length() > 0) { 432 os << " - elements = {"; 433 obj->PrintElements(os); 434 os << "\n }\n"; 435 } 436} 437 438 439void JSObject::JSObjectPrint(std::ostream& os) { // NOLINT 440 JSObjectPrintHeader(os, this, nullptr); 441 JSObjectPrintBody(os, this); 442} 443 444void JSArray::JSArrayPrint(std::ostream& os) { // NOLINT 445 JSObjectPrintHeader(os, this, "JSArray"); 446 os << "\n - length = " << Brief(this->length()); 447 JSObjectPrintBody(os, this); 448} 449 450 451void JSRegExp::JSRegExpPrint(std::ostream& os) { // NOLINT 452 JSObjectPrintHeader(os, this, "JSRegExp"); 453 os << "\n - data = " << Brief(data()); 454 JSObjectPrintBody(os, this); 455} 456 457 458void JSModule::JSModulePrint(std::ostream& os) { // NOLINT 459 JSObjectPrintHeader(os, this, "JSModule"); 460 os << "\n - context = " << Brief(context()); 461 os << " - scope_info = " << Brief(scope_info()); 462 JSObjectPrintBody(os, this); 463} 464 465 466void Symbol::SymbolPrint(std::ostream& os) { // NOLINT 467 HeapObject::PrintHeader(os, "Symbol"); 468 os << "\n - hash: " << Hash(); 469 os << "\n - name: " << Brief(name()); 470 if (name()->IsUndefined(GetIsolate())) { 471 os << " (" << PrivateSymbolToName() << ")"; 472 } 473 os << "\n - private: " << is_private(); 474 os << "\n"; 475} 476 477 478void Map::MapPrint(std::ostream& os) { // NOLINT 479 HeapObject::PrintHeader(os, "Map"); 480 os << "\n - type: " << instance_type(); 481 os << "\n - instance size: " << instance_size(); 482 if (IsJSObjectMap()) { 483 os << "\n - inobject properties: " << GetInObjectProperties(); 484 } 485 os << "\n - elements kind: " << ElementsKindToString(elements_kind()); 486 os << "\n - unused property fields: " << unused_property_fields(); 487 os << "\n - enum length: "; 488 if (EnumLength() == kInvalidEnumCacheSentinel) { 489 os << "invalid"; 490 } else { 491 os << EnumLength(); 492 } 493 if (is_deprecated()) os << "\n - deprecated_map"; 494 if (is_stable()) os << "\n - stable_map"; 495 if (is_dictionary_map()) os << "\n - dictionary_map"; 496 if (has_hidden_prototype()) os << "\n - has_hidden_prototype"; 497 if (has_named_interceptor()) os << " - named_interceptor"; 498 if (has_indexed_interceptor()) os << "\n - indexed_interceptor"; 499 if (is_undetectable()) os << "\n - undetectable"; 500 if (is_callable()) os << "\n - callable"; 501 if (is_constructor()) os << "\n - constructor"; 502 if (is_access_check_needed()) os << "\n - access_check_needed"; 503 if (!is_extensible()) os << "\n - non-extensible"; 504 if (is_prototype_map()) { 505 os << "\n - prototype_map"; 506 os << "\n - prototype info: " << Brief(prototype_info()); 507 } else { 508 os << "\n - back pointer: " << Brief(GetBackPointer()); 509 } 510 os << "\n - instance descriptors " << (owns_descriptors() ? "(own) " : "") 511 << "#" << NumberOfOwnDescriptors() << ": " 512 << Brief(instance_descriptors()); 513 if (FLAG_unbox_double_fields) { 514 os << "\n - layout descriptor: " << Brief(layout_descriptor()); 515 } 516 int nof_transitions = TransitionArray::NumberOfTransitions(raw_transitions()); 517 if (nof_transitions > 0) { 518 os << "\n - transitions #" << nof_transitions << ": " 519 << Brief(raw_transitions()); 520 TransitionArray::PrintTransitions(os, raw_transitions(), false); 521 } 522 os << "\n - prototype: " << Brief(prototype()); 523 os << "\n - constructor: " << Brief(GetConstructor()); 524 os << "\n - code cache: " << Brief(code_cache()); 525 os << "\n - dependent code: " << Brief(dependent_code()); 526 os << "\n - construction counter: " << construction_counter(); 527 os << "\n"; 528} 529 530 531void TypeFeedbackInfo::TypeFeedbackInfoPrint(std::ostream& os) { // NOLINT 532 HeapObject::PrintHeader(os, "TypeFeedbackInfo"); 533 os << "\n - ic_total_count: " << ic_total_count() 534 << ", ic_with_type_info_count: " << ic_with_type_info_count() 535 << ", ic_generic_count: " << ic_generic_count() << "\n"; 536} 537 538 539void AliasedArgumentsEntry::AliasedArgumentsEntryPrint( 540 std::ostream& os) { // NOLINT 541 HeapObject::PrintHeader(os, "AliasedArgumentsEntry"); 542 os << "\n - aliased_context_slot: " << aliased_context_slot(); 543} 544 545 546void FixedArray::FixedArrayPrint(std::ostream& os) { // NOLINT 547 HeapObject::PrintHeader(os, "FixedArray"); 548 os << "\n - length: " << length(); 549 for (int i = 0; i < length(); i++) { 550 os << "\n [" << i << "]: " << Brief(get(i)); 551 } 552 os << "\n"; 553} 554 555 556void FixedDoubleArray::FixedDoubleArrayPrint(std::ostream& os) { // NOLINT 557 HeapObject::PrintHeader(os, "FixedDoubleArray"); 558 os << "\n - length: " << length(); 559 for (int i = 0; i < length(); i++) { 560 os << "\n [" << i << "]: "; 561 if (is_the_hole(i)) { 562 os << "<the hole>"; 563 } else { 564 os << get_scalar(i); 565 } 566 } 567 os << "\n"; 568} 569 570 571void TransitionArray::TransitionArrayPrint(std::ostream& os) { // NOLINT 572 HeapObject::PrintHeader(os, "TransitionArray"); 573 os << "\n - capacity: " << length(); 574 for (int i = 0; i < length(); i++) { 575 os << "\n [" << i << "]: " << Brief(get(i)); 576 if (i == kNextLinkIndex) os << " (next link)"; 577 if (i == kPrototypeTransitionsIndex) os << " (prototype transitions)"; 578 if (i == kTransitionLengthIndex) os << " (number of transitions)"; 579 } 580 os << "\n"; 581} 582 583template void FeedbackVectorSpecBase<StaticFeedbackVectorSpec>::Print(); 584template void FeedbackVectorSpecBase<FeedbackVectorSpec>::Print(); 585 586template <typename Derived> 587void FeedbackVectorSpecBase<Derived>::Print() { 588 OFStream os(stdout); 589 FeedbackVectorSpecPrint(os); 590 os << std::flush; 591} 592 593template <typename Derived> 594void FeedbackVectorSpecBase<Derived>::FeedbackVectorSpecPrint( 595 std::ostream& os) { // NOLINT 596 int slot_count = This()->slots(); 597 os << " - slot_count: " << slot_count; 598 if (slot_count == 0) { 599 os << " (empty)\n"; 600 return; 601 } 602 603 for (int slot = 0, name_index = 0; slot < slot_count;) { 604 FeedbackVectorSlotKind kind = This()->GetKind(slot); 605 int entry_size = TypeFeedbackMetadata::GetSlotSize(kind); 606 DCHECK_LT(0, entry_size); 607 608 os << "\n Slot #" << slot << " " << kind; 609 if (TypeFeedbackMetadata::SlotRequiresName(kind)) { 610 os << ", " << Brief(*This()->GetName(name_index++)); 611 } 612 613 slot += entry_size; 614 } 615 os << "\n"; 616} 617 618void TypeFeedbackMetadata::Print() { 619 OFStream os(stdout); 620 TypeFeedbackMetadataPrint(os); 621 os << std::flush; 622} 623 624 625void TypeFeedbackMetadata::TypeFeedbackMetadataPrint( 626 std::ostream& os) { // NOLINT 627 HeapObject::PrintHeader(os, "TypeFeedbackMetadata"); 628 os << "\n - length: " << length(); 629 if (length() == 0) { 630 os << " (empty)\n"; 631 return; 632 } 633 os << "\n - slot_count: " << slot_count(); 634 635 TypeFeedbackMetadataIterator iter(this); 636 while (iter.HasNext()) { 637 FeedbackVectorSlot slot = iter.Next(); 638 FeedbackVectorSlotKind kind = iter.kind(); 639 os << "\n Slot " << slot << " " << kind; 640 if (TypeFeedbackMetadata::SlotRequiresName(kind)) { 641 os << ", " << Brief(iter.name()); 642 } 643 } 644 os << "\n"; 645} 646 647 648void TypeFeedbackVector::Print() { 649 OFStream os(stdout); 650 TypeFeedbackVectorPrint(os); 651 os << std::flush; 652} 653 654 655void TypeFeedbackVector::TypeFeedbackVectorPrint(std::ostream& os) { // NOLINT 656 HeapObject::PrintHeader(os, "TypeFeedbackVector"); 657 os << "\n - length: " << length(); 658 if (length() == 0) { 659 os << " (empty)\n"; 660 return; 661 } 662 663 TypeFeedbackMetadataIterator iter(metadata()); 664 while (iter.HasNext()) { 665 FeedbackVectorSlot slot = iter.Next(); 666 FeedbackVectorSlotKind kind = iter.kind(); 667 668 os << "\n Slot " << slot << " " << kind; 669 if (TypeFeedbackMetadata::SlotRequiresName(kind)) { 670 os << ", " << Brief(iter.name()); 671 } 672 os << " "; 673 switch (kind) { 674 case FeedbackVectorSlotKind::LOAD_IC: { 675 LoadICNexus nexus(this, slot); 676 os << Code::ICState2String(nexus.StateFromFeedback()); 677 break; 678 } 679 case FeedbackVectorSlotKind::LOAD_GLOBAL_IC: { 680 LoadGlobalICNexus nexus(this, slot); 681 os << Code::ICState2String(nexus.StateFromFeedback()); 682 break; 683 } 684 case FeedbackVectorSlotKind::KEYED_LOAD_IC: { 685 KeyedLoadICNexus nexus(this, slot); 686 os << Code::ICState2String(nexus.StateFromFeedback()); 687 break; 688 } 689 case FeedbackVectorSlotKind::CALL_IC: { 690 CallICNexus nexus(this, slot); 691 os << Code::ICState2String(nexus.StateFromFeedback()); 692 break; 693 } 694 case FeedbackVectorSlotKind::STORE_IC: { 695 StoreICNexus nexus(this, slot); 696 os << Code::ICState2String(nexus.StateFromFeedback()); 697 break; 698 } 699 case FeedbackVectorSlotKind::KEYED_STORE_IC: { 700 KeyedStoreICNexus nexus(this, slot); 701 os << Code::ICState2String(nexus.StateFromFeedback()); 702 break; 703 } 704 case FeedbackVectorSlotKind::GENERAL: 705 break; 706 case FeedbackVectorSlotKind::INVALID: 707 case FeedbackVectorSlotKind::KINDS_NUMBER: 708 UNREACHABLE(); 709 break; 710 } 711 712 int entry_size = iter.entry_size(); 713 for (int i = 0; i < entry_size; i++) { 714 int index = GetIndex(slot) + i; 715 os << "\n [" << index << "]: " << Brief(get(index)); 716 } 717 } 718 os << "\n"; 719} 720 721 722void JSValue::JSValuePrint(std::ostream& os) { // NOLINT 723 JSObjectPrintHeader(os, this, "JSValue"); 724 os << "\n - value = " << Brief(value()); 725 JSObjectPrintBody(os, this); 726} 727 728 729void JSMessageObject::JSMessageObjectPrint(std::ostream& os) { // NOLINT 730 JSObjectPrintHeader(os, this, "JSMessageObject"); 731 os << "\n - type: " << type(); 732 os << "\n - arguments: " << Brief(argument()); 733 os << "\n - start_position: " << start_position(); 734 os << "\n - end_position: " << end_position(); 735 os << "\n - script: " << Brief(script()); 736 os << "\n - stack_frames: " << Brief(stack_frames()); 737 JSObjectPrintBody(os, this); 738} 739 740 741void String::StringPrint(std::ostream& os) { // NOLINT 742 if (StringShape(this).IsInternalized()) { 743 os << "#"; 744 } else if (StringShape(this).IsCons()) { 745 os << "c\""; 746 } else { 747 os << "\""; 748 } 749 750 const char truncated_epilogue[] = "...<truncated>"; 751 int len = length(); 752 if (!FLAG_use_verbose_printer) { 753 if (len > 100) { 754 len = 100 - sizeof(truncated_epilogue); 755 } 756 } 757 for (int i = 0; i < len; i++) { 758 os << AsUC16(Get(i)); 759 } 760 if (len != length()) { 761 os << truncated_epilogue; 762 } 763 764 if (!StringShape(this).IsInternalized()) os << "\""; 765} 766 767 768void Name::NamePrint(std::ostream& os) { // NOLINT 769 if (IsString()) { 770 String::cast(this)->StringPrint(os); 771 } else { 772 os << Brief(this); 773 } 774} 775 776 777static const char* const weekdays[] = { 778 "???", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" 779}; 780 781 782void JSDate::JSDatePrint(std::ostream& os) { // NOLINT 783 JSObjectPrintHeader(os, this, "JSDate"); 784 os << "\n - value = " << Brief(value()); 785 if (!year()->IsSmi()) { 786 os << "\n - time = NaN\n"; 787 } else { 788 // TODO(svenpanne) Add some basic formatting to our streams. 789 ScopedVector<char> buf(100); 790 SNPrintF( 791 buf, "\n - time = %s %04d/%02d/%02d %02d:%02d:%02d\n", 792 weekdays[weekday()->IsSmi() ? Smi::cast(weekday())->value() + 1 : 0], 793 year()->IsSmi() ? Smi::cast(year())->value() : -1, 794 month()->IsSmi() ? Smi::cast(month())->value() : -1, 795 day()->IsSmi() ? Smi::cast(day())->value() : -1, 796 hour()->IsSmi() ? Smi::cast(hour())->value() : -1, 797 min()->IsSmi() ? Smi::cast(min())->value() : -1, 798 sec()->IsSmi() ? Smi::cast(sec())->value() : -1); 799 os << buf.start(); 800 } 801 JSObjectPrintBody(os, this); 802} 803 804 805void JSProxy::JSProxyPrint(std::ostream& os) { // NOLINT 806 HeapObject::PrintHeader(os, "JSProxy"); 807 os << "\n - map = " << reinterpret_cast<void*>(map()); 808 os << "\n - target = "; 809 target()->ShortPrint(os); 810 os << "\n - handler = "; 811 handler()->ShortPrint(os); 812 os << "\n - hash = "; 813 hash()->ShortPrint(os); 814 os << "\n"; 815} 816 817 818void JSSet::JSSetPrint(std::ostream& os) { // NOLINT 819 JSObjectPrintHeader(os, this, "JSSet"); 820 os << " - table = " << Brief(table()); 821 JSObjectPrintBody(os, this); 822} 823 824 825void JSMap::JSMapPrint(std::ostream& os) { // NOLINT 826 JSObjectPrintHeader(os, this, "JSMap"); 827 os << " - table = " << Brief(table()); 828 JSObjectPrintBody(os, this); 829} 830 831 832template <class Derived, class TableType> 833void 834OrderedHashTableIterator<Derived, TableType>::OrderedHashTableIteratorPrint( 835 std::ostream& os) { // NOLINT 836 os << "\n - table = " << Brief(table()); 837 os << "\n - index = " << Brief(index()); 838 os << "\n - kind = " << Brief(kind()); 839 os << "\n"; 840} 841 842 843template void OrderedHashTableIterator< 844 JSSetIterator, 845 OrderedHashSet>::OrderedHashTableIteratorPrint(std::ostream& os); // NOLINT 846 847 848template void OrderedHashTableIterator< 849 JSMapIterator, 850 OrderedHashMap>::OrderedHashTableIteratorPrint(std::ostream& os); // NOLINT 851 852 853void JSSetIterator::JSSetIteratorPrint(std::ostream& os) { // NOLINT 854 JSObjectPrintHeader(os, this, "JSSetIterator"); 855 OrderedHashTableIteratorPrint(os); 856} 857 858 859void JSMapIterator::JSMapIteratorPrint(std::ostream& os) { // NOLINT 860 JSObjectPrintHeader(os, this, "JSMapIterator"); 861 OrderedHashTableIteratorPrint(os); 862} 863 864 865void JSWeakMap::JSWeakMapPrint(std::ostream& os) { // NOLINT 866 JSObjectPrintHeader(os, this, "JSWeakMap"); 867 os << "\n - table = " << Brief(table()); 868 JSObjectPrintBody(os, this); 869} 870 871 872void JSWeakSet::JSWeakSetPrint(std::ostream& os) { // NOLINT 873 JSObjectPrintHeader(os, this, "JSWeakSet"); 874 os << "\n - table = " << Brief(table()); 875 JSObjectPrintBody(os, this); 876} 877 878 879void JSArrayBuffer::JSArrayBufferPrint(std::ostream& os) { // NOLINT 880 JSObjectPrintHeader(os, this, "JSArrayBuffer"); 881 os << "\n - backing_store = " << backing_store(); 882 os << "\n - byte_length = " << Brief(byte_length()); 883 if (was_neutered()) os << " - neutered\n"; 884 JSObjectPrintBody(os, this, !was_neutered()); 885} 886 887 888void JSTypedArray::JSTypedArrayPrint(std::ostream& os) { // NOLINT 889 JSObjectPrintHeader(os, this, "JSTypedArray"); 890 os << "\n - buffer = " << Brief(buffer()); 891 os << "\n - byte_offset = " << Brief(byte_offset()); 892 os << "\n - byte_length = " << Brief(byte_length()); 893 os << "\n - length = " << Brief(length()); 894 if (WasNeutered()) os << " - neutered\n"; 895 JSObjectPrintBody(os, this, !WasNeutered()); 896} 897 898 899void JSDataView::JSDataViewPrint(std::ostream& os) { // NOLINT 900 JSObjectPrintHeader(os, this, "JSDataView"); 901 os << "\n - buffer =" << Brief(buffer()); 902 os << "\n - byte_offset = " << Brief(byte_offset()); 903 os << "\n - byte_length = " << Brief(byte_length()); 904 if (WasNeutered()) os << " - neutered\n"; 905 JSObjectPrintBody(os, this, !WasNeutered()); 906} 907 908 909void JSBoundFunction::JSBoundFunctionPrint(std::ostream& os) { // NOLINT 910 JSObjectPrintHeader(os, this, "JSBoundFunction"); 911 os << "\n - bound_target_function = " << Brief(bound_target_function()); 912 os << "\n - bound_this = " << Brief(bound_this()); 913 os << "\n - bound_arguments = " << Brief(bound_arguments()); 914 JSObjectPrintBody(os, this); 915} 916 917 918void JSFunction::JSFunctionPrint(std::ostream& os) { // NOLINT 919 JSObjectPrintHeader(os, this, "Function"); 920 os << "\n - initial_map = "; 921 if (has_initial_map()) os << Brief(initial_map()); 922 os << "\n - shared_info = " << Brief(shared()); 923 os << "\n - name = " << Brief(shared()->name()); 924 os << "\n - formal_parameter_count = " 925 << shared()->internal_formal_parameter_count(); 926 if (shared()->is_generator()) { 927 os << "\n - generator"; 928 } else if (shared()->is_async()) { 929 os << "\n - async"; 930 } 931 os << "\n - context = " << Brief(context()); 932 os << "\n - literals = " << Brief(literals()); 933 os << "\n - code = " << Brief(code()); 934 JSObjectPrintBody(os, this); 935} 936 937 938void SharedFunctionInfo::SharedFunctionInfoPrint(std::ostream& os) { // NOLINT 939 HeapObject::PrintHeader(os, "SharedFunctionInfo"); 940 os << "\n - name = " << Brief(name()); 941 os << "\n - formal_parameter_count = " << internal_formal_parameter_count(); 942 os << "\n - expected_nof_properties = " << expected_nof_properties(); 943 os << "\n - ast_node_count = " << ast_node_count(); 944 os << "\n - instance class name = "; 945 instance_class_name()->Print(os); 946 os << "\n - code = " << Brief(code()); 947 if (HasSourceCode()) { 948 os << "\n - source code = "; 949 String* source = String::cast(Script::cast(script())->source()); 950 int start = start_position(); 951 int length = end_position() - start; 952 base::SmartArrayPointer<char> source_string = source->ToCString( 953 DISALLOW_NULLS, FAST_STRING_TRAVERSAL, start, length, NULL); 954 os << source_string.get(); 955 } 956 // Script files are often large, hard to read. 957 // os << "\n - script ="; 958 // script()->Print(os); 959 if (is_named_expression()) { 960 os << "\n - named expression"; 961 } else if (is_anonymous_expression()) { 962 os << "\n - anonymous expression"; 963 } else if (is_declaration()) { 964 os << "\n - declaration"; 965 } 966 os << "\n - function token position = " << function_token_position(); 967 os << "\n - start position = " << start_position(); 968 os << "\n - end position = " << end_position(); 969 os << "\n - debug info = " << Brief(debug_info()); 970 os << "\n - length = " << length(); 971 os << "\n - num_literals = " << num_literals(); 972 os << "\n - optimized_code_map = " << Brief(optimized_code_map()); 973 os << "\n - feedback_metadata = "; 974 feedback_metadata()->TypeFeedbackMetadataPrint(os); 975 if (HasBytecodeArray()) { 976 os << "\n - bytecode_array = " << bytecode_array(); 977 } 978 os << "\n"; 979} 980 981 982void JSGlobalProxy::JSGlobalProxyPrint(std::ostream& os) { // NOLINT 983 os << "global_proxy "; 984 JSObjectPrint(os); 985 os << "native context : " << Brief(native_context()); 986 os << "\n"; 987} 988 989 990void JSGlobalObject::JSGlobalObjectPrint(std::ostream& os) { // NOLINT 991 os << "global "; 992 JSObjectPrint(os); 993 os << "native context : " << Brief(native_context()); 994 os << "\n"; 995} 996 997 998void Cell::CellPrint(std::ostream& os) { // NOLINT 999 HeapObject::PrintHeader(os, "Cell"); 1000 os << "\n - value: " << Brief(value()); 1001 os << "\n"; 1002} 1003 1004 1005void PropertyCell::PropertyCellPrint(std::ostream& os) { // NOLINT 1006 HeapObject::PrintHeader(os, "PropertyCell"); 1007 os << "\n - value: " << Brief(value()); 1008 os << "\n - details: " << property_details(); 1009 os << "\n"; 1010} 1011 1012 1013void WeakCell::WeakCellPrint(std::ostream& os) { // NOLINT 1014 HeapObject::PrintHeader(os, "WeakCell"); 1015 if (cleared()) { 1016 os << "\n - cleared"; 1017 } else { 1018 os << "\n - value: " << Brief(value()); 1019 } 1020 os << "\n"; 1021} 1022 1023 1024void Code::CodePrint(std::ostream& os) { // NOLINT 1025 HeapObject::PrintHeader(os, "Code"); 1026 os << "\n"; 1027#ifdef ENABLE_DISASSEMBLER 1028 if (FLAG_use_verbose_printer) { 1029 Disassemble(NULL, os); 1030 } 1031#endif 1032} 1033 1034 1035void Foreign::ForeignPrint(std::ostream& os) { // NOLINT 1036 os << "foreign address : " << foreign_address(); 1037 os << "\n"; 1038} 1039 1040 1041void AccessorInfo::AccessorInfoPrint(std::ostream& os) { // NOLINT 1042 HeapObject::PrintHeader(os, "AccessorInfo"); 1043 os << "\n - name: " << Brief(name()); 1044 os << "\n - flag: " << flag(); 1045 os << "\n - getter: " << Brief(getter()); 1046 os << "\n - setter: " << Brief(setter()); 1047 os << "\n - js_getter: " << Brief(js_getter()); 1048 os << "\n - data: " << Brief(data()); 1049 os << "\n"; 1050} 1051 1052 1053void Box::BoxPrint(std::ostream& os) { // NOLINT 1054 HeapObject::PrintHeader(os, "Box"); 1055 os << "\n - value: " << Brief(value()); 1056 os << "\n"; 1057} 1058 1059 1060void PrototypeInfo::PrototypeInfoPrint(std::ostream& os) { // NOLINT 1061 HeapObject::PrintHeader(os, "PrototypeInfo"); 1062 os << "\n - prototype users: " << Brief(prototype_users()); 1063 os << "\n - registry slot: " << registry_slot(); 1064 os << "\n - validity cell: " << Brief(validity_cell()); 1065 os << "\n"; 1066} 1067 1068 1069void SloppyBlockWithEvalContextExtension:: 1070 SloppyBlockWithEvalContextExtensionPrint(std::ostream& os) { // NOLINT 1071 HeapObject::PrintHeader(os, "SloppyBlockWithEvalContextExtension"); 1072 os << "\n - scope_info: " << Brief(scope_info()); 1073 os << "\n - extension: " << Brief(extension()); 1074 os << "\n"; 1075} 1076 1077 1078void AccessorPair::AccessorPairPrint(std::ostream& os) { // NOLINT 1079 HeapObject::PrintHeader(os, "AccessorPair"); 1080 os << "\n - getter: " << Brief(getter()); 1081 os << "\n - setter: " << Brief(setter()); 1082 os << "\n"; 1083} 1084 1085 1086void AccessCheckInfo::AccessCheckInfoPrint(std::ostream& os) { // NOLINT 1087 HeapObject::PrintHeader(os, "AccessCheckInfo"); 1088 os << "\n - callback: " << Brief(callback()); 1089 os << "\n - named_interceptor: " << Brief(named_interceptor()); 1090 os << "\n - indexed_interceptor: " << Brief(indexed_interceptor()); 1091 os << "\n - data: " << Brief(data()); 1092 os << "\n"; 1093} 1094 1095 1096void InterceptorInfo::InterceptorInfoPrint(std::ostream& os) { // NOLINT 1097 HeapObject::PrintHeader(os, "InterceptorInfo"); 1098 os << "\n - getter: " << Brief(getter()); 1099 os << "\n - setter: " << Brief(setter()); 1100 os << "\n - query: " << Brief(query()); 1101 os << "\n - deleter: " << Brief(deleter()); 1102 os << "\n - enumerator: " << Brief(enumerator()); 1103 os << "\n - data: " << Brief(data()); 1104 os << "\n"; 1105} 1106 1107 1108void CallHandlerInfo::CallHandlerInfoPrint(std::ostream& os) { // NOLINT 1109 HeapObject::PrintHeader(os, "CallHandlerInfo"); 1110 os << "\n - callback: " << Brief(callback()); 1111 os << "\n - data: " << Brief(data()); 1112 os << "\n"; 1113} 1114 1115 1116void FunctionTemplateInfo::FunctionTemplateInfoPrint( 1117 std::ostream& os) { // NOLINT 1118 HeapObject::PrintHeader(os, "FunctionTemplateInfo"); 1119 os << "\n - class name: " << Brief(class_name()); 1120 os << "\n - tag: " << Brief(tag()); 1121 os << "\n - serial_number: " << Brief(serial_number()); 1122 os << "\n - property_list: " << Brief(property_list()); 1123 os << "\n - call_code: " << Brief(call_code()); 1124 os << "\n - property_accessors: " << Brief(property_accessors()); 1125 os << "\n - prototype_template: " << Brief(prototype_template()); 1126 os << "\n - parent_template: " << Brief(parent_template()); 1127 os << "\n - named_property_handler: " << Brief(named_property_handler()); 1128 os << "\n - indexed_property_handler: " << Brief(indexed_property_handler()); 1129 os << "\n - instance_template: " << Brief(instance_template()); 1130 os << "\n - signature: " << Brief(signature()); 1131 os << "\n - access_check_info: " << Brief(access_check_info()); 1132 os << "\n - hidden_prototype: " << (hidden_prototype() ? "true" : "false"); 1133 os << "\n - undetectable: " << (undetectable() ? "true" : "false"); 1134 os << "\n - need_access_check: " << (needs_access_check() ? "true" : "false"); 1135 os << "\n - instantiated: " << (instantiated() ? "true" : "false"); 1136 os << "\n"; 1137} 1138 1139 1140void ObjectTemplateInfo::ObjectTemplateInfoPrint(std::ostream& os) { // NOLINT 1141 HeapObject::PrintHeader(os, "ObjectTemplateInfo"); 1142 os << "\n - tag: " << Brief(tag()); 1143 os << "\n - serial_number: " << Brief(serial_number()); 1144 os << "\n - property_list: " << Brief(property_list()); 1145 os << "\n - property_accessors: " << Brief(property_accessors()); 1146 os << "\n - constructor: " << Brief(constructor()); 1147 os << "\n - internal_field_count: " << Brief(internal_field_count()); 1148 os << "\n"; 1149} 1150 1151 1152void AllocationSite::AllocationSitePrint(std::ostream& os) { // NOLINT 1153 HeapObject::PrintHeader(os, "AllocationSite"); 1154 os << "\n - weak_next: " << Brief(weak_next()); 1155 os << "\n - dependent code: " << Brief(dependent_code()); 1156 os << "\n - nested site: " << Brief(nested_site()); 1157 os << "\n - memento found count: " 1158 << Brief(Smi::FromInt(memento_found_count())); 1159 os << "\n - memento create count: " 1160 << Brief(Smi::FromInt(memento_create_count())); 1161 os << "\n - pretenure decision: " 1162 << Brief(Smi::FromInt(pretenure_decision())); 1163 os << "\n - transition_info: "; 1164 if (transition_info()->IsSmi()) { 1165 ElementsKind kind = GetElementsKind(); 1166 os << "Array allocation with ElementsKind " << ElementsKindToString(kind); 1167 } else if (transition_info()->IsJSArray()) { 1168 os << "Array literal " << Brief(transition_info()); 1169 } else { 1170 os << "unknown transition_info" << Brief(transition_info()); 1171 } 1172 os << "\n"; 1173} 1174 1175 1176void AllocationMemento::AllocationMementoPrint(std::ostream& os) { // NOLINT 1177 HeapObject::PrintHeader(os, "AllocationMemento"); 1178 os << "\n - allocation site: "; 1179 if (IsValid()) { 1180 GetAllocationSite()->Print(os); 1181 } else { 1182 os << "<invalid>\n"; 1183 } 1184} 1185 1186 1187void Script::ScriptPrint(std::ostream& os) { // NOLINT 1188 HeapObject::PrintHeader(os, "Script"); 1189 os << "\n - source: " << Brief(source()); 1190 os << "\n - name: " << Brief(name()); 1191 os << "\n - line_offset: " << line_offset(); 1192 os << "\n - column_offset: " << column_offset(); 1193 os << "\n - type: " << type(); 1194 os << "\n - id: " << id(); 1195 os << "\n - context data: " << Brief(context_data()); 1196 os << "\n - wrapper: " << Brief(wrapper()); 1197 os << "\n - compilation type: " << compilation_type(); 1198 os << "\n - line ends: " << Brief(line_ends()); 1199 os << "\n - eval from shared: " << Brief(eval_from_shared()); 1200 os << "\n - eval from position: " << eval_from_position(); 1201 os << "\n - shared function infos: " << Brief(shared_function_infos()); 1202 os << "\n"; 1203} 1204 1205 1206void DebugInfo::DebugInfoPrint(std::ostream& os) { // NOLINT 1207 HeapObject::PrintHeader(os, "DebugInfo"); 1208 os << "\n - shared: " << Brief(shared()); 1209 os << "\n - code: " << Brief(abstract_code()); 1210 os << "\n - break_points: "; 1211 break_points()->Print(os); 1212} 1213 1214 1215void BreakPointInfo::BreakPointInfoPrint(std::ostream& os) { // NOLINT 1216 HeapObject::PrintHeader(os, "BreakPointInfo"); 1217 os << "\n - code_offset: " << code_offset(); 1218 os << "\n - source_position: " << source_position(); 1219 os << "\n - statement_position: " << statement_position(); 1220 os << "\n - break_point_objects: " << Brief(break_point_objects()); 1221 os << "\n"; 1222} 1223 1224 1225static void PrintBitMask(std::ostream& os, uint32_t value) { // NOLINT 1226 for (int i = 0; i < 32; i++) { 1227 if ((i & 7) == 0) os << " "; 1228 os << (((value & 1) == 0) ? "_" : "x"); 1229 value >>= 1; 1230 } 1231} 1232 1233 1234void LayoutDescriptor::Print() { 1235 OFStream os(stdout); 1236 this->Print(os); 1237 os << std::flush; 1238} 1239 1240 1241void LayoutDescriptor::Print(std::ostream& os) { // NOLINT 1242 os << "Layout descriptor: "; 1243 if (IsOddball() && IsUninitialized(HeapObject::cast(this)->GetIsolate())) { 1244 os << "<uninitialized>"; 1245 } else if (IsFastPointerLayout()) { 1246 os << "<all tagged>"; 1247 } else if (IsSmi()) { 1248 os << "fast"; 1249 PrintBitMask(os, static_cast<uint32_t>(Smi::cast(this)->value())); 1250 } else { 1251 os << "slow"; 1252 int len = length(); 1253 for (int i = 0; i < len; i++) { 1254 if (i > 0) os << " |"; 1255 PrintBitMask(os, get_scalar(i)); 1256 } 1257 } 1258 os << "\n"; 1259} 1260 1261 1262#endif // OBJECT_PRINT 1263 1264 1265#if TRACE_MAPS 1266 1267 1268void Name::NameShortPrint() { 1269 if (this->IsString()) { 1270 PrintF("%s", String::cast(this)->ToCString().get()); 1271 } else { 1272 DCHECK(this->IsSymbol()); 1273 Symbol* s = Symbol::cast(this); 1274 if (s->name()->IsUndefined(GetIsolate())) { 1275 PrintF("#<%s>", s->PrivateSymbolToName()); 1276 } else { 1277 PrintF("<%s>", String::cast(s->name())->ToCString().get()); 1278 } 1279 } 1280} 1281 1282 1283int Name::NameShortPrint(Vector<char> str) { 1284 if (this->IsString()) { 1285 return SNPrintF(str, "%s", String::cast(this)->ToCString().get()); 1286 } else { 1287 DCHECK(this->IsSymbol()); 1288 Symbol* s = Symbol::cast(this); 1289 if (s->name()->IsUndefined(GetIsolate())) { 1290 return SNPrintF(str, "#<%s>", s->PrivateSymbolToName()); 1291 } else { 1292 return SNPrintF(str, "<%s>", String::cast(s->name())->ToCString().get()); 1293 } 1294 } 1295} 1296 1297 1298#endif // TRACE_MAPS 1299 1300 1301#if defined(DEBUG) || defined(OBJECT_PRINT) 1302// This method is only meant to be called from gdb for debugging purposes. 1303// Since the string can also be in two-byte encoding, non-Latin1 characters 1304// will be ignored in the output. 1305char* String::ToAsciiArray() { 1306 // Static so that subsequent calls frees previously allocated space. 1307 // This also means that previous results will be overwritten. 1308 static char* buffer = NULL; 1309 if (buffer != NULL) delete[] buffer; 1310 buffer = new char[length() + 1]; 1311 WriteToFlat(this, reinterpret_cast<uint8_t*>(buffer), 0, length()); 1312 buffer[length()] = 0; 1313 return buffer; 1314} 1315 1316 1317void DescriptorArray::Print() { 1318 OFStream os(stdout); 1319 this->PrintDescriptors(os); 1320 os << std::flush; 1321} 1322 1323 1324void DescriptorArray::PrintDescriptors(std::ostream& os) { // NOLINT 1325 HandleScope scope(GetIsolate()); 1326 os << "Descriptor array #" << number_of_descriptors(); 1327 for (int i = 0; i < number_of_descriptors(); i++) { 1328 Descriptor desc; 1329 Get(i, &desc); 1330 os << "\n " << i << ": " << desc; 1331 } 1332 os << "\n"; 1333} 1334 1335 1336void TransitionArray::Print() { 1337 OFStream os(stdout); 1338 TransitionArray::PrintTransitions(os, this); 1339 os << "\n" << std::flush; 1340} 1341 1342 1343void TransitionArray::PrintTransitions(std::ostream& os, Object* transitions, 1344 bool print_header) { // NOLINT 1345 int num_transitions = NumberOfTransitions(transitions); 1346 if (print_header) { 1347 os << "Transition array #" << num_transitions << ":"; 1348 } 1349 for (int i = 0; i < num_transitions; i++) { 1350 Name* key = GetKey(transitions, i); 1351 Map* target = GetTarget(transitions, i); 1352 os << "\n "; 1353#ifdef OBJECT_PRINT 1354 key->NamePrint(os); 1355#else 1356 key->ShortPrint(os); 1357#endif 1358 os << ": "; 1359 Heap* heap = key->GetHeap(); 1360 if (key == heap->nonextensible_symbol()) { 1361 os << "(transition to non-extensible)"; 1362 } else if (key == heap->sealed_symbol()) { 1363 os << "(transition to sealed)"; 1364 } else if (key == heap->frozen_symbol()) { 1365 os << "(transition to frozen)"; 1366 } else if (key == heap->elements_transition_symbol()) { 1367 os << "(transition to " << ElementsKindToString(target->elements_kind()) 1368 << ")"; 1369 } else if (key == heap->strict_function_transition_symbol()) { 1370 os << " (transition to strict function)"; 1371 } else { 1372 PropertyDetails details = GetTargetDetails(key, target); 1373 os << "(transition to "; 1374 if (details.location() == kDescriptor) { 1375 os << "immutable "; 1376 } 1377 os << (details.kind() == kData ? "data" : "accessor"); 1378 if (details.location() == kDescriptor) { 1379 Object* value = 1380 target->instance_descriptors()->GetValue(target->LastAdded()); 1381 os << " " << Brief(value); 1382 } 1383 os << "), attrs: " << details.attributes(); 1384 } 1385 os << " -> " << Brief(target); 1386 } 1387} 1388 1389 1390void JSObject::PrintTransitions(std::ostream& os) { // NOLINT 1391 Object* transitions = map()->raw_transitions(); 1392 int num_transitions = TransitionArray::NumberOfTransitions(transitions); 1393 if (num_transitions == 0) return; 1394 os << "\n - transitions"; 1395 TransitionArray::PrintTransitions(os, transitions, false); 1396} 1397#endif // defined(DEBUG) || defined(OBJECT_PRINT) 1398} // namespace internal 1399} // namespace v8 1400