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