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 <iomanip> 8 #include <memory> 9 10 #include "src/bootstrapper.h" 11 #include "src/disasm.h" 12 #include "src/disassembler.h" 13 #include "src/instruction-stream.h" 14 #include "src/interpreter/bytecodes.h" 15 #include "src/objects-inl.h" 16 #include "src/objects/arguments-inl.h" 17 #ifdef V8_INTL_SUPPORT 18 #include "src/objects/js-collator-inl.h" 19 #endif // V8_INTL_SUPPORT 20 #include "src/objects/data-handler-inl.h" 21 #include "src/objects/debug-objects-inl.h" 22 #include "src/objects/hash-table-inl.h" 23 #include "src/objects/js-array-buffer-inl.h" 24 #include "src/objects/js-array-inl.h" 25 #include "src/objects/js-collection-inl.h" 26 #include "src/objects/js-generator-inl.h" 27 #ifdef V8_INTL_SUPPORT 28 #include "src/objects/js-list-format-inl.h" 29 #include "src/objects/js-locale-inl.h" 30 #endif // V8_INTL_SUPPORT 31 #include "src/objects/js-regexp-inl.h" 32 #include "src/objects/js-regexp-string-iterator-inl.h" 33 #ifdef V8_INTL_SUPPORT 34 #include "src/objects/js-plural-rules-inl.h" 35 #include "src/objects/js-relative-time-format-inl.h" 36 #endif // V8_INTL_SUPPORT 37 #include "src/objects/literal-objects-inl.h" 38 #include "src/objects/microtask-inl.h" 39 #include "src/objects/module-inl.h" 40 #include "src/objects/promise-inl.h" 41 #include "src/ostreams.h" 42 #include "src/regexp/jsregexp.h" 43 #include "src/transitions-inl.h" 44 #include "src/wasm/wasm-code-manager.h" 45 #include "src/wasm/wasm-engine.h" 46 #include "src/wasm/wasm-objects-inl.h" 47 48 namespace v8 { 49 namespace internal { 50 51 #ifdef OBJECT_PRINT 52 53 void Object::Print() { 54 StdoutStream os; 55 this->Print(os); 56 os << std::flush; 57 } 58 59 void Object::Print(std::ostream& os) { // NOLINT 60 if (IsSmi()) { 61 os << "Smi: " << std::hex << "0x" << Smi::ToInt(this); 62 os << std::dec << " (" << Smi::ToInt(this) << ")\n"; 63 } else { 64 HeapObject::cast(this)->HeapObjectPrint(os); 65 } 66 } 67 68 void HeapObject::PrintHeader(std::ostream& os, const char* id) { // NOLINT 69 os << reinterpret_cast<void*>(this) << ": ["; 70 if (id != nullptr) { 71 os << id; 72 } else { 73 os << map()->instance_type(); 74 } 75 os << "]"; 76 MemoryChunk* chunk = MemoryChunk::FromAddress( 77 reinterpret_cast<Address>(const_cast<HeapObject*>(this))); 78 if (chunk->owner()->identity() == OLD_SPACE) os << " in OldSpace"; 79 if (!IsMap()) os << "\n - map: " << Brief(map()); 80 } 81 82 void HeapObject::HeapObjectPrint(std::ostream& os) { // NOLINT 83 InstanceType instance_type = map()->instance_type(); 84 85 if (instance_type < FIRST_NONSTRING_TYPE) { 86 String::cast(this)->StringPrint(os); 87 os << "\n"; 88 return; 89 } 90 91 switch (instance_type) { 92 case SYMBOL_TYPE: 93 Symbol::cast(this)->SymbolPrint(os); 94 break; 95 case MAP_TYPE: 96 Map::cast(this)->MapPrint(os); 97 break; 98 case HEAP_NUMBER_TYPE: 99 HeapNumber::cast(this)->HeapNumberPrint(os); 100 os << "\n"; 101 break; 102 case MUTABLE_HEAP_NUMBER_TYPE: 103 os << "<mutable "; 104 MutableHeapNumber::cast(this)->MutableHeapNumberPrint(os); 105 os << ">\n"; 106 break; 107 case BIGINT_TYPE: 108 BigInt::cast(this)->BigIntPrint(os); 109 os << "\n"; 110 break; 111 case FIXED_DOUBLE_ARRAY_TYPE: 112 FixedDoubleArray::cast(this)->FixedDoubleArrayPrint(os); 113 break; 114 case FIXED_ARRAY_TYPE: 115 case BLOCK_CONTEXT_TYPE: 116 case CATCH_CONTEXT_TYPE: 117 case DEBUG_EVALUATE_CONTEXT_TYPE: 118 case EVAL_CONTEXT_TYPE: 119 case FUNCTION_CONTEXT_TYPE: 120 case MODULE_CONTEXT_TYPE: 121 case NATIVE_CONTEXT_TYPE: 122 case SCRIPT_CONTEXT_TYPE: 123 case WITH_CONTEXT_TYPE: 124 case SCRIPT_CONTEXT_TABLE_TYPE: 125 FixedArray::cast(this)->FixedArrayPrint(os); 126 break; 127 case HASH_TABLE_TYPE: 128 case ORDERED_HASH_MAP_TYPE: 129 case ORDERED_HASH_SET_TYPE: 130 case NAME_DICTIONARY_TYPE: 131 case GLOBAL_DICTIONARY_TYPE: 132 case SIMPLE_NUMBER_DICTIONARY_TYPE: 133 case STRING_TABLE_TYPE: 134 ObjectHashTable::cast(this)->ObjectHashTablePrint(os); 135 break; 136 case NUMBER_DICTIONARY_TYPE: 137 NumberDictionary::cast(this)->NumberDictionaryPrint(os); 138 break; 139 case EPHEMERON_HASH_TABLE_TYPE: 140 EphemeronHashTable::cast(this)->EphemeronHashTablePrint(os); 141 break; 142 case OBJECT_BOILERPLATE_DESCRIPTION_TYPE: 143 ObjectBoilerplateDescription::cast(this) 144 ->ObjectBoilerplateDescriptionPrint(os); 145 break; 146 case PROPERTY_ARRAY_TYPE: 147 PropertyArray::cast(this)->PropertyArrayPrint(os); 148 break; 149 case BYTE_ARRAY_TYPE: 150 ByteArray::cast(this)->ByteArrayPrint(os); 151 break; 152 case BYTECODE_ARRAY_TYPE: 153 BytecodeArray::cast(this)->BytecodeArrayPrint(os); 154 break; 155 case DESCRIPTOR_ARRAY_TYPE: 156 DescriptorArray::cast(this)->DescriptorArrayPrint(os); 157 break; 158 case TRANSITION_ARRAY_TYPE: 159 TransitionArray::cast(this)->TransitionArrayPrint(os); 160 break; 161 case FEEDBACK_CELL_TYPE: 162 FeedbackCell::cast(this)->FeedbackCellPrint(os); 163 break; 164 case FEEDBACK_VECTOR_TYPE: 165 FeedbackVector::cast(this)->FeedbackVectorPrint(os); 166 break; 167 case FREE_SPACE_TYPE: 168 FreeSpace::cast(this)->FreeSpacePrint(os); 169 break; 170 171 #define PRINT_FIXED_TYPED_ARRAY(Type, type, TYPE, ctype) \ 172 case Fixed##Type##Array::kInstanceType: \ 173 Fixed##Type##Array::cast(this)->FixedTypedArrayPrint(os); \ 174 break; 175 176 TYPED_ARRAYS(PRINT_FIXED_TYPED_ARRAY) 177 #undef PRINT_FIXED_TYPED_ARRAY 178 179 case FILLER_TYPE: 180 os << "filler"; 181 break; 182 case JS_OBJECT_TYPE: // fall through 183 case JS_API_OBJECT_TYPE: 184 case JS_SPECIAL_API_OBJECT_TYPE: 185 case JS_CONTEXT_EXTENSION_OBJECT_TYPE: 186 case JS_ASYNC_GENERATOR_OBJECT_TYPE: 187 case JS_ARGUMENTS_TYPE: 188 case JS_ERROR_TYPE: 189 // TODO(titzer): debug printing for more wasm objects 190 case WASM_GLOBAL_TYPE: 191 case WASM_MEMORY_TYPE: 192 case WASM_TABLE_TYPE: 193 JSObject::cast(this)->JSObjectPrint(os); 194 break; 195 case WASM_MODULE_TYPE: 196 WasmModuleObject::cast(this)->WasmModuleObjectPrint(os); 197 break; 198 case WASM_INSTANCE_TYPE: 199 WasmInstanceObject::cast(this)->WasmInstanceObjectPrint(os); 200 break; 201 case JS_GENERATOR_OBJECT_TYPE: 202 JSGeneratorObject::cast(this)->JSGeneratorObjectPrint(os); 203 break; 204 case JS_PROMISE_TYPE: 205 JSPromise::cast(this)->JSPromisePrint(os); 206 break; 207 case JS_ARRAY_TYPE: 208 JSArray::cast(this)->JSArrayPrint(os); 209 break; 210 case JS_REGEXP_TYPE: 211 JSRegExp::cast(this)->JSRegExpPrint(os); 212 break; 213 case JS_REGEXP_STRING_ITERATOR_TYPE: 214 JSRegExpStringIterator::cast(this)->JSRegExpStringIteratorPrint(os); 215 break; 216 case ODDBALL_TYPE: 217 Oddball::cast(this)->to_string()->Print(os); 218 break; 219 case JS_BOUND_FUNCTION_TYPE: 220 JSBoundFunction::cast(this)->JSBoundFunctionPrint(os); 221 break; 222 case JS_FUNCTION_TYPE: 223 JSFunction::cast(this)->JSFunctionPrint(os); 224 break; 225 case JS_GLOBAL_PROXY_TYPE: 226 JSGlobalProxy::cast(this)->JSGlobalProxyPrint(os); 227 break; 228 case JS_GLOBAL_OBJECT_TYPE: 229 JSGlobalObject::cast(this)->JSGlobalObjectPrint(os); 230 break; 231 case JS_VALUE_TYPE: 232 JSValue::cast(this)->JSValuePrint(os); 233 break; 234 case JS_DATE_TYPE: 235 JSDate::cast(this)->JSDatePrint(os); 236 break; 237 case CODE_TYPE: 238 Code::cast(this)->CodePrint(os); 239 break; 240 case CODE_DATA_CONTAINER_TYPE: 241 CodeDataContainer::cast(this)->CodeDataContainerPrint(os); 242 break; 243 case JS_PROXY_TYPE: 244 JSProxy::cast(this)->JSProxyPrint(os); 245 break; 246 case JS_SET_TYPE: 247 JSSet::cast(this)->JSSetPrint(os); 248 break; 249 case JS_MAP_TYPE: 250 JSMap::cast(this)->JSMapPrint(os); 251 break; 252 case JS_SET_KEY_VALUE_ITERATOR_TYPE: 253 case JS_SET_VALUE_ITERATOR_TYPE: 254 JSSetIterator::cast(this)->JSSetIteratorPrint(os); 255 break; 256 case JS_MAP_KEY_ITERATOR_TYPE: 257 case JS_MAP_KEY_VALUE_ITERATOR_TYPE: 258 case JS_MAP_VALUE_ITERATOR_TYPE: 259 JSMapIterator::cast(this)->JSMapIteratorPrint(os); 260 break; 261 case JS_WEAK_MAP_TYPE: 262 JSWeakMap::cast(this)->JSWeakMapPrint(os); 263 break; 264 case JS_WEAK_SET_TYPE: 265 JSWeakSet::cast(this)->JSWeakSetPrint(os); 266 break; 267 case JS_MODULE_NAMESPACE_TYPE: 268 JSModuleNamespace::cast(this)->JSModuleNamespacePrint(os); 269 break; 270 case FOREIGN_TYPE: 271 Foreign::cast(this)->ForeignPrint(os); 272 break; 273 case CALL_HANDLER_INFO_TYPE: 274 CallHandlerInfo::cast(this)->CallHandlerInfoPrint(os); 275 break; 276 case PRE_PARSED_SCOPE_DATA_TYPE: 277 PreParsedScopeData::cast(this)->PreParsedScopeDataPrint(os); 278 break; 279 case UNCOMPILED_DATA_WITHOUT_PRE_PARSED_SCOPE_TYPE: 280 UncompiledDataWithoutPreParsedScope::cast(this) 281 ->UncompiledDataWithoutPreParsedScopePrint(os); 282 break; 283 case UNCOMPILED_DATA_WITH_PRE_PARSED_SCOPE_TYPE: 284 UncompiledDataWithPreParsedScope::cast(this) 285 ->UncompiledDataWithPreParsedScopePrint(os); 286 break; 287 case SHARED_FUNCTION_INFO_TYPE: 288 SharedFunctionInfo::cast(this)->SharedFunctionInfoPrint(os); 289 break; 290 case JS_MESSAGE_OBJECT_TYPE: 291 JSMessageObject::cast(this)->JSMessageObjectPrint(os); 292 break; 293 case CELL_TYPE: 294 Cell::cast(this)->CellPrint(os); 295 break; 296 case PROPERTY_CELL_TYPE: 297 PropertyCell::cast(this)->PropertyCellPrint(os); 298 break; 299 case JS_ARRAY_BUFFER_TYPE: 300 JSArrayBuffer::cast(this)->JSArrayBufferPrint(os); 301 break; 302 case JS_ARRAY_ITERATOR_TYPE: 303 JSArrayIterator::cast(this)->JSArrayIteratorPrint(os); 304 break; 305 case JS_TYPED_ARRAY_TYPE: 306 JSTypedArray::cast(this)->JSTypedArrayPrint(os); 307 break; 308 case JS_DATA_VIEW_TYPE: 309 JSDataView::cast(this)->JSDataViewPrint(os); 310 break; 311 #ifdef V8_INTL_SUPPORT 312 case JS_INTL_COLLATOR_TYPE: 313 JSCollator::cast(this)->JSCollatorPrint(os); 314 break; 315 case JS_INTL_LIST_FORMAT_TYPE: 316 JSListFormat::cast(this)->JSListFormatPrint(os); 317 break; 318 case JS_INTL_LOCALE_TYPE: 319 JSLocale::cast(this)->JSLocalePrint(os); 320 break; 321 case JS_INTL_PLURAL_RULES_TYPE: 322 JSPluralRules::cast(this)->JSPluralRulesPrint(os); 323 break; 324 case JS_INTL_RELATIVE_TIME_FORMAT_TYPE: 325 JSRelativeTimeFormat::cast(this)->JSRelativeTimeFormatPrint(os); 326 break; 327 #endif // V8_INTL_SUPPORT 328 #define MAKE_STRUCT_CASE(NAME, Name, name) \ 329 case NAME##_TYPE: \ 330 Name::cast(this)->Name##Print(os); \ 331 break; 332 STRUCT_LIST(MAKE_STRUCT_CASE) 333 #undef MAKE_STRUCT_CASE 334 335 case ALLOCATION_SITE_TYPE: 336 AllocationSite::cast(this)->AllocationSitePrint(os); 337 break; 338 case LOAD_HANDLER_TYPE: 339 LoadHandler::cast(this)->LoadHandlerPrint(os); 340 break; 341 case STORE_HANDLER_TYPE: 342 StoreHandler::cast(this)->StoreHandlerPrint(os); 343 break; 344 case SCOPE_INFO_TYPE: 345 ScopeInfo::cast(this)->ScopeInfoPrint(os); 346 break; 347 case FEEDBACK_METADATA_TYPE: 348 FeedbackMetadata::cast(this)->FeedbackMetadataPrint(os); 349 break; 350 case WEAK_FIXED_ARRAY_TYPE: 351 WeakFixedArray::cast(this)->WeakFixedArrayPrint(os); 352 break; 353 case WEAK_ARRAY_LIST_TYPE: 354 WeakArrayList::cast(this)->WeakArrayListPrint(os); 355 break; 356 case INTERNALIZED_STRING_TYPE: 357 case EXTERNAL_INTERNALIZED_STRING_TYPE: 358 case ONE_BYTE_INTERNALIZED_STRING_TYPE: 359 case EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE: 360 case EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE: 361 case SHORT_EXTERNAL_INTERNALIZED_STRING_TYPE: 362 case SHORT_EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE: 363 case SHORT_EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE: 364 case STRING_TYPE: 365 case CONS_STRING_TYPE: 366 case EXTERNAL_STRING_TYPE: 367 case SLICED_STRING_TYPE: 368 case THIN_STRING_TYPE: 369 case ONE_BYTE_STRING_TYPE: 370 case CONS_ONE_BYTE_STRING_TYPE: 371 case EXTERNAL_ONE_BYTE_STRING_TYPE: 372 case SLICED_ONE_BYTE_STRING_TYPE: 373 case THIN_ONE_BYTE_STRING_TYPE: 374 case EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE: 375 case SHORT_EXTERNAL_STRING_TYPE: 376 case SHORT_EXTERNAL_ONE_BYTE_STRING_TYPE: 377 case SHORT_EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE: 378 case SMALL_ORDERED_HASH_MAP_TYPE: 379 case SMALL_ORDERED_HASH_SET_TYPE: 380 case JS_ASYNC_FROM_SYNC_ITERATOR_TYPE: 381 case JS_STRING_ITERATOR_TYPE: 382 // TODO(all): Handle these types too. 383 os << "UNKNOWN TYPE " << map()->instance_type(); 384 UNREACHABLE(); 385 break; 386 } 387 } 388 389 void ByteArray::ByteArrayPrint(std::ostream& os) { // NOLINT 390 os << "byte array, data starts at " << GetDataStartAddress(); 391 } 392 393 void BytecodeArray::BytecodeArrayPrint(std::ostream& os) { // NOLINT 394 HeapObject::PrintHeader(os, "BytecodeArray"); 395 Disassemble(os); 396 } 397 398 399 void FreeSpace::FreeSpacePrint(std::ostream& os) { // NOLINT 400 os << "free space, size " << Size(); 401 } 402 403 404 template <class Traits> 405 void FixedTypedArray<Traits>::FixedTypedArrayPrint( 406 std::ostream& os) { // NOLINT 407 os << "fixed " << Traits::Designator(); 408 } 409 410 bool JSObject::PrintProperties(std::ostream& os) { // NOLINT 411 if (HasFastProperties()) { 412 DescriptorArray* descs = map()->instance_descriptors(); 413 int nof_inobject_properties = map()->GetInObjectProperties(); 414 int i = 0; 415 for (; i < map()->NumberOfOwnDescriptors(); i++) { 416 os << "\n "; 417 descs->GetKey(i)->NamePrint(os); 418 os << ": "; 419 PropertyDetails details = descs->GetDetails(i); 420 switch (details.location()) { 421 case kField: { 422 FieldIndex field_index = FieldIndex::ForDescriptor(map(), i); 423 if (IsUnboxedDoubleField(field_index)) { 424 os << "<unboxed double> " << RawFastDoublePropertyAt(field_index); 425 } else { 426 os << Brief(RawFastPropertyAt(field_index)); 427 } 428 break; 429 } 430 case kDescriptor: 431 os << Brief(descs->GetStrongValue(i)); 432 break; 433 } 434 os << " "; 435 details.PrintAsFastTo(os, PropertyDetails::kForProperties); 436 if (details.location() != kField) continue; 437 int field_index = details.field_index(); 438 if (nof_inobject_properties <= field_index) { 439 field_index -= nof_inobject_properties; 440 os << " properties[" << field_index << "]"; 441 } 442 } 443 return i > 0; 444 } else if (IsJSGlobalObject()) { 445 JSGlobalObject::cast(this)->global_dictionary()->Print(os); 446 } else { 447 property_dictionary()->Print(os); 448 } 449 return true; 450 } 451 452 namespace { 453 454 template <class T> 455 bool IsTheHoleAt(T* array, int index) { 456 return false; 457 } 458 459 template <> 460 bool IsTheHoleAt(FixedDoubleArray* array, int index) { 461 return array->is_the_hole(index); 462 } 463 464 template <class T> 465 double GetScalarElement(T* array, int index) { 466 if (IsTheHoleAt(array, index)) { 467 return std::numeric_limits<double>::quiet_NaN(); 468 } 469 return array->get_scalar(index); 470 } 471 472 template <class T> 473 void DoPrintElements(std::ostream& os, Object* object) { // NOLINT 474 const bool print_the_hole = std::is_same<T, FixedDoubleArray>::value; 475 T* array = T::cast(object); 476 if (array->length() == 0) return; 477 int previous_index = 0; 478 double previous_value = GetScalarElement(array, 0); 479 double value = 0.0; 480 int i; 481 for (i = 1; i <= array->length(); i++) { 482 if (i < array->length()) value = GetScalarElement(array, i); 483 bool values_are_nan = std::isnan(previous_value) && std::isnan(value); 484 if (i != array->length() && (previous_value == value || values_are_nan) && 485 IsTheHoleAt(array, i - 1) == IsTheHoleAt(array, i)) { 486 continue; 487 } 488 os << "\n"; 489 std::stringstream ss; 490 ss << previous_index; 491 if (previous_index != i - 1) { 492 ss << '-' << (i - 1); 493 } 494 os << std::setw(12) << ss.str() << ": "; 495 if (print_the_hole && IsTheHoleAt(array, i - 1)) { 496 os << "<the_hole>"; 497 } else { 498 os << previous_value; 499 } 500 previous_index = i; 501 previous_value = value; 502 } 503 } 504 505 template <typename T> 506 void PrintFixedArrayElements(std::ostream& os, T* array) { 507 // Print in array notation for non-sparse arrays. 508 Object* previous_value = array->length() > 0 ? array->get(0) : nullptr; 509 Object* value = nullptr; 510 int previous_index = 0; 511 int i; 512 for (i = 1; i <= array->length(); i++) { 513 if (i < array->length()) value = array->get(i); 514 if (previous_value == value && i != array->length()) { 515 continue; 516 } 517 os << "\n"; 518 std::stringstream ss; 519 ss << previous_index; 520 if (previous_index != i - 1) { 521 ss << '-' << (i - 1); 522 } 523 os << std::setw(12) << ss.str() << ": " << Brief(previous_value); 524 previous_index = i; 525 previous_value = value; 526 } 527 } 528 529 void PrintDictionaryElements(std::ostream& os, FixedArrayBase* elements) { 530 // Print some internal fields 531 NumberDictionary* dict = NumberDictionary::cast(elements); 532 if (dict->requires_slow_elements()) { 533 os << "\n - requires_slow_elements"; 534 } else { 535 os << "\n - max_number_key: " << dict->max_number_key(); 536 } 537 dict->Print(os); 538 } 539 540 void PrintSloppyArgumentElements(std::ostream& os, ElementsKind kind, 541 SloppyArgumentsElements* elements) { 542 FixedArray* arguments_store = elements->arguments(); 543 os << "\n 0: context: " << Brief(elements->context()) 544 << "\n 1: arguments_store: " << Brief(arguments_store) 545 << "\n parameter to context slot map:"; 546 for (uint32_t i = 0; i < elements->parameter_map_length(); i++) { 547 uint32_t raw_index = i + SloppyArgumentsElements::kParameterMapStart; 548 Object* mapped_entry = elements->get_mapped_entry(i); 549 os << "\n " << raw_index << ": param(" << i 550 << "): " << Brief(mapped_entry); 551 if (mapped_entry->IsTheHole()) { 552 os << " in the arguments_store[" << i << "]"; 553 } else { 554 os << " in the context"; 555 } 556 } 557 if (arguments_store->length() == 0) return; 558 os << "\n }" 559 << "\n - arguments_store: " << Brief(arguments_store) << " " 560 << ElementsKindToString(arguments_store->map()->elements_kind()) << " {"; 561 if (kind == FAST_SLOPPY_ARGUMENTS_ELEMENTS) { 562 PrintFixedArrayElements(os, arguments_store); 563 } else { 564 DCHECK_EQ(kind, SLOW_SLOPPY_ARGUMENTS_ELEMENTS); 565 PrintDictionaryElements(os, arguments_store); 566 } 567 } 568 569 } // namespace 570 571 void JSObject::PrintElements(std::ostream& os) { // NOLINT 572 // Don't call GetElementsKind, its validation code can cause the printer to 573 // fail when debugging. 574 os << " - elements: " << Brief(elements()) << " {"; 575 if (elements()->length() == 0) { 576 os << " }\n"; 577 return; 578 } 579 switch (map()->elements_kind()) { 580 case HOLEY_SMI_ELEMENTS: 581 case PACKED_SMI_ELEMENTS: 582 case HOLEY_ELEMENTS: 583 case PACKED_ELEMENTS: 584 case FAST_STRING_WRAPPER_ELEMENTS: { 585 PrintFixedArrayElements(os, FixedArray::cast(elements())); 586 break; 587 } 588 case HOLEY_DOUBLE_ELEMENTS: 589 case PACKED_DOUBLE_ELEMENTS: { 590 DoPrintElements<FixedDoubleArray>(os, elements()); 591 break; 592 } 593 594 #define PRINT_ELEMENTS(Type, type, TYPE, elementType) \ 595 case TYPE##_ELEMENTS: { \ 596 DoPrintElements<Fixed##Type##Array>(os, elements()); \ 597 break; \ 598 } 599 TYPED_ARRAYS(PRINT_ELEMENTS) 600 #undef PRINT_ELEMENTS 601 602 case DICTIONARY_ELEMENTS: 603 case SLOW_STRING_WRAPPER_ELEMENTS: 604 PrintDictionaryElements(os, elements()); 605 break; 606 case FAST_SLOPPY_ARGUMENTS_ELEMENTS: 607 case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: 608 PrintSloppyArgumentElements(os, map()->elements_kind(), 609 SloppyArgumentsElements::cast(elements())); 610 break; 611 case NO_ELEMENTS: 612 break; 613 } 614 os << "\n }\n"; 615 } 616 617 static void JSObjectPrintHeader(std::ostream& os, JSObject* obj, 618 const char* id) { // NOLINT 619 Isolate* isolate = obj->GetIsolate(); 620 obj->PrintHeader(os, id); 621 // Don't call GetElementsKind, its validation code can cause the printer to 622 // fail when debugging. 623 os << " ["; 624 if (obj->HasFastProperties()) { 625 os << "FastProperties"; 626 } else { 627 os << "DictionaryProperties"; 628 } 629 PrototypeIterator iter(isolate, obj); 630 os << "]\n - prototype: " << Brief(iter.GetCurrent()); 631 os << "\n - elements: " << Brief(obj->elements()) << " [" 632 << ElementsKindToString(obj->map()->elements_kind()); 633 if (obj->elements()->IsCowArray()) os << " (COW)"; 634 os << "]"; 635 Object* hash = obj->GetHash(); 636 if (hash->IsSmi()) { 637 os << "\n - hash: " << Brief(hash); 638 } 639 if (obj->GetEmbedderFieldCount() > 0) { 640 os << "\n - embedder fields: " << obj->GetEmbedderFieldCount(); 641 } 642 } 643 644 static void JSObjectPrintBody(std::ostream& os, 645 JSObject* obj, // NOLINT 646 bool print_elements = true) { 647 os << "\n - properties: "; 648 Object* properties_or_hash = obj->raw_properties_or_hash(); 649 if (!properties_or_hash->IsSmi()) { 650 os << Brief(properties_or_hash); 651 } 652 os << " {"; 653 if (obj->PrintProperties(os)) os << "\n "; 654 os << "}\n"; 655 if (print_elements && obj->elements()->length() > 0) { 656 obj->PrintElements(os); 657 } 658 int embedder_fields = obj->GetEmbedderFieldCount(); 659 if (embedder_fields > 0) { 660 os << " - embedder fields = {"; 661 for (int i = 0; i < embedder_fields; i++) { 662 os << "\n " << obj->GetEmbedderField(i); 663 } 664 os << "\n }\n"; 665 } 666 } 667 668 void JSObject::JSObjectPrint(std::ostream& os) { // NOLINT 669 JSObjectPrintHeader(os, this, nullptr); 670 JSObjectPrintBody(os, this); 671 } 672 673 void JSGeneratorObject::JSGeneratorObjectPrint(std::ostream& os) { // NOLINT 674 JSObjectPrintHeader(os, this, "JSGeneratorObject"); 675 os << "\n - function: " << Brief(function()); 676 os << "\n - context: " << Brief(context()); 677 os << "\n - receiver: " << Brief(receiver()); 678 if (is_executing() || is_closed()) { 679 os << "\n - input: " << Brief(input_or_debug_pos()); 680 } else { 681 DCHECK(is_suspended()); 682 os << "\n - debug pos: " << Brief(input_or_debug_pos()); 683 } 684 const char* mode = "(invalid)"; 685 switch (resume_mode()) { 686 case kNext: 687 mode = ".next()"; 688 break; 689 case kReturn: 690 mode = ".return()"; 691 break; 692 case kThrow: 693 mode = ".throw()"; 694 break; 695 } 696 os << "\n - resume mode: " << mode; 697 os << "\n - continuation: " << continuation(); 698 if (is_closed()) os << " (closed)"; 699 if (is_executing()) os << " (executing)"; 700 if (is_suspended()) os << " (suspended)"; 701 if (is_suspended()) { 702 DisallowHeapAllocation no_gc; 703 SharedFunctionInfo* fun_info = function()->shared(); 704 if (fun_info->HasSourceCode()) { 705 Script* script = Script::cast(fun_info->script()); 706 int lin = script->GetLineNumber(source_position()) + 1; 707 int col = script->GetColumnNumber(source_position()) + 1; 708 String* script_name = script->name()->IsString() 709 ? String::cast(script->name()) 710 : GetReadOnlyRoots().empty_string(); 711 os << "\n - source position: " << source_position(); 712 os << " ("; 713 script_name->PrintUC16(os); 714 os << ", lin " << lin; 715 os << ", col " << col; 716 os << ")"; 717 } 718 } 719 os << "\n - register file: " << Brief(parameters_and_registers()); 720 os << "\n"; 721 } 722 723 void JSArray::JSArrayPrint(std::ostream& os) { // NOLINT 724 JSObjectPrintHeader(os, this, "JSArray"); 725 os << "\n - length: " << Brief(this->length()); 726 JSObjectPrintBody(os, this); 727 } 728 729 void JSPromise::JSPromisePrint(std::ostream& os) { // NOLINT 730 JSObjectPrintHeader(os, this, "JSPromise"); 731 os << "\n - status: " << JSPromise::Status(status()); 732 if (status() == Promise::kPending) { 733 os << "\n - reactions: " << Brief(reactions()); 734 } else { 735 os << "\n - result: " << Brief(result()); 736 } 737 os << "\n - has_handler: " << has_handler(); 738 os << "\n "; 739 } 740 741 void JSRegExp::JSRegExpPrint(std::ostream& os) { // NOLINT 742 JSObjectPrintHeader(os, this, "JSRegExp"); 743 os << "\n - data: " << Brief(data()); 744 os << "\n - source: " << Brief(source()); 745 JSObjectPrintBody(os, this); 746 } 747 748 void JSRegExpStringIterator::JSRegExpStringIteratorPrint( 749 std::ostream& os) { // NOLINT 750 JSObjectPrintHeader(os, this, "JSRegExpStringIterator"); 751 os << "\n - regex: " << Brief(iterating_regexp()); 752 os << "\n - string: " << Brief(iterating_string()); 753 os << "\n - done: " << done(); 754 os << "\n - global: " << global(); 755 os << "\n - unicode: " << unicode(); 756 JSObjectPrintBody(os, this); 757 } 758 759 void Symbol::SymbolPrint(std::ostream& os) { // NOLINT 760 HeapObject::PrintHeader(os, "Symbol"); 761 os << "\n - hash: " << Hash(); 762 os << "\n - name: " << Brief(name()); 763 if (name()->IsUndefined()) { 764 os << " (" << PrivateSymbolToName() << ")"; 765 } 766 os << "\n - private: " << is_private(); 767 os << "\n"; 768 } 769 770 void Map::MapPrint(std::ostream& os) { // NOLINT 771 HeapObject::PrintHeader(os, "Map"); 772 os << "\n - type: " << instance_type(); 773 os << "\n - instance size: "; 774 if (instance_size() == kVariableSizeSentinel) { 775 os << "variable"; 776 } else { 777 os << instance_size(); 778 } 779 if (IsJSObjectMap()) { 780 os << "\n - inobject properties: " << GetInObjectProperties(); 781 } 782 os << "\n - elements kind: " << ElementsKindToString(elements_kind()); 783 os << "\n - unused property fields: " << UnusedPropertyFields(); 784 os << "\n - enum length: "; 785 if (EnumLength() == kInvalidEnumCacheSentinel) { 786 os << "invalid"; 787 } else { 788 os << EnumLength(); 789 } 790 if (is_deprecated()) os << "\n - deprecated_map"; 791 if (is_stable()) os << "\n - stable_map"; 792 if (is_migration_target()) os << "\n - migration_target"; 793 if (is_dictionary_map()) os << "\n - dictionary_map"; 794 if (has_hidden_prototype()) os << "\n - has_hidden_prototype"; 795 if (has_named_interceptor()) os << "\n - named_interceptor"; 796 if (has_indexed_interceptor()) os << "\n - indexed_interceptor"; 797 if (may_have_interesting_symbols()) os << "\n - may_have_interesting_symbols"; 798 if (is_undetectable()) os << "\n - undetectable"; 799 if (is_callable()) os << "\n - callable"; 800 if (is_constructor()) os << "\n - constructor"; 801 if (has_prototype_slot()) { 802 os << "\n - has_prototype_slot"; 803 if (has_non_instance_prototype()) os << " (non-instance prototype)"; 804 } 805 if (is_access_check_needed()) os << "\n - access_check_needed"; 806 if (!is_extensible()) os << "\n - non-extensible"; 807 if (is_prototype_map()) { 808 os << "\n - prototype_map"; 809 os << "\n - prototype info: " << Brief(prototype_info()); 810 } else { 811 os << "\n - back pointer: " << Brief(GetBackPointer()); 812 } 813 os << "\n - prototype_validity cell: " << Brief(prototype_validity_cell()); 814 os << "\n - instance descriptors " << (owns_descriptors() ? "(own) " : "") 815 << "#" << NumberOfOwnDescriptors() << ": " 816 << Brief(instance_descriptors()); 817 if (FLAG_unbox_double_fields) { 818 os << "\n - layout descriptor: "; 819 layout_descriptor()->ShortPrint(os); 820 } 821 822 Isolate* isolate; 823 // Read-only maps can't have transitions, which is fortunate because we need 824 // the isolate to iterate over the transitions. 825 if (Isolate::FromWritableHeapObject(this, &isolate)) { 826 DisallowHeapAllocation no_gc; 827 TransitionsAccessor transitions(isolate, this, &no_gc); 828 int nof_transitions = transitions.NumberOfTransitions(); 829 if (nof_transitions > 0) { 830 os << "\n - transitions #" << nof_transitions << ": "; 831 HeapObject* heap_object; 832 Smi* smi; 833 if (raw_transitions()->ToSmi(&smi)) { 834 os << Brief(smi); 835 } else if (raw_transitions()->ToStrongOrWeakHeapObject(&heap_object)) { 836 os << Brief(heap_object); 837 } 838 transitions.PrintTransitions(os); 839 } 840 } 841 os << "\n - prototype: " << Brief(prototype()); 842 os << "\n - constructor: " << Brief(GetConstructor()); 843 os << "\n - dependent code: " << Brief(dependent_code()); 844 os << "\n - construction counter: " << construction_counter(); 845 os << "\n"; 846 } 847 848 void DescriptorArray::DescriptorArrayPrint(std::ostream& os) { 849 HeapObject::PrintHeader(os, "DescriptorArray"); 850 os << "\n - capacity: " << length(); 851 EnumCache* enum_cache = GetEnumCache(); 852 os << "\n - enum_cache: "; 853 if (enum_cache->keys()->length() == 0) { 854 os << "empty"; 855 } else { 856 os << enum_cache->keys()->length(); 857 os << "\n - keys: " << Brief(enum_cache->keys()); 858 os << "\n - indices: " << Brief(enum_cache->indices()); 859 } 860 os << "\n - nof descriptors: " << number_of_descriptors(); 861 PrintDescriptors(os); 862 } 863 864 void AliasedArgumentsEntry::AliasedArgumentsEntryPrint( 865 std::ostream& os) { // NOLINT 866 HeapObject::PrintHeader(os, "AliasedArgumentsEntry"); 867 os << "\n - aliased_context_slot: " << aliased_context_slot(); 868 } 869 870 namespace { 871 void PrintFixedArrayWithHeader(std::ostream& os, FixedArray* array, 872 const char* type) { 873 array->PrintHeader(os, type); 874 os << "\n - length: " << array->length(); 875 PrintFixedArrayElements(os, array); 876 os << "\n"; 877 } 878 879 template <typename T> 880 void PrintHashTableWithHeader(std::ostream& os, T* table, const char* type) { 881 table->PrintHeader(os, type); 882 os << "\n - length: " << table->length(); 883 os << "\n - elements: " << table->NumberOfElements(); 884 os << "\n - deleted: " << table->NumberOfDeletedElements(); 885 os << "\n - capacity: " << table->Capacity(); 886 887 os << "\n - elements: {"; 888 for (int i = 0; i < table->Capacity(); i++) { 889 os << '\n' 890 << std::setw(12) << i << ": " << Brief(table->KeyAt(i)) << " -> " 891 << Brief(table->ValueAt(i)); 892 } 893 os << "\n }\n"; 894 } 895 896 template <typename T> 897 void PrintWeakArrayElements(std::ostream& os, T* array) { 898 // Print in array notation for non-sparse arrays. 899 MaybeObject* previous_value = array->length() > 0 ? array->Get(0) : nullptr; 900 MaybeObject* value = nullptr; 901 int previous_index = 0; 902 int i; 903 for (i = 1; i <= array->length(); i++) { 904 if (i < array->length()) value = array->Get(i); 905 if (previous_value == value && i != array->length()) { 906 continue; 907 } 908 os << "\n"; 909 std::stringstream ss; 910 ss << previous_index; 911 if (previous_index != i - 1) { 912 ss << '-' << (i - 1); 913 } 914 os << std::setw(12) << ss.str() << ": " << Brief(previous_value); 915 previous_index = i; 916 previous_value = value; 917 } 918 } 919 920 } // namespace 921 922 void FixedArray::FixedArrayPrint(std::ostream& os) { // NOLINT 923 PrintFixedArrayWithHeader(os, this, "FixedArray"); 924 } 925 926 void ObjectHashTable::ObjectHashTablePrint(std::ostream& os) { 927 PrintHashTableWithHeader(os, this, "ObjectHashTable"); 928 } 929 930 void NumberDictionary::NumberDictionaryPrint(std::ostream& os) { 931 PrintHashTableWithHeader(os, this, "NumberDictionary"); 932 } 933 934 void EphemeronHashTable::EphemeronHashTablePrint(std::ostream& os) { 935 PrintHashTableWithHeader(os, this, "EphemeronHashTable"); 936 } 937 938 void ObjectBoilerplateDescription::ObjectBoilerplateDescriptionPrint( 939 std::ostream& os) { 940 PrintFixedArrayWithHeader(os, this, "ObjectBoilerplateDescription"); 941 } 942 943 void PropertyArray::PropertyArrayPrint(std::ostream& os) { // NOLINT 944 HeapObject::PrintHeader(os, "PropertyArray"); 945 os << "\n - length: " << length(); 946 os << "\n - hash: " << Hash(); 947 PrintFixedArrayElements(os, this); 948 os << "\n"; 949 } 950 951 void FixedDoubleArray::FixedDoubleArrayPrint(std::ostream& os) { // NOLINT 952 HeapObject::PrintHeader(os, "FixedDoubleArray"); 953 os << "\n - length: " << length(); 954 DoPrintElements<FixedDoubleArray>(os, this); 955 os << "\n"; 956 } 957 958 void WeakFixedArray::WeakFixedArrayPrint(std::ostream& os) { 959 PrintHeader(os, "WeakFixedArray"); 960 os << "\n - length: " << length() << "\n"; 961 PrintWeakArrayElements(os, this); 962 os << "\n"; 963 } 964 965 void WeakArrayList::WeakArrayListPrint(std::ostream& os) { 966 PrintHeader(os, "WeakArrayList"); 967 os << "\n - capacity: " << capacity(); 968 os << "\n - length: " << length() << "\n"; 969 PrintWeakArrayElements(os, this); 970 os << "\n"; 971 } 972 973 void TransitionArray::TransitionArrayPrint(std::ostream& os) { // NOLINT 974 HeapObject::PrintHeader(os, "TransitionArray"); 975 PrintInternal(os); 976 } 977 978 void FeedbackCell::FeedbackCellPrint(std::ostream& os) { // NOLINT 979 HeapObject::PrintHeader(os, "FeedbackCell"); 980 ReadOnlyRoots roots = GetReadOnlyRoots(); 981 if (map() == roots.no_closures_cell_map()) { 982 os << "\n - no closures"; 983 } else if (map() == roots.one_closure_cell_map()) { 984 os << "\n - one closure"; 985 } else if (map() == roots.many_closures_cell_map()) { 986 os << "\n - many closures"; 987 } else { 988 os << "\n - Invalid FeedbackCell map"; 989 } 990 os << " - value: " << Brief(value()); 991 os << "\n"; 992 } 993 994 void FeedbackVectorSpec::Print() { 995 StdoutStream os; 996 997 FeedbackVectorSpecPrint(os); 998 999 os << std::flush; 1000 } 1001 1002 void FeedbackVectorSpec::FeedbackVectorSpecPrint(std::ostream& os) { // NOLINT 1003 int slot_count = slots(); 1004 os << " - slot_count: " << slot_count; 1005 if (slot_count == 0) { 1006 os << " (empty)\n"; 1007 return; 1008 } 1009 1010 for (int slot = 0; slot < slot_count;) { 1011 FeedbackSlotKind kind = GetKind(FeedbackSlot(slot)); 1012 int entry_size = FeedbackMetadata::GetSlotSize(kind); 1013 DCHECK_LT(0, entry_size); 1014 os << "\n Slot #" << slot << " " << kind; 1015 slot += entry_size; 1016 } 1017 os << "\n"; 1018 } 1019 1020 void FeedbackMetadata::FeedbackMetadataPrint(std::ostream& os) { 1021 HeapObject::PrintHeader(os, "FeedbackMetadata"); 1022 os << "\n - slot_count: " << slot_count(); 1023 1024 FeedbackMetadataIterator iter(this); 1025 while (iter.HasNext()) { 1026 FeedbackSlot slot = iter.Next(); 1027 FeedbackSlotKind kind = iter.kind(); 1028 os << "\n Slot " << slot << " " << kind; 1029 } 1030 os << "\n"; 1031 } 1032 1033 void FeedbackVector::FeedbackVectorPrint(std::ostream& os) { // NOLINT 1034 HeapObject::PrintHeader(os, "FeedbackVector"); 1035 os << "\n - length: " << length(); 1036 if (length() == 0) { 1037 os << " (empty)\n"; 1038 return; 1039 } 1040 1041 os << "\n - shared function info: " << Brief(shared_function_info()); 1042 os << "\n - optimized code/marker: "; 1043 if (has_optimized_code()) { 1044 os << Brief(optimized_code()); 1045 } else { 1046 os << optimization_marker(); 1047 } 1048 os << "\n - invocation count: " << invocation_count(); 1049 os << "\n - profiler ticks: " << profiler_ticks(); 1050 1051 FeedbackMetadataIterator iter(metadata()); 1052 while (iter.HasNext()) { 1053 FeedbackSlot slot = iter.Next(); 1054 FeedbackSlotKind kind = iter.kind(); 1055 1056 os << "\n - slot " << slot << " " << kind << " "; 1057 FeedbackSlotPrint(os, slot); 1058 1059 int entry_size = iter.entry_size(); 1060 if (entry_size > 0) os << " {"; 1061 for (int i = 0; i < entry_size; i++) { 1062 int index = GetIndex(slot) + i; 1063 os << "\n [" << index << "]: " << Brief(get(index)); 1064 } 1065 if (entry_size > 0) os << "\n }"; 1066 } 1067 os << "\n"; 1068 } 1069 1070 void FeedbackVector::FeedbackSlotPrint(std::ostream& os, 1071 FeedbackSlot slot) { // NOLINT 1072 FeedbackNexus nexus(this, slot); 1073 nexus.Print(os); 1074 } 1075 1076 namespace { 1077 1078 const char* ICState2String(InlineCacheState state) { 1079 switch (state) { 1080 case UNINITIALIZED: 1081 return "UNINITIALIZED"; 1082 case PREMONOMORPHIC: 1083 return "PREMONOMORPHIC"; 1084 case MONOMORPHIC: 1085 return "MONOMORPHIC"; 1086 case RECOMPUTE_HANDLER: 1087 return "RECOMPUTE_HANDLER"; 1088 case POLYMORPHIC: 1089 return "POLYMORPHIC"; 1090 case MEGAMORPHIC: 1091 return "MEGAMORPHIC"; 1092 case GENERIC: 1093 return "GENERIC"; 1094 } 1095 UNREACHABLE(); 1096 } 1097 } // anonymous namespace 1098 1099 void FeedbackNexus::Print(std::ostream& os) { // NOLINT 1100 switch (kind()) { 1101 case FeedbackSlotKind::kCall: 1102 case FeedbackSlotKind::kLoadProperty: 1103 case FeedbackSlotKind::kLoadKeyed: 1104 case FeedbackSlotKind::kLoadGlobalInsideTypeof: 1105 case FeedbackSlotKind::kLoadGlobalNotInsideTypeof: 1106 case FeedbackSlotKind::kStoreNamedSloppy: 1107 case FeedbackSlotKind::kStoreNamedStrict: 1108 case FeedbackSlotKind::kStoreOwnNamed: 1109 case FeedbackSlotKind::kStoreGlobalSloppy: 1110 case FeedbackSlotKind::kStoreGlobalStrict: 1111 case FeedbackSlotKind::kStoreKeyedSloppy: 1112 case FeedbackSlotKind::kInstanceOf: 1113 case FeedbackSlotKind::kStoreDataPropertyInLiteral: 1114 case FeedbackSlotKind::kStoreKeyedStrict: 1115 case FeedbackSlotKind::kStoreInArrayLiteral: 1116 case FeedbackSlotKind::kCloneObject: { 1117 os << ICState2String(StateFromFeedback()); 1118 break; 1119 } 1120 case FeedbackSlotKind::kBinaryOp: { 1121 os << "BinaryOp:" << GetBinaryOperationFeedback(); 1122 break; 1123 } 1124 case FeedbackSlotKind::kCompareOp: { 1125 os << "CompareOp:" << GetCompareOperationFeedback(); 1126 break; 1127 } 1128 case FeedbackSlotKind::kForIn: { 1129 os << "ForIn:" << GetForInFeedback(); 1130 break; 1131 } 1132 case FeedbackSlotKind::kCreateClosure: 1133 case FeedbackSlotKind::kLiteral: 1134 case FeedbackSlotKind::kTypeProfile: 1135 break; 1136 case FeedbackSlotKind::kInvalid: 1137 case FeedbackSlotKind::kKindsNumber: 1138 UNREACHABLE(); 1139 break; 1140 } 1141 } 1142 1143 void JSValue::JSValuePrint(std::ostream& os) { // NOLINT 1144 JSObjectPrintHeader(os, this, "JSValue"); 1145 os << "\n - value: " << Brief(value()); 1146 JSObjectPrintBody(os, this); 1147 } 1148 1149 void JSMessageObject::JSMessageObjectPrint(std::ostream& os) { // NOLINT 1150 JSObjectPrintHeader(os, this, "JSMessageObject"); 1151 os << "\n - type: " << type(); 1152 os << "\n - arguments: " << Brief(argument()); 1153 os << "\n - start_position: " << start_position(); 1154 os << "\n - end_position: " << end_position(); 1155 os << "\n - script: " << Brief(script()); 1156 os << "\n - stack_frames: " << Brief(stack_frames()); 1157 JSObjectPrintBody(os, this); 1158 } 1159 1160 1161 void String::StringPrint(std::ostream& os) { // NOLINT 1162 if (!HasOnlyOneByteChars()) { 1163 os << "u"; 1164 } 1165 if (StringShape(this).IsInternalized()) { 1166 os << "#"; 1167 } else if (StringShape(this).IsCons()) { 1168 os << "c\""; 1169 } else if (StringShape(this).IsThin()) { 1170 os << ">\""; 1171 } else { 1172 os << "\""; 1173 } 1174 1175 const char truncated_epilogue[] = "...<truncated>"; 1176 int len = length(); 1177 if (!FLAG_use_verbose_printer) { 1178 if (len > 100) { 1179 len = 100 - sizeof(truncated_epilogue); 1180 } 1181 } 1182 for (int i = 0; i < len; i++) { 1183 os << AsUC16(Get(i)); 1184 } 1185 if (len != length()) { 1186 os << truncated_epilogue; 1187 } 1188 1189 if (!StringShape(this).IsInternalized()) os << "\""; 1190 } 1191 1192 1193 void Name::NamePrint(std::ostream& os) { // NOLINT 1194 if (IsString()) { 1195 String::cast(this)->StringPrint(os); 1196 } else { 1197 os << Brief(this); 1198 } 1199 } 1200 1201 1202 static const char* const weekdays[] = { 1203 "???", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" 1204 }; 1205 1206 void JSDate::JSDatePrint(std::ostream& os) { // NOLINT 1207 JSObjectPrintHeader(os, this, "JSDate"); 1208 os << "\n - value: " << Brief(value()); 1209 if (!year()->IsSmi()) { 1210 os << "\n - time = NaN\n"; 1211 } else { 1212 // TODO(svenpanne) Add some basic formatting to our streams. 1213 ScopedVector<char> buf(100); 1214 SNPrintF(buf, "\n - time = %s %04d/%02d/%02d %02d:%02d:%02d\n", 1215 weekdays[weekday()->IsSmi() ? Smi::ToInt(weekday()) + 1 : 0], 1216 year()->IsSmi() ? Smi::ToInt(year()) : -1, 1217 month()->IsSmi() ? Smi::ToInt(month()) : -1, 1218 day()->IsSmi() ? Smi::ToInt(day()) : -1, 1219 hour()->IsSmi() ? Smi::ToInt(hour()) : -1, 1220 min()->IsSmi() ? Smi::ToInt(min()) : -1, 1221 sec()->IsSmi() ? Smi::ToInt(sec()) : -1); 1222 os << buf.start(); 1223 } 1224 JSObjectPrintBody(os, this); 1225 } 1226 1227 1228 void JSProxy::JSProxyPrint(std::ostream& os) { // NOLINT 1229 HeapObject::PrintHeader(os, "JSProxy"); 1230 os << "\n - target: "; 1231 target()->ShortPrint(os); 1232 os << "\n - handler: "; 1233 handler()->ShortPrint(os); 1234 os << "\n"; 1235 } 1236 1237 void JSSet::JSSetPrint(std::ostream& os) { // NOLINT 1238 JSObjectPrintHeader(os, this, "JSSet"); 1239 os << " - table: " << Brief(table()); 1240 JSObjectPrintBody(os, this); 1241 } 1242 1243 void JSMap::JSMapPrint(std::ostream& os) { // NOLINT 1244 JSObjectPrintHeader(os, this, "JSMap"); 1245 os << " - table: " << Brief(table()); 1246 JSObjectPrintBody(os, this); 1247 } 1248 1249 void JSCollectionIterator::JSCollectionIteratorPrint( 1250 std::ostream& os) { // NOLINT 1251 os << "\n - table: " << Brief(table()); 1252 os << "\n - index: " << Brief(index()); 1253 os << "\n"; 1254 } 1255 1256 void JSSetIterator::JSSetIteratorPrint(std::ostream& os) { // NOLINT 1257 JSObjectPrintHeader(os, this, "JSSetIterator"); 1258 JSCollectionIteratorPrint(os); 1259 } 1260 1261 void JSMapIterator::JSMapIteratorPrint(std::ostream& os) { // NOLINT 1262 JSObjectPrintHeader(os, this, "JSMapIterator"); 1263 JSCollectionIteratorPrint(os); 1264 } 1265 1266 void JSWeakMap::JSWeakMapPrint(std::ostream& os) { // NOLINT 1267 JSObjectPrintHeader(os, this, "JSWeakMap"); 1268 os << "\n - table: " << Brief(table()); 1269 JSObjectPrintBody(os, this); 1270 } 1271 1272 void JSWeakSet::JSWeakSetPrint(std::ostream& os) { // NOLINT 1273 JSObjectPrintHeader(os, this, "JSWeakSet"); 1274 os << "\n - table: " << Brief(table()); 1275 JSObjectPrintBody(os, this); 1276 } 1277 1278 void JSArrayBuffer::JSArrayBufferPrint(std::ostream& os) { // NOLINT 1279 JSObjectPrintHeader(os, this, "JSArrayBuffer"); 1280 os << "\n - backing_store: " << backing_store(); 1281 os << "\n - byte_length: " << Brief(byte_length()); 1282 if (is_external()) os << "\n - external"; 1283 if (is_neuterable()) os << "\n - neuterable"; 1284 if (was_neutered()) os << "\n - neutered"; 1285 if (is_shared()) os << "\n - shared"; 1286 if (is_wasm_memory()) os << "\n - is_wasm_memory"; 1287 if (is_growable()) os << "\n - growable"; 1288 JSObjectPrintBody(os, this, !was_neutered()); 1289 } 1290 1291 void JSTypedArray::JSTypedArrayPrint(std::ostream& os) { // NOLINT 1292 JSObjectPrintHeader(os, this, "JSTypedArray"); 1293 os << "\n - buffer: " << Brief(buffer()); 1294 os << "\n - byte_offset: " << Brief(byte_offset()); 1295 os << "\n - byte_length: " << Brief(byte_length()); 1296 os << "\n - length: " << Brief(length()); 1297 if (WasNeutered()) os << "\n - neutered"; 1298 JSObjectPrintBody(os, this, !WasNeutered()); 1299 } 1300 1301 void JSArrayIterator::JSArrayIteratorPrint(std::ostream& os) { // NOLING 1302 JSObjectPrintHeader(os, this, "JSArrayIterator"); 1303 os << "\n - iterated_object: " << Brief(iterated_object()); 1304 os << "\n - next_index: " << Brief(next_index()); 1305 os << "\n - kind: " << kind(); 1306 JSObjectPrintBody(os, this); 1307 } 1308 1309 void JSDataView::JSDataViewPrint(std::ostream& os) { // NOLINT 1310 JSObjectPrintHeader(os, this, "JSDataView"); 1311 os << "\n - buffer =" << Brief(buffer()); 1312 os << "\n - byte_offset: " << Brief(byte_offset()); 1313 os << "\n - byte_length: " << Brief(byte_length()); 1314 if (WasNeutered()) os << "\n - neutered"; 1315 JSObjectPrintBody(os, this, !WasNeutered()); 1316 } 1317 1318 void JSBoundFunction::JSBoundFunctionPrint(std::ostream& os) { // NOLINT 1319 JSObjectPrintHeader(os, this, "JSBoundFunction"); 1320 os << "\n - bound_target_function: " << Brief(bound_target_function()); 1321 os << "\n - bound_this: " << Brief(bound_this()); 1322 os << "\n - bound_arguments: " << Brief(bound_arguments()); 1323 JSObjectPrintBody(os, this); 1324 } 1325 1326 void JSFunction::JSFunctionPrint(std::ostream& os) { // NOLINT 1327 Isolate* isolate = GetIsolate(); 1328 JSObjectPrintHeader(os, this, "Function"); 1329 os << "\n - function prototype: "; 1330 if (has_prototype_slot()) { 1331 if (has_prototype()) { 1332 os << Brief(prototype()); 1333 if (map()->has_non_instance_prototype()) { 1334 os << " (non-instance prototype)"; 1335 } 1336 } 1337 os << "\n - initial_map: "; 1338 if (has_initial_map()) os << Brief(initial_map()); 1339 } else { 1340 os << "<no-prototype-slot>"; 1341 } 1342 os << "\n - shared_info: " << Brief(shared()); 1343 os << "\n - name: " << Brief(shared()->Name()); 1344 1345 // Print Builtin name for builtin functions 1346 int builtin_index = code()->builtin_index(); 1347 if (builtin_index != -1 && !IsInterpreted()) { 1348 if (builtin_index == Builtins::kDeserializeLazy) { 1349 if (shared()->HasBuiltinId()) { 1350 builtin_index = shared()->builtin_id(); 1351 os << "\n - builtin: " << isolate->builtins()->name(builtin_index) 1352 << "(lazy)"; 1353 } 1354 } else { 1355 os << "\n - builtin: " << isolate->builtins()->name(builtin_index); 1356 } 1357 } 1358 1359 os << "\n - formal_parameter_count: " 1360 << shared()->internal_formal_parameter_count(); 1361 os << "\n - kind: " << shared()->kind(); 1362 os << "\n - context: " << Brief(context()); 1363 os << "\n - code: " << Brief(code()); 1364 if (IsInterpreted()) { 1365 os << "\n - interpreted"; 1366 if (shared()->HasBytecodeArray()) { 1367 os << "\n - bytecode: " << shared()->GetBytecodeArray(); 1368 } 1369 } 1370 if (WasmExportedFunction::IsWasmExportedFunction(this)) { 1371 WasmExportedFunction* function = WasmExportedFunction::cast(this); 1372 os << "\n - WASM instance " 1373 << reinterpret_cast<void*>(function->instance()); 1374 os << "\n - WASM function index " << function->function_index(); 1375 } 1376 shared()->PrintSourceCode(os); 1377 JSObjectPrintBody(os, this); 1378 os << "\n - feedback vector: "; 1379 if (!shared()->HasFeedbackMetadata()) { 1380 os << "feedback metadata is not available in SFI\n"; 1381 } else if (has_feedback_vector()) { 1382 feedback_vector()->FeedbackVectorPrint(os); 1383 } else { 1384 os << "not available\n"; 1385 } 1386 } 1387 1388 void SharedFunctionInfo::PrintSourceCode(std::ostream& os) { 1389 if (HasSourceCode()) { 1390 os << "\n - source code: "; 1391 String* source = String::cast(Script::cast(script())->source()); 1392 int start = StartPosition(); 1393 int length = EndPosition() - start; 1394 std::unique_ptr<char[]> source_string = source->ToCString( 1395 DISALLOW_NULLS, FAST_STRING_TRAVERSAL, start, length, nullptr); 1396 os << source_string.get(); 1397 } 1398 } 1399 1400 void SharedFunctionInfo::SharedFunctionInfoPrint(std::ostream& os) { // NOLINT 1401 HeapObject::PrintHeader(os, "SharedFunctionInfo"); 1402 os << "\n - name: "; 1403 if (HasSharedName()) { 1404 os << Brief(Name()); 1405 } else { 1406 os << "<no-shared-name>"; 1407 } 1408 if (HasInferredName()) { 1409 os << "\n - inferred name: " << Brief(inferred_name()); 1410 } 1411 os << "\n - kind: " << kind(); 1412 if (needs_home_object()) { 1413 os << "\n - needs_home_object"; 1414 } 1415 os << "\n - function_map_index: " << function_map_index(); 1416 os << "\n - formal_parameter_count: " << internal_formal_parameter_count(); 1417 os << "\n - expected_nof_properties: " << expected_nof_properties(); 1418 os << "\n - language_mode: " << language_mode(); 1419 os << "\n - data: " << Brief(function_data()); 1420 os << "\n - code (from data): " << Brief(GetCode()); 1421 PrintSourceCode(os); 1422 // Script files are often large, hard to read. 1423 // os << "\n - script ="; 1424 // script()->Print(os); 1425 if (is_named_expression()) { 1426 os << "\n - named expression"; 1427 } else if (is_anonymous_expression()) { 1428 os << "\n - anonymous expression"; 1429 } else if (is_declaration()) { 1430 os << "\n - declaration"; 1431 } 1432 os << "\n - function token position: " << function_token_position(); 1433 os << "\n - start position: " << StartPosition(); 1434 os << "\n - end position: " << EndPosition(); 1435 if (HasDebugInfo()) { 1436 os << "\n - debug info: " << Brief(GetDebugInfo()); 1437 } else { 1438 os << "\n - no debug info"; 1439 } 1440 os << "\n - scope info: " << Brief(scope_info()); 1441 if (HasOuterScopeInfo()) { 1442 os << "\n - outer scope info: " << Brief(GetOuterScopeInfo()); 1443 } 1444 os << "\n - length: " << length(); 1445 os << "\n - feedback_metadata: "; 1446 if (HasFeedbackMetadata()) { 1447 feedback_metadata()->FeedbackMetadataPrint(os); 1448 } else { 1449 os << "<none>"; 1450 } 1451 os << "\n"; 1452 } 1453 1454 void JSGlobalProxy::JSGlobalProxyPrint(std::ostream& os) { // NOLINT 1455 JSObjectPrintHeader(os, this, "JSGlobalProxy"); 1456 if (!GetIsolate()->bootstrapper()->IsActive()) { 1457 os << "\n - native context: " << Brief(native_context()); 1458 } 1459 JSObjectPrintBody(os, this); 1460 } 1461 1462 void JSGlobalObject::JSGlobalObjectPrint(std::ostream& os) { // NOLINT 1463 JSObjectPrintHeader(os, this, "JSGlobalObject"); 1464 if (!GetIsolate()->bootstrapper()->IsActive()) { 1465 os << "\n - native context: " << Brief(native_context()); 1466 } 1467 os << "\n - global proxy: " << Brief(global_proxy()); 1468 JSObjectPrintBody(os, this); 1469 } 1470 1471 void Cell::CellPrint(std::ostream& os) { // NOLINT 1472 HeapObject::PrintHeader(os, "Cell"); 1473 os << "\n - value: " << Brief(value()); 1474 os << "\n"; 1475 } 1476 1477 void PropertyCell::PropertyCellPrint(std::ostream& os) { // NOLINT 1478 HeapObject::PrintHeader(os, "PropertyCell"); 1479 os << "\n - name: "; 1480 name()->NamePrint(os); 1481 os << "\n - value: " << Brief(value()); 1482 os << "\n - details: "; 1483 property_details().PrintAsSlowTo(os); 1484 PropertyCellType cell_type = property_details().cell_type(); 1485 os << "\n - cell_type: "; 1486 if (value()->IsTheHole()) { 1487 switch (cell_type) { 1488 case PropertyCellType::kUninitialized: 1489 os << "Uninitialized"; 1490 break; 1491 case PropertyCellType::kInvalidated: 1492 os << "Invalidated"; 1493 break; 1494 default: 1495 os << "??? " << static_cast<int>(cell_type); 1496 break; 1497 } 1498 } else { 1499 switch (cell_type) { 1500 case PropertyCellType::kUndefined: 1501 os << "Undefined"; 1502 break; 1503 case PropertyCellType::kConstant: 1504 os << "Constant"; 1505 break; 1506 case PropertyCellType::kConstantType: 1507 os << "ConstantType" 1508 << " ("; 1509 switch (GetConstantType()) { 1510 case PropertyCellConstantType::kSmi: 1511 os << "Smi"; 1512 break; 1513 case PropertyCellConstantType::kStableMap: 1514 os << "StableMap"; 1515 break; 1516 } 1517 os << ")"; 1518 break; 1519 case PropertyCellType::kMutable: 1520 os << "Mutable"; 1521 break; 1522 } 1523 } 1524 os << "\n"; 1525 } 1526 1527 void Code::CodePrint(std::ostream& os) { // NOLINT 1528 HeapObject::PrintHeader(os, "Code"); 1529 os << "\n"; 1530 #ifdef ENABLE_DISASSEMBLER 1531 if (FLAG_use_verbose_printer) { 1532 Disassemble(nullptr, os); 1533 } 1534 #endif 1535 } 1536 1537 void CodeDataContainer::CodeDataContainerPrint(std::ostream& os) { // NOLINT 1538 HeapObject::PrintHeader(os, "CodeDataContainer"); 1539 os << "\n - kind_specific_flags: " << kind_specific_flags(); 1540 os << "\n"; 1541 } 1542 1543 void Foreign::ForeignPrint(std::ostream& os) { // NOLINT 1544 os << "foreign address : " << reinterpret_cast<void*>(foreign_address()); 1545 os << "\n"; 1546 } 1547 1548 1549 void AccessorInfo::AccessorInfoPrint(std::ostream& os) { // NOLINT 1550 HeapObject::PrintHeader(os, "AccessorInfo"); 1551 os << "\n - name: " << Brief(name()); 1552 os << "\n - flags: " << flags(); 1553 os << "\n - getter: " << Brief(getter()); 1554 os << "\n - setter: " << Brief(setter()); 1555 os << "\n - js_getter: " << Brief(js_getter()); 1556 os << "\n - data: " << Brief(data()); 1557 os << "\n"; 1558 } 1559 1560 void CallbackTask::CallbackTaskPrint(std::ostream& os) { // NOLINT 1561 HeapObject::PrintHeader(os, "CallbackTask"); 1562 os << "\n - callback: " << Brief(callback()); 1563 os << "\n - data: " << Brief(data()); 1564 os << "\n"; 1565 } 1566 1567 void CallableTask::CallableTaskPrint(std::ostream& os) { // NOLINT 1568 HeapObject::PrintHeader(os, "CallableTask"); 1569 os << "\n - context: " << Brief(context()); 1570 os << "\n - callable: " << Brief(callable()); 1571 os << "\n"; 1572 } 1573 1574 void PromiseFulfillReactionJobTask::PromiseFulfillReactionJobTaskPrint( 1575 std::ostream& os) { // NOLINT 1576 HeapObject::PrintHeader(os, "PromiseFulfillReactionJobTask"); 1577 os << "\n - argument: " << Brief(argument()); 1578 os << "\n - context: " << Brief(context()); 1579 os << "\n - handler: " << Brief(handler()); 1580 os << "\n - promise_or_capability: " << Brief(promise_or_capability()); 1581 os << "\n"; 1582 } 1583 1584 void PromiseRejectReactionJobTask::PromiseRejectReactionJobTaskPrint( 1585 std::ostream& os) { // NOLINT 1586 HeapObject::PrintHeader(os, "PromiseRejectReactionJobTask"); 1587 os << "\n - argument: " << Brief(argument()); 1588 os << "\n - context: " << Brief(context()); 1589 os << "\n - handler: " << Brief(handler()); 1590 os << "\n - promise_or_capability: " << Brief(promise_or_capability()); 1591 os << "\n"; 1592 } 1593 1594 void PromiseResolveThenableJobTask::PromiseResolveThenableJobTaskPrint( 1595 std::ostream& os) { // NOLINT 1596 HeapObject::PrintHeader(os, "PromiseResolveThenableJobTask"); 1597 os << "\n - context: " << Brief(context()); 1598 os << "\n - promise_to_resolve: " << Brief(promise_to_resolve()); 1599 os << "\n - then: " << Brief(then()); 1600 os << "\n - thenable: " << Brief(thenable()); 1601 os << "\n"; 1602 } 1603 1604 void PromiseCapability::PromiseCapabilityPrint(std::ostream& os) { // NOLINT 1605 HeapObject::PrintHeader(os, "PromiseCapability"); 1606 os << "\n - promise: " << Brief(promise()); 1607 os << "\n - resolve: " << Brief(resolve()); 1608 os << "\n - reject: " << Brief(reject()); 1609 os << "\n"; 1610 } 1611 1612 void PromiseReaction::PromiseReactionPrint(std::ostream& os) { // NOLINT 1613 HeapObject::PrintHeader(os, "PromiseReaction"); 1614 os << "\n - next: " << Brief(next()); 1615 os << "\n - reject_handler: " << Brief(reject_handler()); 1616 os << "\n - fulfill_handler: " << Brief(fulfill_handler()); 1617 os << "\n - promise_or_capability: " << Brief(promise_or_capability()); 1618 os << "\n"; 1619 } 1620 1621 void AsyncGeneratorRequest::AsyncGeneratorRequestPrint( 1622 std::ostream& os) { // NOLINT 1623 HeapObject::PrintHeader(os, "AsyncGeneratorRequest"); 1624 const char* mode = "Invalid!"; 1625 switch (resume_mode()) { 1626 case JSGeneratorObject::kNext: 1627 mode = ".next()"; 1628 break; 1629 case JSGeneratorObject::kReturn: 1630 mode = ".return()"; 1631 break; 1632 case JSGeneratorObject::kThrow: 1633 mode = ".throw()"; 1634 break; 1635 } 1636 os << "\n - resume mode: " << mode; 1637 os << "\n - value: " << Brief(value()); 1638 os << "\n - next: " << Brief(next()); 1639 os << "\n"; 1640 } 1641 1642 void ModuleInfoEntry::ModuleInfoEntryPrint(std::ostream& os) { // NOLINT 1643 HeapObject::PrintHeader(os, "ModuleInfoEntry"); 1644 os << "\n - export_name: " << Brief(export_name()); 1645 os << "\n - local_name: " << Brief(local_name()); 1646 os << "\n - import_name: " << Brief(import_name()); 1647 os << "\n - module_request: " << module_request(); 1648 os << "\n - cell_index: " << cell_index(); 1649 os << "\n - beg_pos: " << beg_pos(); 1650 os << "\n - end_pos: " << end_pos(); 1651 os << "\n"; 1652 } 1653 1654 void Module::ModulePrint(std::ostream& os) { // NOLINT 1655 HeapObject::PrintHeader(os, "Module"); 1656 os << "\n - origin: " << Brief(script()->GetNameOrSourceURL()); 1657 os << "\n - code: " << Brief(code()); 1658 os << "\n - exports: " << Brief(exports()); 1659 os << "\n - requested_modules: " << Brief(requested_modules()); 1660 os << "\n - script: " << Brief(script()); 1661 os << "\n - import_meta: " << Brief(import_meta()); 1662 os << "\n - status: " << status(); 1663 os << "\n - exception: " << Brief(exception()); 1664 os << "\n"; 1665 } 1666 1667 void JSModuleNamespace::JSModuleNamespacePrint(std::ostream& os) { // NOLINT 1668 JSObjectPrintHeader(os, this, "JSModuleNamespace"); 1669 os << "\n - module: " << Brief(module()); 1670 JSObjectPrintBody(os, this); 1671 } 1672 1673 void PrototypeInfo::PrototypeInfoPrint(std::ostream& os) { // NOLINT 1674 HeapObject::PrintHeader(os, "PrototypeInfo"); 1675 os << "\n - module namespace: " << Brief(module_namespace()); 1676 os << "\n - prototype users: " << Brief(prototype_users()); 1677 os << "\n - registry slot: " << registry_slot(); 1678 os << "\n - object create map: " << Brief(object_create_map()); 1679 os << "\n - should_be_fast_map: " << should_be_fast_map(); 1680 os << "\n"; 1681 } 1682 1683 void Tuple2::Tuple2Print(std::ostream& os) { // NOLINT 1684 HeapObject::PrintHeader(os, "Tuple2"); 1685 os << "\n - value1: " << Brief(value1()); 1686 os << "\n - value2: " << Brief(value2()); 1687 os << "\n"; 1688 } 1689 1690 void Tuple3::Tuple3Print(std::ostream& os) { // NOLINT 1691 HeapObject::PrintHeader(os, "Tuple3"); 1692 os << "\n - value1: " << Brief(value1()); 1693 os << "\n - value2: " << Brief(value2()); 1694 os << "\n - value3: " << Brief(value3()); 1695 os << "\n"; 1696 } 1697 1698 void ArrayBoilerplateDescription::ArrayBoilerplateDescriptionPrint( 1699 std::ostream& os) { // NOLINT 1700 HeapObject::PrintHeader(os, "ArrayBoilerplateDescription"); 1701 os << "\n - elements kind: " << elements_kind(); 1702 os << "\n - constant elements: " << Brief(constant_elements()); 1703 os << "\n"; 1704 } 1705 1706 void WasmDebugInfo::WasmDebugInfoPrint(std::ostream& os) { // NOLINT 1707 HeapObject::PrintHeader(os, "WasmDebugInfo"); 1708 os << "\n - wasm_instance: " << Brief(wasm_instance()); 1709 os << "\n"; 1710 } 1711 1712 void WasmInstanceObject::WasmInstanceObjectPrint(std::ostream& os) { // NOLINT 1713 HeapObject::PrintHeader(os, "WasmInstanceObject"); 1714 os << "\n - module_object: " << Brief(module_object()); 1715 os << "\n - exports_object: " << Brief(exports_object()); 1716 os << "\n - native_context: " << Brief(native_context()); 1717 if (has_memory_object()) { 1718 os << "\n - memory_object: " << Brief(memory_object()); 1719 } 1720 if (has_globals_buffer()) { 1721 os << "\n - globals_buffer: " << Brief(globals_buffer()); 1722 } 1723 if (has_imported_mutable_globals_buffers()) { 1724 os << "\n - imported_mutable_globals_buffers: " 1725 << Brief(imported_mutable_globals_buffers()); 1726 } 1727 if (has_debug_info()) { 1728 os << "\n - debug_info: " << Brief(debug_info()); 1729 } 1730 if (has_table_object()) { 1731 os << "\n - table_object: " << Brief(table_object()); 1732 } 1733 os << "\n - imported_function_instances: " 1734 << Brief(imported_function_instances()); 1735 os << "\n - imported_function_callables: " 1736 << Brief(imported_function_callables()); 1737 if (has_indirect_function_table_instances()) { 1738 os << "\n - indirect_function_table_instances: " 1739 << Brief(indirect_function_table_instances()); 1740 } 1741 if (has_managed_native_allocations()) { 1742 os << "\n - managed_native_allocations: " 1743 << Brief(managed_native_allocations()); 1744 } 1745 os << "\n - memory_start: " << static_cast<void*>(memory_start()); 1746 os << "\n - memory_size: " << memory_size(); 1747 os << "\n - memory_mask: " << AsHex(memory_mask()); 1748 os << "\n - imported_function_targets: " 1749 << static_cast<void*>(imported_function_targets()); 1750 os << "\n - globals_start: " << static_cast<void*>(globals_start()); 1751 os << "\n - imported_mutable_globals: " 1752 << static_cast<void*>(imported_mutable_globals()); 1753 os << "\n - indirect_function_table_size: " << indirect_function_table_size(); 1754 os << "\n - indirect_function_table_sig_ids: " 1755 << static_cast<void*>(indirect_function_table_sig_ids()); 1756 os << "\n - indirect_function_table_targets: " 1757 << static_cast<void*>(indirect_function_table_targets()); 1758 os << "\n"; 1759 } 1760 1761 void WasmExportedFunctionData::WasmExportedFunctionDataPrint( 1762 std::ostream& os) { // NOLINT 1763 HeapObject::PrintHeader(os, "WasmExportedFunctionData"); 1764 os << "\n - wrapper_code: " << Brief(wrapper_code()); 1765 os << "\n - instance: " << Brief(instance()); 1766 os << "\n - function_index: " << function_index(); 1767 os << "\n"; 1768 } 1769 1770 void WasmModuleObject::WasmModuleObjectPrint(std::ostream& os) { // NOLINT 1771 HeapObject::PrintHeader(os, "WasmModuleObject"); 1772 os << "\n - module: " << module(); 1773 os << "\n - native module: " << native_module(); 1774 os << "\n - export wrappers: " << Brief(export_wrappers()); 1775 os << "\n - script: " << Brief(script()); 1776 if (has_asm_js_offset_table()) { 1777 os << "\n - asm_js_offset_table: " << Brief(asm_js_offset_table()); 1778 } 1779 if (has_breakpoint_infos()) { 1780 os << "\n - breakpoint_infos: " << Brief(breakpoint_infos()); 1781 } 1782 os << "\n"; 1783 } 1784 1785 void LoadHandler::LoadHandlerPrint(std::ostream& os) { // NOLINT 1786 HeapObject::PrintHeader(os, "LoadHandler"); 1787 // TODO(ishell): implement printing based on handler kind 1788 os << "\n - handler: " << Brief(smi_handler()); 1789 os << "\n - validity_cell: " << Brief(validity_cell()); 1790 int data_count = data_field_count(); 1791 if (data_count >= 1) { 1792 os << "\n - data1: " << Brief(data1()); 1793 } 1794 if (data_count >= 2) { 1795 os << "\n - data2: " << Brief(data2()); 1796 } 1797 if (data_count >= 3) { 1798 os << "\n - data3: " << Brief(data3()); 1799 } 1800 os << "\n"; 1801 } 1802 1803 void StoreHandler::StoreHandlerPrint(std::ostream& os) { // NOLINT 1804 HeapObject::PrintHeader(os, "StoreHandler"); 1805 // TODO(ishell): implement printing based on handler kind 1806 os << "\n - handler: " << Brief(smi_handler()); 1807 os << "\n - validity_cell: " << Brief(validity_cell()); 1808 int data_count = data_field_count(); 1809 if (data_count >= 1) { 1810 os << "\n - data1: " << Brief(data1()); 1811 } 1812 if (data_count >= 2) { 1813 os << "\n - data2: " << Brief(data2()); 1814 } 1815 if (data_count >= 3) { 1816 os << "\n - data3: " << Brief(data3()); 1817 } 1818 os << "\n"; 1819 } 1820 1821 void AccessorPair::AccessorPairPrint(std::ostream& os) { // NOLINT 1822 HeapObject::PrintHeader(os, "AccessorPair"); 1823 os << "\n - getter: " << Brief(getter()); 1824 os << "\n - setter: " << Brief(setter()); 1825 os << "\n"; 1826 } 1827 1828 1829 void AccessCheckInfo::AccessCheckInfoPrint(std::ostream& os) { // NOLINT 1830 HeapObject::PrintHeader(os, "AccessCheckInfo"); 1831 os << "\n - callback: " << Brief(callback()); 1832 os << "\n - named_interceptor: " << Brief(named_interceptor()); 1833 os << "\n - indexed_interceptor: " << Brief(indexed_interceptor()); 1834 os << "\n - data: " << Brief(data()); 1835 os << "\n"; 1836 } 1837 1838 void CallHandlerInfo::CallHandlerInfoPrint(std::ostream& os) { // NOLINT 1839 HeapObject::PrintHeader(os, "CallHandlerInfo"); 1840 os << "\n - callback: " << Brief(callback()); 1841 os << "\n - js_callback: " << Brief(js_callback()); 1842 os << "\n - data: " << Brief(data()); 1843 os << "\n - side_effect_free: " 1844 << (IsSideEffectFreeCallHandlerInfo() ? "true" : "false"); 1845 os << "\n"; 1846 } 1847 1848 void InterceptorInfo::InterceptorInfoPrint(std::ostream& os) { // NOLINT 1849 HeapObject::PrintHeader(os, "InterceptorInfo"); 1850 os << "\n - getter: " << Brief(getter()); 1851 os << "\n - setter: " << Brief(setter()); 1852 os << "\n - query: " << Brief(query()); 1853 os << "\n - deleter: " << Brief(deleter()); 1854 os << "\n - enumerator: " << Brief(enumerator()); 1855 os << "\n - data: " << Brief(data()); 1856 os << "\n"; 1857 } 1858 1859 1860 void FunctionTemplateInfo::FunctionTemplateInfoPrint( 1861 std::ostream& os) { // NOLINT 1862 HeapObject::PrintHeader(os, "FunctionTemplateInfo"); 1863 os << "\n - class name: " << Brief(class_name()); 1864 os << "\n - tag: " << Brief(tag()); 1865 os << "\n - serial_number: " << Brief(serial_number()); 1866 os << "\n - property_list: " << Brief(property_list()); 1867 os << "\n - call_code: " << Brief(call_code()); 1868 os << "\n - property_accessors: " << Brief(property_accessors()); 1869 os << "\n - prototype_template: " << Brief(prototype_template()); 1870 os << "\n - parent_template: " << Brief(parent_template()); 1871 os << "\n - named_property_handler: " << Brief(named_property_handler()); 1872 os << "\n - indexed_property_handler: " << Brief(indexed_property_handler()); 1873 os << "\n - instance_template: " << Brief(instance_template()); 1874 os << "\n - signature: " << Brief(signature()); 1875 os << "\n - access_check_info: " << Brief(access_check_info()); 1876 os << "\n - cached_property_name: " << Brief(cached_property_name()); 1877 os << "\n - hidden_prototype: " << (hidden_prototype() ? "true" : "false"); 1878 os << "\n - undetectable: " << (undetectable() ? "true" : "false"); 1879 os << "\n - need_access_check: " << (needs_access_check() ? "true" : "false"); 1880 os << "\n - instantiated: " << (instantiated() ? "true" : "false"); 1881 os << "\n"; 1882 } 1883 1884 1885 void ObjectTemplateInfo::ObjectTemplateInfoPrint(std::ostream& os) { // NOLINT 1886 HeapObject::PrintHeader(os, "ObjectTemplateInfo"); 1887 os << "\n - tag: " << Brief(tag()); 1888 os << "\n - serial_number: " << Brief(serial_number()); 1889 os << "\n - property_list: " << Brief(property_list()); 1890 os << "\n - property_accessors: " << Brief(property_accessors()); 1891 os << "\n - constructor: " << Brief(constructor()); 1892 os << "\n - embedder_field_count: " << embedder_field_count(); 1893 os << "\n - immutable_proto: " << (immutable_proto() ? "true" : "false"); 1894 os << "\n"; 1895 } 1896 1897 1898 void AllocationSite::AllocationSitePrint(std::ostream& os) { // NOLINT 1899 HeapObject::PrintHeader(os, "AllocationSite"); 1900 if (this->HasWeakNext()) os << "\n - weak_next: " << Brief(weak_next()); 1901 os << "\n - dependent code: " << Brief(dependent_code()); 1902 os << "\n - nested site: " << Brief(nested_site()); 1903 os << "\n - memento found count: " 1904 << Brief(Smi::FromInt(memento_found_count())); 1905 os << "\n - memento create count: " 1906 << Brief(Smi::FromInt(memento_create_count())); 1907 os << "\n - pretenure decision: " 1908 << Brief(Smi::FromInt(pretenure_decision())); 1909 os << "\n - transition_info: "; 1910 if (!PointsToLiteral()) { 1911 ElementsKind kind = GetElementsKind(); 1912 os << "Array allocation with ElementsKind " << ElementsKindToString(kind); 1913 } else if (boilerplate()->IsJSArray()) { 1914 os << "Array literal with boilerplate " << Brief(boilerplate()); 1915 } else { 1916 os << "Object literal with boilerplate " << Brief(boilerplate()); 1917 } 1918 os << "\n"; 1919 } 1920 1921 1922 void AllocationMemento::AllocationMementoPrint(std::ostream& os) { // NOLINT 1923 HeapObject::PrintHeader(os, "AllocationMemento"); 1924 os << "\n - allocation site: "; 1925 if (IsValid()) { 1926 GetAllocationSite()->AllocationSitePrint(os); 1927 } else { 1928 os << "<invalid>\n"; 1929 } 1930 } 1931 1932 1933 void Script::ScriptPrint(std::ostream& os) { // NOLINT 1934 HeapObject::PrintHeader(os, "Script"); 1935 os << "\n - source: " << Brief(source()); 1936 os << "\n - name: " << Brief(name()); 1937 os << "\n - line_offset: " << line_offset(); 1938 os << "\n - column_offset: " << column_offset(); 1939 os << "\n - type: " << type(); 1940 os << "\n - id: " << id(); 1941 os << "\n - context data: " << Brief(context_data()); 1942 os << "\n - compilation type: " << compilation_type(); 1943 os << "\n - line ends: " << Brief(line_ends()); 1944 if (has_eval_from_shared()) { 1945 os << "\n - eval from shared: " << Brief(eval_from_shared()); 1946 } 1947 if (is_wrapped()) { 1948 os << "\n - wrapped arguments: " << Brief(wrapped_arguments()); 1949 } 1950 os << "\n - eval from position: " << eval_from_position(); 1951 os << "\n - shared function infos: " << Brief(shared_function_infos()); 1952 os << "\n"; 1953 } 1954 1955 #ifdef V8_INTL_SUPPORT 1956 void JSCollator::JSCollatorPrint(std::ostream& os) { // NOLINT 1957 JSObjectPrintHeader(os, this, "JSCollator"); 1958 os << "\n - usage: " << JSCollator::UsageToString(usage()); 1959 os << "\n - icu collator: " << Brief(icu_collator()); 1960 os << "\n - bound compare: " << Brief(bound_compare()); 1961 os << "\n"; 1962 } 1963 1964 void JSListFormat::JSListFormatPrint(std::ostream& os) { // NOLINT 1965 JSObjectPrintHeader(os, this, "JSListFormat"); 1966 os << "\n - locale: " << Brief(locale()); 1967 os << "\n - style: " << StyleAsString(); 1968 os << "\n - type: " << TypeAsString(); 1969 os << "\n - formatter: " << Brief(formatter()); 1970 os << "\n"; 1971 } 1972 1973 void JSLocale::JSLocalePrint(std::ostream& os) { // NOLINT 1974 HeapObject::PrintHeader(os, "JSLocale"); 1975 os << "\n - language: " << Brief(language()); 1976 os << "\n - script: " << Brief(script()); 1977 os << "\n - region: " << Brief(region()); 1978 os << "\n - baseName: " << Brief(base_name()); 1979 os << "\n - locale: " << Brief(locale()); 1980 os << "\n - calendar: " << Brief(calendar()); 1981 os << "\n - caseFirst: " << Brief(case_first()); 1982 os << "\n - collation: " << Brief(collation()); 1983 os << "\n - hourCycle: " << Brief(hour_cycle()); 1984 os << "\n - numeric: " << Brief(numeric()); 1985 os << "\n - numberingSystem: " << Brief(numbering_system()); 1986 os << "\n"; 1987 } 1988 1989 void JSPluralRules::JSPluralRulesPrint(std::ostream& os) { // NOLINT 1990 HeapObject::PrintHeader(os, "JSPluralRules"); 1991 JSObjectPrint(os); 1992 os << "\n - locale: " << Brief(locale()); 1993 os << "\n - type: " << Brief(type()); 1994 os << "\n - icu plural rules: " << Brief(icu_plural_rules()); 1995 os << "\n - icu decimal format: " << Brief(icu_decimal_format()); 1996 os << "\n"; 1997 } 1998 1999 void JSRelativeTimeFormat::JSRelativeTimeFormatPrint( 2000 std::ostream& os) { // NOLINT 2001 JSObjectPrintHeader(os, this, "JSRelativeTimeFormat"); 2002 os << "\n - locale: " << Brief(locale()); 2003 os << "\n - style: " << StyleAsString(); 2004 os << "\n - numeric: " << NumericAsString(); 2005 os << "\n - formatter: " << Brief(formatter()); 2006 os << "\n"; 2007 } 2008 #endif // V8_INTL_SUPPORT 2009 2010 namespace { 2011 void PrintScopeInfoList(ScopeInfo* scope_info, std::ostream& os, 2012 const char* list_name, int nof_internal_slots, 2013 int start, int length) { 2014 if (length <= 0) return; 2015 int end = start + length; 2016 os << "\n - " << list_name; 2017 if (nof_internal_slots > 0) { 2018 os << " " << start << "-" << end << " [internal slots]"; 2019 } 2020 os << " {\n"; 2021 for (int i = nof_internal_slots; start < end; ++i, ++start) { 2022 os << " - " << i << ": "; 2023 String::cast(scope_info->get(start))->ShortPrint(os); 2024 os << "\n"; 2025 } 2026 os << " }"; 2027 } 2028 } // namespace 2029 2030 void ScopeInfo::ScopeInfoPrint(std::ostream& os) { // NOLINT 2031 HeapObject::PrintHeader(os, "ScopeInfo"); 2032 if (length() == 0) { 2033 os << "\n - length = 0\n"; 2034 return; 2035 } 2036 int flags = Flags(); 2037 2038 os << "\n - parameters: " << ParameterCount(); 2039 os << "\n - context locals : " << ContextLocalCount(); 2040 2041 os << "\n - scope type: " << scope_type(); 2042 if (CallsSloppyEval()) os << "\n - sloppy eval"; 2043 os << "\n - language mode: " << language_mode(); 2044 if (is_declaration_scope()) os << "\n - declaration scope"; 2045 if (HasReceiver()) { 2046 os << "\n - receiver: " << ReceiverVariableField::decode(flags); 2047 } 2048 if (HasNewTarget()) os << "\n - needs new target"; 2049 if (HasFunctionName()) { 2050 os << "\n - function name(" << FunctionVariableField::decode(flags) 2051 << "): "; 2052 FunctionName()->ShortPrint(os); 2053 } 2054 if (IsAsmModule()) os << "\n - asm module"; 2055 if (HasSimpleParameters()) os << "\n - simple parameters"; 2056 os << "\n - function kind: " << function_kind(); 2057 if (HasOuterScopeInfo()) { 2058 os << "\n - outer scope info: " << Brief(OuterScopeInfo()); 2059 } 2060 if (HasFunctionName()) { 2061 os << "\n - function name: " << Brief(FunctionName()); 2062 } 2063 if (HasInferredFunctionName()) { 2064 os << "\n - inferred function name: " << Brief(InferredFunctionName()); 2065 } 2066 2067 if (HasPositionInfo()) { 2068 os << "\n - start position: " << StartPosition(); 2069 os << "\n - end position: " << EndPosition(); 2070 } 2071 os << "\n - length: " << length(); 2072 if (length() > 0) { 2073 PrintScopeInfoList(this, os, "context slots", Context::MIN_CONTEXT_SLOTS, 2074 ContextLocalNamesIndex(), ContextLocalCount()); 2075 // TODO(neis): Print module stuff if present. 2076 } 2077 os << "\n"; 2078 } 2079 2080 void DebugInfo::DebugInfoPrint(std::ostream& os) { // NOLINT 2081 HeapObject::PrintHeader(os, "DebugInfo"); 2082 os << "\n - flags: " << flags(); 2083 os << "\n - debugger_hints: " << debugger_hints(); 2084 os << "\n - shared: " << Brief(shared()); 2085 os << "\n - script: " << Brief(script()); 2086 os << "\n - original bytecode array: " << Brief(original_bytecode_array()); 2087 os << "\n - break_points: "; 2088 break_points()->FixedArrayPrint(os); 2089 os << "\n - coverage_info: " << Brief(coverage_info()); 2090 } 2091 2092 2093 void StackFrameInfo::StackFrameInfoPrint(std::ostream& os) { // NOLINT 2094 HeapObject::PrintHeader(os, "StackFrame"); 2095 os << "\n - line_number: " << line_number(); 2096 os << "\n - column_number: " << column_number(); 2097 os << "\n - script_id: " << script_id(); 2098 os << "\n - script_name: " << Brief(script_name()); 2099 os << "\n - script_name_or_source_url: " 2100 << Brief(script_name_or_source_url()); 2101 os << "\n - function_name: " << Brief(function_name()); 2102 os << "\n - is_eval: " << (is_eval() ? "true" : "false"); 2103 os << "\n - is_constructor: " << (is_constructor() ? "true" : "false"); 2104 os << "\n"; 2105 } 2106 2107 static void PrintBitMask(std::ostream& os, uint32_t value) { // NOLINT 2108 for (int i = 0; i < 32; i++) { 2109 if ((i & 7) == 0) os << " "; 2110 os << (((value & 1) == 0) ? "_" : "x"); 2111 value >>= 1; 2112 } 2113 } 2114 2115 void LayoutDescriptor::Print() { 2116 StdoutStream os; 2117 this->Print(os); 2118 os << std::flush; 2119 } 2120 2121 void LayoutDescriptor::ShortPrint(std::ostream& os) { 2122 if (IsSmi()) { 2123 os << this; // Print tagged value for easy use with "jld" gdb macro. 2124 } else { 2125 os << Brief(this); 2126 } 2127 } 2128 2129 void LayoutDescriptor::Print(std::ostream& os) { // NOLINT 2130 os << "Layout descriptor: "; 2131 if (IsFastPointerLayout()) { 2132 os << "<all tagged>"; 2133 } else if (IsSmi()) { 2134 os << "fast"; 2135 PrintBitMask(os, static_cast<uint32_t>(Smi::ToInt(this))); 2136 } else if (IsOddball() && IsUninitialized()) { 2137 os << "<uninitialized>"; 2138 } else { 2139 os << "slow"; 2140 int num_words = number_of_layout_words(); 2141 for (int i = 0; i < num_words; i++) { 2142 if (i > 0) os << " |"; 2143 PrintBitMask(os, get_layout_word(i)); 2144 } 2145 } 2146 os << "\n"; 2147 } 2148 2149 void PreParsedScopeData::PreParsedScopeDataPrint(std::ostream& os) { // NOLINT 2150 HeapObject::PrintHeader(os, "PreParsedScopeData"); 2151 os << "\n - scope_data: " << Brief(scope_data()); 2152 os << "\n - length: " << length(); 2153 for (int i = 0; i < length(); ++i) { 2154 os << "\n - [" << i << "]: " << Brief(child_data(i)); 2155 } 2156 os << "\n"; 2157 } 2158 2159 void UncompiledDataWithoutPreParsedScope:: 2160 UncompiledDataWithoutPreParsedScopePrint(std::ostream& os) { // NOLINT 2161 HeapObject::PrintHeader(os, "UncompiledDataWithoutPreParsedScope"); 2162 os << "\n - start position: " << start_position(); 2163 os << "\n - end position: " << end_position(); 2164 os << "\n"; 2165 } 2166 2167 void UncompiledDataWithPreParsedScope::UncompiledDataWithPreParsedScopePrint( 2168 std::ostream& os) { // NOLINT 2169 HeapObject::PrintHeader(os, "UncompiledDataWithPreParsedScope"); 2170 os << "\n - start position: " << start_position(); 2171 os << "\n - end position: " << end_position(); 2172 os << "\n - pre_parsed_scope_data: " << Brief(pre_parsed_scope_data()); 2173 os << "\n"; 2174 } 2175 2176 void InterpreterData::InterpreterDataPrint(std::ostream& os) { // NOLINT 2177 HeapObject::PrintHeader(os, "InterpreterData"); 2178 os << "\n - bytecode_array: " << Brief(bytecode_array()); 2179 os << "\n - interpreter_trampoline: " << Brief(interpreter_trampoline()); 2180 os << "\n"; 2181 } 2182 2183 void MaybeObject::Print() { 2184 StdoutStream os; 2185 this->Print(os); 2186 os << std::flush; 2187 } 2188 2189 void MaybeObject::Print(std::ostream& os) { 2190 Smi* smi; 2191 HeapObject* heap_object; 2192 if (ToSmi(&smi)) { 2193 smi->SmiPrint(os); 2194 } else if (IsClearedWeakHeapObject()) { 2195 os << "[cleared]"; 2196 } else if (ToWeakHeapObject(&heap_object)) { 2197 os << "[weak] "; 2198 heap_object->HeapObjectPrint(os); 2199 } else if (ToStrongHeapObject(&heap_object)) { 2200 heap_object->HeapObjectPrint(os); 2201 } else { 2202 UNREACHABLE(); 2203 } 2204 } 2205 2206 #endif // OBJECT_PRINT 2207 2208 void HeapNumber::HeapNumberPrint(std::ostream& os) { os << value(); } 2209 2210 void MutableHeapNumber::MutableHeapNumberPrint(std::ostream& os) { 2211 os << value(); 2212 } 2213 2214 // TODO(cbruni): remove once the new maptracer is in place. 2215 void Name::NameShortPrint() { 2216 if (this->IsString()) { 2217 PrintF("%s", String::cast(this)->ToCString().get()); 2218 } else { 2219 DCHECK(this->IsSymbol()); 2220 Symbol* s = Symbol::cast(this); 2221 if (s->name()->IsUndefined()) { 2222 PrintF("#<%s>", s->PrivateSymbolToName()); 2223 } else { 2224 PrintF("<%s>", String::cast(s->name())->ToCString().get()); 2225 } 2226 } 2227 } 2228 2229 // TODO(cbruni): remove once the new maptracer is in place. 2230 int Name::NameShortPrint(Vector<char> str) { 2231 if (this->IsString()) { 2232 return SNPrintF(str, "%s", String::cast(this)->ToCString().get()); 2233 } else { 2234 DCHECK(this->IsSymbol()); 2235 Symbol* s = Symbol::cast(this); 2236 if (s->name()->IsUndefined()) { 2237 return SNPrintF(str, "#<%s>", s->PrivateSymbolToName()); 2238 } else { 2239 return SNPrintF(str, "<%s>", String::cast(s->name())->ToCString().get()); 2240 } 2241 } 2242 } 2243 2244 void Map::PrintMapDetails(std::ostream& os) { 2245 DisallowHeapAllocation no_gc; 2246 #ifdef OBJECT_PRINT 2247 this->MapPrint(os); 2248 #else 2249 os << "Map=" << reinterpret_cast<void*>(this); 2250 #endif 2251 os << "\n"; 2252 instance_descriptors()->PrintDescriptors(os); 2253 } 2254 2255 void DescriptorArray::PrintDescriptors(std::ostream& os) { 2256 for (int i = 0; i < number_of_descriptors(); i++) { 2257 Name* key = GetKey(i); 2258 os << "\n [" << i << "]: "; 2259 #ifdef OBJECT_PRINT 2260 key->NamePrint(os); 2261 #else 2262 key->ShortPrint(os); 2263 #endif 2264 os << " "; 2265 PrintDescriptorDetails(os, i, PropertyDetails::kPrintFull); 2266 } 2267 os << "\n"; 2268 } 2269 2270 void DescriptorArray::PrintDescriptorDetails(std::ostream& os, int descriptor, 2271 PropertyDetails::PrintMode mode) { 2272 PropertyDetails details = GetDetails(descriptor); 2273 details.PrintAsFastTo(os, mode); 2274 os << " @ "; 2275 switch (details.location()) { 2276 case kField: { 2277 FieldType* field_type = GetFieldType(descriptor); 2278 field_type->PrintTo(os); 2279 break; 2280 } 2281 case kDescriptor: 2282 Object* value = GetStrongValue(descriptor); 2283 os << Brief(value); 2284 if (value->IsAccessorPair()) { 2285 AccessorPair* pair = AccessorPair::cast(value); 2286 os << "(get: " << Brief(pair->getter()) 2287 << ", set: " << Brief(pair->setter()) << ")"; 2288 } 2289 break; 2290 } 2291 } 2292 2293 #if defined(DEBUG) || defined(OBJECT_PRINT) 2294 // This method is only meant to be called from gdb for debugging purposes. 2295 // Since the string can also be in two-byte encoding, non-Latin1 characters 2296 // will be ignored in the output. 2297 char* String::ToAsciiArray() { 2298 // Static so that subsequent calls frees previously allocated space. 2299 // This also means that previous results will be overwritten. 2300 static char* buffer = nullptr; 2301 if (buffer != nullptr) delete[] buffer; 2302 buffer = new char[length() + 1]; 2303 WriteToFlat(this, reinterpret_cast<uint8_t*>(buffer), 0, length()); 2304 buffer[length()] = 0; 2305 return buffer; 2306 } 2307 2308 // static 2309 void TransitionsAccessor::PrintOneTransition(std::ostream& os, Name* key, 2310 Map* target) { 2311 os << "\n "; 2312 #ifdef OBJECT_PRINT 2313 key->NamePrint(os); 2314 #else 2315 key->ShortPrint(os); 2316 #endif 2317 os << ": "; 2318 ReadOnlyRoots roots = key->GetReadOnlyRoots(); 2319 if (key == roots.nonextensible_symbol()) { 2320 os << "(transition to non-extensible)"; 2321 } else if (key == roots.sealed_symbol()) { 2322 os << "(transition to sealed)"; 2323 } else if (key == roots.frozen_symbol()) { 2324 os << "(transition to frozen)"; 2325 } else if (key == roots.elements_transition_symbol()) { 2326 os << "(transition to " << ElementsKindToString(target->elements_kind()) 2327 << ")"; 2328 } else if (key == roots.strict_function_transition_symbol()) { 2329 os << " (transition to strict function)"; 2330 } else { 2331 DCHECK(!IsSpecialTransition(roots, key)); 2332 os << "(transition to "; 2333 int descriptor = target->LastAdded(); 2334 DescriptorArray* descriptors = target->instance_descriptors(); 2335 descriptors->PrintDescriptorDetails(os, descriptor, 2336 PropertyDetails::kForTransitions); 2337 os << ")"; 2338 } 2339 os << " -> " << Brief(target); 2340 } 2341 2342 void TransitionArray::PrintInternal(std::ostream& os) { 2343 int num_transitions = number_of_transitions(); 2344 os << "Transition array #" << num_transitions << ":"; 2345 for (int i = 0; i < num_transitions; i++) { 2346 Name* key = GetKey(i); 2347 Map* target = GetTarget(i); 2348 TransitionsAccessor::PrintOneTransition(os, key, target); 2349 } 2350 os << "\n" << std::flush; 2351 } 2352 2353 void TransitionsAccessor::PrintTransitions(std::ostream& os) { // NOLINT 2354 switch (encoding()) { 2355 case kPrototypeInfo: 2356 case kUninitialized: 2357 return; 2358 case kWeakRef: { 2359 Map* target = Map::cast(raw_transitions_->ToWeakHeapObject()); 2360 Name* key = GetSimpleTransitionKey(target); 2361 PrintOneTransition(os, key, target); 2362 break; 2363 } 2364 case kFullTransitionArray: 2365 return transitions()->PrintInternal(os); 2366 } 2367 } 2368 2369 void TransitionsAccessor::PrintTransitionTree() { 2370 StdoutStream os; 2371 os << "map= " << Brief(map_); 2372 DisallowHeapAllocation no_gc; 2373 PrintTransitionTree(os, 0, &no_gc); 2374 os << "\n" << std::flush; 2375 } 2376 2377 void TransitionsAccessor::PrintTransitionTree(std::ostream& os, int level, 2378 DisallowHeapAllocation* no_gc) { 2379 ReadOnlyRoots roots = ReadOnlyRoots(isolate_); 2380 int num_transitions = NumberOfTransitions(); 2381 if (num_transitions == 0) return; 2382 for (int i = 0; i < num_transitions; i++) { 2383 Name* key = GetKey(i); 2384 Map* target = GetTarget(i); 2385 os << std::endl 2386 << " " << level << "/" << i << ":" << std::setw(level * 2 + 2) << " "; 2387 std::stringstream ss; 2388 ss << Brief(target); 2389 os << std::left << std::setw(50) << ss.str() << ": "; 2390 2391 if (key == roots.nonextensible_symbol()) { 2392 os << "to non-extensible"; 2393 } else if (key == roots.sealed_symbol()) { 2394 os << "to sealed "; 2395 } else if (key == roots.frozen_symbol()) { 2396 os << "to frozen"; 2397 } else if (key == roots.elements_transition_symbol()) { 2398 os << "to " << ElementsKindToString(target->elements_kind()); 2399 } else if (key == roots.strict_function_transition_symbol()) { 2400 os << "to strict function"; 2401 } else { 2402 #ifdef OBJECT_PRINT 2403 key->NamePrint(os); 2404 #else 2405 key->ShortPrint(os); 2406 #endif 2407 os << " "; 2408 DCHECK(!IsSpecialTransition(ReadOnlyRoots(isolate_), key)); 2409 os << "to "; 2410 int descriptor = target->LastAdded(); 2411 DescriptorArray* descriptors = target->instance_descriptors(); 2412 descriptors->PrintDescriptorDetails(os, descriptor, 2413 PropertyDetails::kForTransitions); 2414 } 2415 TransitionsAccessor transitions(isolate_, target, no_gc); 2416 transitions.PrintTransitionTree(os, level + 1, no_gc); 2417 } 2418 } 2419 2420 void JSObject::PrintTransitions(std::ostream& os) { // NOLINT 2421 DisallowHeapAllocation no_gc; 2422 TransitionsAccessor ta(GetIsolate(), map(), &no_gc); 2423 if (ta.NumberOfTransitions() == 0) return; 2424 os << "\n - transitions"; 2425 ta.PrintTransitions(os); 2426 } 2427 2428 #endif // defined(DEBUG) || defined(OBJECT_PRINT) 2429 } // namespace internal 2430 } // namespace v8 2431 2432 // 2433 // The following functions are used by our gdb macros. 2434 // 2435 V8_EXPORT_PRIVATE extern void _v8_internal_Print_Object(void* object) { 2436 reinterpret_cast<i::Object*>(object)->Print(); 2437 } 2438 2439 V8_EXPORT_PRIVATE extern void _v8_internal_Print_Code(void* object) { 2440 i::Address address = reinterpret_cast<i::Address>(object); 2441 i::Isolate* isolate = i::Isolate::Current(); 2442 2443 i::wasm::WasmCode* wasm_code = 2444 isolate->wasm_engine()->code_manager()->LookupCode(address); 2445 if (wasm_code) { 2446 i::StdoutStream os; 2447 wasm_code->Disassemble(nullptr, os, address); 2448 return; 2449 } 2450 2451 if (!isolate->heap()->InSpaceSlow(address, i::CODE_SPACE) && 2452 !isolate->heap()->InSpaceSlow(address, i::LO_SPACE) && 2453 !i::InstructionStream::PcIsOffHeap(isolate, address)) { 2454 i::PrintF( 2455 "%p is not within the current isolate's large object, code or embedded " 2456 "spaces\n", 2457 object); 2458 return; 2459 } 2460 2461 i::Code* code = isolate->FindCodeObject(address); 2462 if (!code->IsCode()) { 2463 i::PrintF("No code object found containing %p\n", object); 2464 return; 2465 } 2466 #ifdef ENABLE_DISASSEMBLER 2467 i::StdoutStream os; 2468 code->Disassemble(nullptr, os, address); 2469 #else // ENABLE_DISASSEMBLER 2470 code->Print(); 2471 #endif // ENABLE_DISASSEMBLER 2472 } 2473 2474 V8_EXPORT_PRIVATE extern void _v8_internal_Print_LayoutDescriptor( 2475 void* object) { 2476 i::Object* o = reinterpret_cast<i::Object*>(object); 2477 if (!o->IsLayoutDescriptor()) { 2478 printf("Please provide a layout descriptor\n"); 2479 } else { 2480 reinterpret_cast<i::LayoutDescriptor*>(object)->Print(); 2481 } 2482 } 2483 2484 V8_EXPORT_PRIVATE extern void _v8_internal_Print_StackTrace() { 2485 i::Isolate* isolate = i::Isolate::Current(); 2486 isolate->PrintStack(stdout); 2487 } 2488 2489 V8_EXPORT_PRIVATE extern void _v8_internal_Print_TransitionTree(void* object) { 2490 i::Object* o = reinterpret_cast<i::Object*>(object); 2491 if (!o->IsMap()) { 2492 printf("Please provide a valid Map\n"); 2493 } else { 2494 #if defined(DEBUG) || defined(OBJECT_PRINT) 2495 i::DisallowHeapAllocation no_gc; 2496 i::Map* map = reinterpret_cast<i::Map*>(object); 2497 i::TransitionsAccessor transitions(i::Isolate::Current(), map, &no_gc); 2498 transitions.PrintTransitionTree(); 2499 #endif 2500 } 2501 } 2502