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/interpreter/bytecodes.h" 14 #include "src/objects-inl.h" 15 #include "src/ostreams.h" 16 #include "src/regexp/jsregexp.h" 17 18 namespace v8 { 19 namespace internal { 20 21 #ifdef OBJECT_PRINT 22 23 void Object::Print() { 24 OFStream os(stdout); 25 this->Print(os); 26 os << std::flush; 27 } 28 29 30 void Object::Print(std::ostream& os) { // NOLINT 31 if (IsSmi()) { 32 os << "Smi: " << std::hex << "0x" << Smi::cast(this)->value(); 33 os << std::dec << " (" << Smi::cast(this)->value() << ")\n"; 34 } else { 35 HeapObject::cast(this)->HeapObjectPrint(os); 36 } 37 } 38 39 40 void HeapObject::PrintHeader(std::ostream& os, const char* id) { // NOLINT 41 os << reinterpret_cast<void*>(this) << ": ["; 42 if (id != nullptr) { 43 os << id; 44 } else { 45 os << map()->instance_type(); 46 } 47 os << "]"; 48 } 49 50 51 void HeapObject::HeapObjectPrint(std::ostream& os) { // NOLINT 52 InstanceType instance_type = map()->instance_type(); 53 54 HandleScope scope(GetIsolate()); 55 if (instance_type < FIRST_NONSTRING_TYPE) { 56 String::cast(this)->StringPrint(os); 57 os << "\n"; 58 return; 59 } 60 61 switch (instance_type) { 62 case SYMBOL_TYPE: 63 Symbol::cast(this)->SymbolPrint(os); 64 break; 65 case MAP_TYPE: 66 Map::cast(this)->MapPrint(os); 67 break; 68 case HEAP_NUMBER_TYPE: 69 HeapNumber::cast(this)->HeapNumberPrint(os); 70 os << "\n"; 71 break; 72 case MUTABLE_HEAP_NUMBER_TYPE: 73 os << "<mutable "; 74 HeapNumber::cast(this)->HeapNumberPrint(os); 75 os << ">\n"; 76 break; 77 case FIXED_DOUBLE_ARRAY_TYPE: 78 FixedDoubleArray::cast(this)->FixedDoubleArrayPrint(os); 79 break; 80 case FIXED_ARRAY_TYPE: 81 FixedArray::cast(this)->FixedArrayPrint(os); 82 break; 83 case BYTE_ARRAY_TYPE: 84 ByteArray::cast(this)->ByteArrayPrint(os); 85 break; 86 case BYTECODE_ARRAY_TYPE: 87 BytecodeArray::cast(this)->BytecodeArrayPrint(os); 88 break; 89 case TRANSITION_ARRAY_TYPE: 90 TransitionArray::cast(this)->TransitionArrayPrint(os); 91 break; 92 case FREE_SPACE_TYPE: 93 FreeSpace::cast(this)->FreeSpacePrint(os); 94 break; 95 96 #define PRINT_FIXED_TYPED_ARRAY(Type, type, TYPE, ctype, size) \ 97 case Fixed##Type##Array::kInstanceType: \ 98 Fixed##Type##Array::cast(this)->FixedTypedArrayPrint(os); \ 99 break; 100 101 TYPED_ARRAYS(PRINT_FIXED_TYPED_ARRAY) 102 #undef PRINT_FIXED_TYPED_ARRAY 103 104 case JS_TYPED_ARRAY_KEY_ITERATOR_TYPE: 105 case JS_FAST_ARRAY_KEY_ITERATOR_TYPE: 106 case JS_GENERIC_ARRAY_KEY_ITERATOR_TYPE: 107 case JS_INT8_ARRAY_KEY_VALUE_ITERATOR_TYPE: 108 case JS_UINT8_ARRAY_KEY_VALUE_ITERATOR_TYPE: 109 case JS_INT16_ARRAY_KEY_VALUE_ITERATOR_TYPE: 110 case JS_UINT16_ARRAY_KEY_VALUE_ITERATOR_TYPE: 111 case JS_INT32_ARRAY_KEY_VALUE_ITERATOR_TYPE: 112 case JS_UINT32_ARRAY_KEY_VALUE_ITERATOR_TYPE: 113 case JS_FLOAT32_ARRAY_KEY_VALUE_ITERATOR_TYPE: 114 case JS_FLOAT64_ARRAY_KEY_VALUE_ITERATOR_TYPE: 115 case JS_UINT8_CLAMPED_ARRAY_KEY_VALUE_ITERATOR_TYPE: 116 case JS_FAST_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE: 117 case JS_FAST_HOLEY_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE: 118 case JS_FAST_ARRAY_KEY_VALUE_ITERATOR_TYPE: 119 case JS_FAST_HOLEY_ARRAY_KEY_VALUE_ITERATOR_TYPE: 120 case JS_FAST_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE: 121 case JS_FAST_HOLEY_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE: 122 case JS_GENERIC_ARRAY_KEY_VALUE_ITERATOR_TYPE: 123 case JS_INT8_ARRAY_VALUE_ITERATOR_TYPE: 124 case JS_UINT8_ARRAY_VALUE_ITERATOR_TYPE: 125 case JS_INT16_ARRAY_VALUE_ITERATOR_TYPE: 126 case JS_UINT16_ARRAY_VALUE_ITERATOR_TYPE: 127 case JS_INT32_ARRAY_VALUE_ITERATOR_TYPE: 128 case JS_UINT32_ARRAY_VALUE_ITERATOR_TYPE: 129 case JS_FLOAT32_ARRAY_VALUE_ITERATOR_TYPE: 130 case JS_FLOAT64_ARRAY_VALUE_ITERATOR_TYPE: 131 case JS_UINT8_CLAMPED_ARRAY_VALUE_ITERATOR_TYPE: 132 case JS_FAST_SMI_ARRAY_VALUE_ITERATOR_TYPE: 133 case JS_FAST_HOLEY_SMI_ARRAY_VALUE_ITERATOR_TYPE: 134 case JS_FAST_ARRAY_VALUE_ITERATOR_TYPE: 135 case JS_FAST_HOLEY_ARRAY_VALUE_ITERATOR_TYPE: 136 case JS_FAST_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE: 137 case JS_FAST_HOLEY_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE: 138 case JS_GENERIC_ARRAY_VALUE_ITERATOR_TYPE: 139 JSArrayIterator::cast(this)->JSArrayIteratorPrint(os); 140 break; 141 142 case FILLER_TYPE: 143 os << "filler"; 144 break; 145 case JS_OBJECT_TYPE: // fall through 146 case JS_API_OBJECT_TYPE: 147 case JS_SPECIAL_API_OBJECT_TYPE: 148 case JS_CONTEXT_EXTENSION_OBJECT_TYPE: 149 case JS_GENERATOR_OBJECT_TYPE: 150 case JS_ARGUMENTS_TYPE: 151 case JS_ERROR_TYPE: 152 case JS_PROMISE_CAPABILITY_TYPE: 153 JSObject::cast(this)->JSObjectPrint(os); 154 break; 155 case JS_PROMISE_TYPE: 156 JSPromise::cast(this)->JSPromisePrint(os); 157 break; 158 case JS_ARRAY_TYPE: 159 JSArray::cast(this)->JSArrayPrint(os); 160 break; 161 case JS_REGEXP_TYPE: 162 JSRegExp::cast(this)->JSRegExpPrint(os); 163 break; 164 case ODDBALL_TYPE: 165 Oddball::cast(this)->to_string()->Print(os); 166 break; 167 case JS_BOUND_FUNCTION_TYPE: 168 JSBoundFunction::cast(this)->JSBoundFunctionPrint(os); 169 break; 170 case JS_FUNCTION_TYPE: 171 JSFunction::cast(this)->JSFunctionPrint(os); 172 break; 173 case JS_GLOBAL_PROXY_TYPE: 174 JSGlobalProxy::cast(this)->JSGlobalProxyPrint(os); 175 break; 176 case JS_GLOBAL_OBJECT_TYPE: 177 JSGlobalObject::cast(this)->JSGlobalObjectPrint(os); 178 break; 179 case JS_VALUE_TYPE: 180 JSValue::cast(this)->JSValuePrint(os); 181 break; 182 case JS_DATE_TYPE: 183 JSDate::cast(this)->JSDatePrint(os); 184 break; 185 case CODE_TYPE: 186 Code::cast(this)->CodePrint(os); 187 break; 188 case JS_PROXY_TYPE: 189 JSProxy::cast(this)->JSProxyPrint(os); 190 break; 191 case JS_SET_TYPE: 192 JSSet::cast(this)->JSSetPrint(os); 193 break; 194 case JS_MAP_TYPE: 195 JSMap::cast(this)->JSMapPrint(os); 196 break; 197 case JS_SET_ITERATOR_TYPE: 198 JSSetIterator::cast(this)->JSSetIteratorPrint(os); 199 break; 200 case JS_MAP_ITERATOR_TYPE: 201 JSMapIterator::cast(this)->JSMapIteratorPrint(os); 202 break; 203 case JS_WEAK_MAP_TYPE: 204 JSWeakMap::cast(this)->JSWeakMapPrint(os); 205 break; 206 case JS_WEAK_SET_TYPE: 207 JSWeakSet::cast(this)->JSWeakSetPrint(os); 208 break; 209 case JS_MODULE_NAMESPACE_TYPE: 210 JSModuleNamespace::cast(this)->JSModuleNamespacePrint(os); 211 break; 212 case FOREIGN_TYPE: 213 Foreign::cast(this)->ForeignPrint(os); 214 break; 215 case SHARED_FUNCTION_INFO_TYPE: 216 SharedFunctionInfo::cast(this)->SharedFunctionInfoPrint(os); 217 break; 218 case JS_MESSAGE_OBJECT_TYPE: 219 JSMessageObject::cast(this)->JSMessageObjectPrint(os); 220 break; 221 case CELL_TYPE: 222 Cell::cast(this)->CellPrint(os); 223 break; 224 case PROPERTY_CELL_TYPE: 225 PropertyCell::cast(this)->PropertyCellPrint(os); 226 break; 227 case WEAK_CELL_TYPE: 228 WeakCell::cast(this)->WeakCellPrint(os); 229 break; 230 case JS_ARRAY_BUFFER_TYPE: 231 JSArrayBuffer::cast(this)->JSArrayBufferPrint(os); 232 break; 233 case JS_TYPED_ARRAY_TYPE: 234 JSTypedArray::cast(this)->JSTypedArrayPrint(os); 235 break; 236 case JS_DATA_VIEW_TYPE: 237 JSDataView::cast(this)->JSDataViewPrint(os); 238 break; 239 #define MAKE_STRUCT_CASE(NAME, Name, name) \ 240 case NAME##_TYPE: \ 241 Name::cast(this)->Name##Print(os); \ 242 break; 243 STRUCT_LIST(MAKE_STRUCT_CASE) 244 #undef MAKE_STRUCT_CASE 245 246 default: 247 os << "UNKNOWN TYPE " << map()->instance_type(); 248 UNREACHABLE(); 249 break; 250 } 251 } 252 253 void ByteArray::ByteArrayPrint(std::ostream& os) { // NOLINT 254 os << "byte array, data starts at " << GetDataStartAddress(); 255 } 256 257 258 void BytecodeArray::BytecodeArrayPrint(std::ostream& os) { // NOLINT 259 Disassemble(os); 260 } 261 262 263 void FreeSpace::FreeSpacePrint(std::ostream& os) { // NOLINT 264 os << "free space, size " << Size(); 265 } 266 267 268 template <class Traits> 269 void FixedTypedArray<Traits>::FixedTypedArrayPrint( 270 std::ostream& os) { // NOLINT 271 os << "fixed " << Traits::Designator(); 272 } 273 274 bool JSObject::PrintProperties(std::ostream& os) { // NOLINT 275 if (HasFastProperties()) { 276 DescriptorArray* descs = map()->instance_descriptors(); 277 int i = 0; 278 for (; i < map()->NumberOfOwnDescriptors(); i++) { 279 os << "\n "; 280 descs->GetKey(i)->NamePrint(os); 281 os << ": "; 282 PropertyDetails details = descs->GetDetails(i); 283 switch (details.location()) { 284 case kField: { 285 FieldIndex field_index = FieldIndex::ForDescriptor(map(), i); 286 if (IsUnboxedDoubleField(field_index)) { 287 os << "<unboxed double> " << RawFastDoublePropertyAt(field_index); 288 } else { 289 os << Brief(RawFastPropertyAt(field_index)); 290 } 291 break; 292 } 293 case kDescriptor: 294 os << Brief(descs->GetValue(i)); 295 break; 296 } 297 os << " "; 298 details.PrintAsFastTo(os, PropertyDetails::kForProperties); 299 } 300 return i > 0; 301 } else if (IsJSGlobalObject()) { 302 global_dictionary()->Print(os); 303 } else { 304 property_dictionary()->Print(os); 305 } 306 return true; 307 } 308 309 namespace { 310 311 template <class T> 312 bool IsTheHoleAt(T* array, int index) { 313 return false; 314 } 315 316 template <> 317 bool IsTheHoleAt(FixedDoubleArray* array, int index) { 318 return array->is_the_hole(index); 319 } 320 321 template <class T> 322 double GetScalarElement(T* array, int index) { 323 if (IsTheHoleAt(array, index)) { 324 return std::numeric_limits<double>::quiet_NaN(); 325 } 326 return array->get_scalar(index); 327 } 328 329 template <class T> 330 void DoPrintElements(std::ostream& os, Object* object) { // NOLINT 331 const bool print_the_hole = std::is_same<T, FixedDoubleArray>::value; 332 T* array = T::cast(object); 333 if (array->length() == 0) return; 334 int previous_index = 0; 335 double previous_value = GetScalarElement(array, 0); 336 double value = 0.0; 337 int i; 338 for (i = 1; i <= array->length(); i++) { 339 if (i < array->length()) value = GetScalarElement(array, i); 340 bool values_are_nan = std::isnan(previous_value) && std::isnan(value); 341 if (i != array->length() && (previous_value == value || values_are_nan) && 342 IsTheHoleAt(array, i - 1) == IsTheHoleAt(array, i)) { 343 continue; 344 } 345 os << "\n"; 346 std::stringstream ss; 347 ss << previous_index; 348 if (previous_index != i - 1) { 349 ss << '-' << (i - 1); 350 } 351 os << std::setw(12) << ss.str() << ": "; 352 if (print_the_hole && IsTheHoleAt(array, i - 1)) { 353 os << "<the_hole>"; 354 } else { 355 os << previous_value; 356 } 357 previous_index = i; 358 previous_value = value; 359 } 360 } 361 362 void PrintFixedArrayElements(std::ostream& os, FixedArray* array) { 363 // Print in array notation for non-sparse arrays. 364 Object* previous_value = array->length() > 0 ? array->get(0) : nullptr; 365 Object* value = nullptr; 366 int previous_index = 0; 367 int i; 368 for (i = 1; i <= array->length(); i++) { 369 if (i < array->length()) value = array->get(i); 370 if (previous_value == value && i != array->length()) { 371 continue; 372 } 373 os << "\n"; 374 std::stringstream ss; 375 ss << previous_index; 376 if (previous_index != i - 1) { 377 ss << '-' << (i - 1); 378 } 379 os << std::setw(12) << ss.str() << ": " << Brief(previous_value); 380 previous_index = i; 381 previous_value = value; 382 } 383 } 384 385 } // namespace 386 387 bool JSObject::PrintElements(std::ostream& os) { // NOLINT 388 // Don't call GetElementsKind, its validation code can cause the printer to 389 // fail when debugging. 390 if (elements()->length() == 0) return false; 391 switch (map()->elements_kind()) { 392 case FAST_HOLEY_SMI_ELEMENTS: 393 case FAST_SMI_ELEMENTS: 394 case FAST_HOLEY_ELEMENTS: 395 case FAST_ELEMENTS: 396 case FAST_STRING_WRAPPER_ELEMENTS: { 397 PrintFixedArrayElements(os, FixedArray::cast(elements())); 398 break; 399 } 400 case FAST_HOLEY_DOUBLE_ELEMENTS: 401 case FAST_DOUBLE_ELEMENTS: { 402 DoPrintElements<FixedDoubleArray>(os, elements()); 403 break; 404 } 405 406 #define PRINT_ELEMENTS(Type, type, TYPE, elementType, size) \ 407 case TYPE##_ELEMENTS: { \ 408 DoPrintElements<Fixed##Type##Array>(os, elements()); \ 409 break; \ 410 } 411 TYPED_ARRAYS(PRINT_ELEMENTS) 412 #undef PRINT_ELEMENTS 413 414 case DICTIONARY_ELEMENTS: 415 case SLOW_STRING_WRAPPER_ELEMENTS: 416 SeededNumberDictionary::cast(elements())->Print(os); 417 break; 418 case FAST_SLOPPY_ARGUMENTS_ELEMENTS: 419 case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: { 420 FixedArray* p = FixedArray::cast(elements()); 421 os << "\n parameter map:"; 422 for (int i = 2; i < p->length(); i++) { 423 os << " " << (i - 2) << ":" << Brief(p->get(i)); 424 } 425 os << "\n context: " << Brief(p->get(0)) 426 << "\n arguments: " << Brief(p->get(1)); 427 break; 428 } 429 case NO_ELEMENTS: 430 break; 431 } 432 return true; 433 } 434 435 436 static void JSObjectPrintHeader(std::ostream& os, JSObject* obj, 437 const char* id) { // NOLINT 438 obj->PrintHeader(os, id); 439 // Don't call GetElementsKind, its validation code can cause the printer to 440 // fail when debugging. 441 os << "\n - map = " << reinterpret_cast<void*>(obj->map()) << " ["; 442 if (obj->HasFastProperties()) { 443 os << "FastProperties"; 444 } else { 445 os << "DictionaryProperties"; 446 } 447 PrototypeIterator iter(obj->GetIsolate(), obj); 448 os << "]\n - prototype = " << reinterpret_cast<void*>(iter.GetCurrent()); 449 os << "\n - elements = " << Brief(obj->elements()) << " [" 450 << ElementsKindToString(obj->map()->elements_kind()); 451 if (obj->elements()->map() == obj->GetHeap()->fixed_cow_array_map()) { 452 os << " (COW)"; 453 } 454 os << "]"; 455 if (obj->GetInternalFieldCount() > 0) { 456 os << "\n - internal fields: " << obj->GetInternalFieldCount(); 457 } 458 } 459 460 461 static void JSObjectPrintBody(std::ostream& os, JSObject* obj, // NOLINT 462 bool print_elements = true) { 463 os << "\n - properties = " << Brief(obj->properties()) << " {"; 464 if (obj->PrintProperties(os)) os << "\n "; 465 os << "}\n"; 466 if (print_elements && obj->elements()->length() > 0) { 467 os << " - elements = " << Brief(obj->elements()) << " {"; 468 if (obj->PrintElements(os)) os << "\n "; 469 os << "}\n"; 470 } 471 int internal_fields = obj->GetInternalFieldCount(); 472 if (internal_fields > 0) { 473 os << " - internal fields = {"; 474 for (int i = 0; i < internal_fields; i++) { 475 os << "\n " << obj->GetInternalField(i); 476 } 477 os << "\n }\n"; 478 } 479 } 480 481 482 void JSObject::JSObjectPrint(std::ostream& os) { // NOLINT 483 JSObjectPrintHeader(os, this, nullptr); 484 JSObjectPrintBody(os, this); 485 } 486 487 void JSArray::JSArrayPrint(std::ostream& os) { // NOLINT 488 JSObjectPrintHeader(os, this, "JSArray"); 489 os << "\n - length = " << Brief(this->length()); 490 JSObjectPrintBody(os, this); 491 } 492 493 void JSPromise::JSPromisePrint(std::ostream& os) { // NOLINT 494 JSObjectPrintHeader(os, this, "JSPromise"); 495 os << "\n - status = " << JSPromise::Status(status()); 496 os << "\n - result = " << Brief(result()); 497 os << "\n - deferred_promise: " << Brief(deferred_promise()); 498 os << "\n - deferred_on_resolve: " << Brief(deferred_on_resolve()); 499 os << "\n - deferred_on_reject: " << Brief(deferred_on_reject()); 500 os << "\n - fulfill_reactions = " << Brief(fulfill_reactions()); 501 os << "\n - reject_reactions = " << Brief(reject_reactions()); 502 os << "\n - has_handler = " << has_handler(); 503 os << "\n "; 504 } 505 506 void JSRegExp::JSRegExpPrint(std::ostream& os) { // NOLINT 507 JSObjectPrintHeader(os, this, "JSRegExp"); 508 os << "\n - data = " << Brief(data()); 509 JSObjectPrintBody(os, this); 510 } 511 512 513 void Symbol::SymbolPrint(std::ostream& os) { // NOLINT 514 HeapObject::PrintHeader(os, "Symbol"); 515 os << "\n - hash: " << Hash(); 516 os << "\n - name: " << Brief(name()); 517 if (name()->IsUndefined(GetIsolate())) { 518 os << " (" << PrivateSymbolToName() << ")"; 519 } 520 os << "\n - private: " << is_private(); 521 os << "\n"; 522 } 523 524 525 void Map::MapPrint(std::ostream& os) { // NOLINT 526 HeapObject::PrintHeader(os, "Map"); 527 os << "\n - type: " << instance_type(); 528 os << "\n - instance size: " << instance_size(); 529 if (IsJSObjectMap()) { 530 os << "\n - inobject properties: " << GetInObjectProperties(); 531 } 532 os << "\n - elements kind: " << ElementsKindToString(elements_kind()); 533 os << "\n - unused property fields: " << unused_property_fields(); 534 os << "\n - enum length: "; 535 if (EnumLength() == kInvalidEnumCacheSentinel) { 536 os << "invalid"; 537 } else { 538 os << EnumLength(); 539 } 540 if (is_deprecated()) os << "\n - deprecated_map"; 541 if (is_stable()) os << "\n - stable_map"; 542 if (is_migration_target()) os << "\n - migration_target"; 543 if (is_dictionary_map()) os << "\n - dictionary_map"; 544 if (has_hidden_prototype()) os << "\n - has_hidden_prototype"; 545 if (has_named_interceptor()) os << "\n - named_interceptor"; 546 if (has_indexed_interceptor()) os << "\n - indexed_interceptor"; 547 if (is_undetectable()) os << "\n - undetectable"; 548 if (is_callable()) os << "\n - callable"; 549 if (is_constructor()) os << "\n - constructor"; 550 if (is_access_check_needed()) os << "\n - access_check_needed"; 551 if (!is_extensible()) os << "\n - non-extensible"; 552 if (is_prototype_map()) { 553 os << "\n - prototype_map"; 554 os << "\n - prototype info: " << Brief(prototype_info()); 555 } else { 556 os << "\n - back pointer: " << Brief(GetBackPointer()); 557 } 558 os << "\n - instance descriptors " << (owns_descriptors() ? "(own) " : "") 559 << "#" << NumberOfOwnDescriptors() << ": " 560 << Brief(instance_descriptors()); 561 if (FLAG_unbox_double_fields) { 562 os << "\n - layout descriptor: "; 563 layout_descriptor()->ShortPrint(os); 564 } 565 int nof_transitions = TransitionArray::NumberOfTransitions(raw_transitions()); 566 if (nof_transitions > 0) { 567 os << "\n - transitions #" << nof_transitions << ": " 568 << Brief(raw_transitions()); 569 TransitionArray::PrintTransitions(os, raw_transitions(), false); 570 } 571 os << "\n - prototype: " << Brief(prototype()); 572 os << "\n - constructor: " << Brief(GetConstructor()); 573 os << "\n - code cache: " << Brief(code_cache()); 574 os << "\n - dependent code: " << Brief(dependent_code()); 575 os << "\n - construction counter: " << construction_counter(); 576 os << "\n"; 577 } 578 579 580 void TypeFeedbackInfo::TypeFeedbackInfoPrint(std::ostream& os) { // NOLINT 581 HeapObject::PrintHeader(os, "TypeFeedbackInfo"); 582 os << "\n - ic_total_count: " << ic_total_count() 583 << ", ic_with_type_info_count: " << ic_with_type_info_count() 584 << ", ic_generic_count: " << ic_generic_count() << "\n"; 585 } 586 587 588 void AliasedArgumentsEntry::AliasedArgumentsEntryPrint( 589 std::ostream& os) { // NOLINT 590 HeapObject::PrintHeader(os, "AliasedArgumentsEntry"); 591 os << "\n - aliased_context_slot: " << aliased_context_slot(); 592 } 593 594 595 void FixedArray::FixedArrayPrint(std::ostream& os) { // NOLINT 596 HeapObject::PrintHeader(os, "FixedArray"); 597 os << "\n - map = " << Brief(map()); 598 os << "\n - length: " << length(); 599 PrintFixedArrayElements(os, this); 600 os << "\n"; 601 } 602 603 604 void FixedDoubleArray::FixedDoubleArrayPrint(std::ostream& os) { // NOLINT 605 HeapObject::PrintHeader(os, "FixedDoubleArray"); 606 os << "\n - map = " << Brief(map()); 607 os << "\n - length: " << length(); 608 DoPrintElements<FixedDoubleArray>(os, this); 609 os << "\n"; 610 } 611 612 613 void TransitionArray::TransitionArrayPrint(std::ostream& os) { // NOLINT 614 HeapObject::PrintHeader(os, "TransitionArray"); 615 os << "\n - capacity: " << length(); 616 for (int i = 0; i < length(); i++) { 617 os << "\n [" << i << "]: " << Brief(get(i)); 618 if (i == kNextLinkIndex) os << " (next link)"; 619 if (i == kPrototypeTransitionsIndex) os << " (prototype transitions)"; 620 if (i == kTransitionLengthIndex) os << " (number of transitions)"; 621 } 622 os << "\n"; 623 } 624 625 template void FeedbackVectorSpecBase<StaticFeedbackVectorSpec>::Print(); 626 template void FeedbackVectorSpecBase<FeedbackVectorSpec>::Print(); 627 628 template <typename Derived> 629 void FeedbackVectorSpecBase<Derived>::Print() { 630 OFStream os(stdout); 631 FeedbackVectorSpecPrint(os); 632 os << std::flush; 633 } 634 635 template <typename Derived> 636 void FeedbackVectorSpecBase<Derived>::FeedbackVectorSpecPrint( 637 std::ostream& os) { // NOLINT 638 int slot_count = This()->slots(); 639 os << " - slot_count: " << slot_count; 640 if (slot_count == 0) { 641 os << " (empty)\n"; 642 return; 643 } 644 645 for (int slot = 0; slot < slot_count;) { 646 FeedbackSlotKind kind = This()->GetKind(FeedbackSlot(slot)); 647 int entry_size = FeedbackMetadata::GetSlotSize(kind); 648 DCHECK_LT(0, entry_size); 649 os << "\n Slot #" << slot << " " << kind; 650 slot += entry_size; 651 } 652 os << "\n"; 653 } 654 655 void FeedbackMetadata::Print() { 656 OFStream os(stdout); 657 FeedbackMetadataPrint(os); 658 os << std::flush; 659 } 660 661 void FeedbackMetadata::FeedbackMetadataPrint(std::ostream& os) { // NOLINT 662 HeapObject::PrintHeader(os, "FeedbackMetadata"); 663 os << "\n - length: " << length(); 664 if (length() == 0) { 665 os << " (empty)\n"; 666 return; 667 } 668 os << "\n - slot_count: " << slot_count(); 669 670 FeedbackMetadataIterator iter(this); 671 while (iter.HasNext()) { 672 FeedbackSlot slot = iter.Next(); 673 FeedbackSlotKind kind = iter.kind(); 674 os << "\n Slot " << slot << " " << kind; 675 } 676 os << "\n"; 677 } 678 679 void FeedbackVector::Print() { 680 OFStream os(stdout); 681 FeedbackVectorPrint(os); 682 os << std::flush; 683 } 684 685 void FeedbackVector::FeedbackVectorPrint(std::ostream& os) { // NOLINT 686 HeapObject::PrintHeader(os, "FeedbackVector"); 687 os << "\n - length: " << length(); 688 if (length() == 0) { 689 os << " (empty)\n"; 690 return; 691 } 692 693 FeedbackMetadataIterator iter(metadata()); 694 while (iter.HasNext()) { 695 FeedbackSlot slot = iter.Next(); 696 FeedbackSlotKind kind = iter.kind(); 697 698 os << "\n Slot " << slot << " " << kind; 699 os << " "; 700 switch (kind) { 701 case FeedbackSlotKind::kLoadProperty: { 702 LoadICNexus nexus(this, slot); 703 os << Code::ICState2String(nexus.StateFromFeedback()); 704 break; 705 } 706 case FeedbackSlotKind::kLoadGlobalInsideTypeof: 707 case FeedbackSlotKind::kLoadGlobalNotInsideTypeof: { 708 LoadGlobalICNexus nexus(this, slot); 709 os << Code::ICState2String(nexus.StateFromFeedback()); 710 break; 711 } 712 case FeedbackSlotKind::kLoadKeyed: { 713 KeyedLoadICNexus nexus(this, slot); 714 os << Code::ICState2String(nexus.StateFromFeedback()); 715 break; 716 } 717 case FeedbackSlotKind::kCall: { 718 CallICNexus nexus(this, slot); 719 os << Code::ICState2String(nexus.StateFromFeedback()); 720 break; 721 } 722 case FeedbackSlotKind::kStoreNamedSloppy: 723 case FeedbackSlotKind::kStoreNamedStrict: 724 case FeedbackSlotKind::kStoreOwnNamed: { 725 StoreICNexus nexus(this, slot); 726 os << Code::ICState2String(nexus.StateFromFeedback()); 727 break; 728 } 729 case FeedbackSlotKind::kStoreKeyedSloppy: 730 case FeedbackSlotKind::kStoreKeyedStrict: { 731 KeyedStoreICNexus nexus(this, slot); 732 os << Code::ICState2String(nexus.StateFromFeedback()); 733 break; 734 } 735 case FeedbackSlotKind::kBinaryOp: { 736 BinaryOpICNexus nexus(this, slot); 737 os << Code::ICState2String(nexus.StateFromFeedback()); 738 break; 739 } 740 case FeedbackSlotKind::kCompareOp: { 741 CompareICNexus nexus(this, slot); 742 os << Code::ICState2String(nexus.StateFromFeedback()); 743 break; 744 } 745 case FeedbackSlotKind::kStoreDataPropertyInLiteral: { 746 StoreDataPropertyInLiteralICNexus nexus(this, slot); 747 os << Code::ICState2String(nexus.StateFromFeedback()); 748 break; 749 } 750 case FeedbackSlotKind::kCreateClosure: 751 case FeedbackSlotKind::kLiteral: 752 case FeedbackSlotKind::kGeneral: 753 break; 754 case FeedbackSlotKind::kToBoolean: 755 case FeedbackSlotKind::kInvalid: 756 case FeedbackSlotKind::kKindsNumber: 757 UNREACHABLE(); 758 break; 759 } 760 761 int entry_size = iter.entry_size(); 762 for (int i = 0; i < entry_size; i++) { 763 int index = GetIndex(slot) + i; 764 os << "\n [" << index << "]: " << Brief(get(index)); 765 } 766 } 767 os << "\n"; 768 } 769 770 771 void JSValue::JSValuePrint(std::ostream& os) { // NOLINT 772 JSObjectPrintHeader(os, this, "JSValue"); 773 os << "\n - value = " << Brief(value()); 774 JSObjectPrintBody(os, this); 775 } 776 777 778 void JSMessageObject::JSMessageObjectPrint(std::ostream& os) { // NOLINT 779 JSObjectPrintHeader(os, this, "JSMessageObject"); 780 os << "\n - type: " << type(); 781 os << "\n - arguments: " << Brief(argument()); 782 os << "\n - start_position: " << start_position(); 783 os << "\n - end_position: " << end_position(); 784 os << "\n - script: " << Brief(script()); 785 os << "\n - stack_frames: " << Brief(stack_frames()); 786 JSObjectPrintBody(os, this); 787 } 788 789 790 void String::StringPrint(std::ostream& os) { // NOLINT 791 if (StringShape(this).IsInternalized()) { 792 os << "#"; 793 } else if (StringShape(this).IsCons()) { 794 os << "c\""; 795 } else if (StringShape(this).IsThin()) { 796 os << ">\""; 797 } else { 798 os << "\""; 799 } 800 801 const char truncated_epilogue[] = "...<truncated>"; 802 int len = length(); 803 if (!FLAG_use_verbose_printer) { 804 if (len > 100) { 805 len = 100 - sizeof(truncated_epilogue); 806 } 807 } 808 for (int i = 0; i < len; i++) { 809 os << AsUC16(Get(i)); 810 } 811 if (len != length()) { 812 os << truncated_epilogue; 813 } 814 815 if (!StringShape(this).IsInternalized()) os << "\""; 816 } 817 818 819 void Name::NamePrint(std::ostream& os) { // NOLINT 820 if (IsString()) { 821 String::cast(this)->StringPrint(os); 822 } else { 823 os << Brief(this); 824 } 825 } 826 827 828 static const char* const weekdays[] = { 829 "???", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" 830 }; 831 832 833 void JSDate::JSDatePrint(std::ostream& os) { // NOLINT 834 JSObjectPrintHeader(os, this, "JSDate"); 835 os << "\n - value = " << Brief(value()); 836 if (!year()->IsSmi()) { 837 os << "\n - time = NaN\n"; 838 } else { 839 // TODO(svenpanne) Add some basic formatting to our streams. 840 ScopedVector<char> buf(100); 841 SNPrintF( 842 buf, "\n - time = %s %04d/%02d/%02d %02d:%02d:%02d\n", 843 weekdays[weekday()->IsSmi() ? Smi::cast(weekday())->value() + 1 : 0], 844 year()->IsSmi() ? Smi::cast(year())->value() : -1, 845 month()->IsSmi() ? Smi::cast(month())->value() : -1, 846 day()->IsSmi() ? Smi::cast(day())->value() : -1, 847 hour()->IsSmi() ? Smi::cast(hour())->value() : -1, 848 min()->IsSmi() ? Smi::cast(min())->value() : -1, 849 sec()->IsSmi() ? Smi::cast(sec())->value() : -1); 850 os << buf.start(); 851 } 852 JSObjectPrintBody(os, this); 853 } 854 855 856 void JSProxy::JSProxyPrint(std::ostream& os) { // NOLINT 857 HeapObject::PrintHeader(os, "JSProxy"); 858 os << "\n - map = " << reinterpret_cast<void*>(map()); 859 os << "\n - target = "; 860 target()->ShortPrint(os); 861 os << "\n - handler = "; 862 handler()->ShortPrint(os); 863 os << "\n - hash = "; 864 hash()->ShortPrint(os); 865 os << "\n"; 866 } 867 868 869 void JSSet::JSSetPrint(std::ostream& os) { // NOLINT 870 JSObjectPrintHeader(os, this, "JSSet"); 871 os << " - table = " << Brief(table()); 872 JSObjectPrintBody(os, this); 873 } 874 875 876 void JSMap::JSMapPrint(std::ostream& os) { // NOLINT 877 JSObjectPrintHeader(os, this, "JSMap"); 878 os << " - table = " << Brief(table()); 879 JSObjectPrintBody(os, this); 880 } 881 882 883 template <class Derived, class TableType> 884 void 885 OrderedHashTableIterator<Derived, TableType>::OrderedHashTableIteratorPrint( 886 std::ostream& os) { // NOLINT 887 os << "\n - table = " << Brief(table()); 888 os << "\n - index = " << Brief(index()); 889 os << "\n - kind = " << Brief(kind()); 890 os << "\n"; 891 } 892 893 894 template void OrderedHashTableIterator< 895 JSSetIterator, 896 OrderedHashSet>::OrderedHashTableIteratorPrint(std::ostream& os); // NOLINT 897 898 899 template void OrderedHashTableIterator< 900 JSMapIterator, 901 OrderedHashMap>::OrderedHashTableIteratorPrint(std::ostream& os); // NOLINT 902 903 904 void JSSetIterator::JSSetIteratorPrint(std::ostream& os) { // NOLINT 905 JSObjectPrintHeader(os, this, "JSSetIterator"); 906 OrderedHashTableIteratorPrint(os); 907 } 908 909 910 void JSMapIterator::JSMapIteratorPrint(std::ostream& os) { // NOLINT 911 JSObjectPrintHeader(os, this, "JSMapIterator"); 912 OrderedHashTableIteratorPrint(os); 913 } 914 915 916 void JSWeakMap::JSWeakMapPrint(std::ostream& os) { // NOLINT 917 JSObjectPrintHeader(os, this, "JSWeakMap"); 918 os << "\n - table = " << Brief(table()); 919 JSObjectPrintBody(os, this); 920 } 921 922 923 void JSWeakSet::JSWeakSetPrint(std::ostream& os) { // NOLINT 924 JSObjectPrintHeader(os, this, "JSWeakSet"); 925 os << "\n - table = " << Brief(table()); 926 JSObjectPrintBody(os, this); 927 } 928 929 930 void JSArrayBuffer::JSArrayBufferPrint(std::ostream& os) { // NOLINT 931 JSObjectPrintHeader(os, this, "JSArrayBuffer"); 932 os << "\n - backing_store = " << backing_store(); 933 os << "\n - byte_length = " << Brief(byte_length()); 934 if (was_neutered()) os << "\n - neutered"; 935 JSObjectPrintBody(os, this, !was_neutered()); 936 } 937 938 939 void JSTypedArray::JSTypedArrayPrint(std::ostream& os) { // NOLINT 940 JSObjectPrintHeader(os, this, "JSTypedArray"); 941 os << "\n - buffer = " << Brief(buffer()); 942 os << "\n - byte_offset = " << Brief(byte_offset()); 943 os << "\n - byte_length = " << Brief(byte_length()); 944 os << "\n - length = " << Brief(length()); 945 if (WasNeutered()) os << "\n - neutered"; 946 JSObjectPrintBody(os, this, !WasNeutered()); 947 } 948 949 void JSArrayIterator::JSArrayIteratorPrint(std::ostream& os) { // NOLING 950 JSObjectPrintHeader(os, this, "JSArrayIterator"); 951 952 InstanceType instance_type = map()->instance_type(); 953 std::string type; 954 if (instance_type <= LAST_ARRAY_KEY_ITERATOR_TYPE) { 955 type = "keys"; 956 } else if (instance_type <= LAST_ARRAY_KEY_VALUE_ITERATOR_TYPE) { 957 type = "entries"; 958 } else { 959 type = "values"; 960 } 961 962 os << "\n - type = " << type; 963 os << "\n - object = " << Brief(object()); 964 os << "\n - index = " << Brief(index()); 965 966 JSObjectPrintBody(os, this); 967 } 968 969 void JSDataView::JSDataViewPrint(std::ostream& os) { // NOLINT 970 JSObjectPrintHeader(os, this, "JSDataView"); 971 os << "\n - buffer =" << Brief(buffer()); 972 os << "\n - byte_offset = " << Brief(byte_offset()); 973 os << "\n - byte_length = " << Brief(byte_length()); 974 if (WasNeutered()) os << "\n - neutered"; 975 JSObjectPrintBody(os, this, !WasNeutered()); 976 } 977 978 979 void JSBoundFunction::JSBoundFunctionPrint(std::ostream& os) { // NOLINT 980 JSObjectPrintHeader(os, this, "JSBoundFunction"); 981 os << "\n - bound_target_function = " << Brief(bound_target_function()); 982 os << "\n - bound_this = " << Brief(bound_this()); 983 os << "\n - bound_arguments = " << Brief(bound_arguments()); 984 JSObjectPrintBody(os, this); 985 } 986 987 988 void JSFunction::JSFunctionPrint(std::ostream& os) { // NOLINT 989 JSObjectPrintHeader(os, this, "Function"); 990 os << "\n - initial_map = "; 991 if (has_initial_map()) os << Brief(initial_map()); 992 os << "\n - shared_info = " << Brief(shared()); 993 os << "\n - name = " << Brief(shared()->name()); 994 os << "\n - formal_parameter_count = " 995 << shared()->internal_formal_parameter_count(); 996 if (IsGeneratorFunction(shared()->kind())) { 997 os << "\n - generator"; 998 } else if (IsAsyncFunction(shared()->kind())) { 999 os << "\n - async"; 1000 } 1001 os << "\n - context = " << Brief(context()); 1002 os << "\n - feedback vector cell = " << Brief(feedback_vector_cell()); 1003 os << "\n - code = " << Brief(code()); 1004 JSObjectPrintBody(os, this); 1005 } 1006 1007 namespace { 1008 1009 std::ostream& operator<<(std::ostream& os, FunctionKind kind) { 1010 os << "["; 1011 if (kind == FunctionKind::kNormalFunction) { 1012 os << " NormalFunction"; 1013 } else { 1014 #define PRINT_FLAG(name) \ 1015 if (static_cast<int>(kind) & static_cast<int>(FunctionKind::k##name)) { \ 1016 os << " " << #name; \ 1017 } 1018 1019 PRINT_FLAG(ArrowFunction) 1020 PRINT_FLAG(GeneratorFunction) 1021 PRINT_FLAG(ConciseMethod) 1022 PRINT_FLAG(DefaultConstructor) 1023 PRINT_FLAG(DerivedConstructor) 1024 PRINT_FLAG(BaseConstructor) 1025 PRINT_FLAG(GetterFunction) 1026 PRINT_FLAG(SetterFunction) 1027 PRINT_FLAG(AsyncFunction) 1028 PRINT_FLAG(Module) 1029 #undef PRINT_FLAG 1030 } 1031 return os << " ]"; 1032 } 1033 1034 } // namespace 1035 1036 void SharedFunctionInfo::SharedFunctionInfoPrint(std::ostream& os) { // NOLINT 1037 HeapObject::PrintHeader(os, "SharedFunctionInfo"); 1038 os << "\n - name = " << Brief(name()); 1039 os << "\n - kind = " << kind(); 1040 os << "\n - formal_parameter_count = " << internal_formal_parameter_count(); 1041 os << "\n - expected_nof_properties = " << expected_nof_properties(); 1042 os << "\n - language_mode = " << language_mode(); 1043 os << "\n - ast_node_count = " << ast_node_count(); 1044 os << "\n - instance class name = "; 1045 instance_class_name()->Print(os); 1046 os << "\n - code = " << Brief(code()); 1047 if (HasSourceCode()) { 1048 os << "\n - source code = "; 1049 String* source = String::cast(Script::cast(script())->source()); 1050 int start = start_position(); 1051 int length = end_position() - start; 1052 std::unique_ptr<char[]> source_string = source->ToCString( 1053 DISALLOW_NULLS, FAST_STRING_TRAVERSAL, start, length, NULL); 1054 os << source_string.get(); 1055 } 1056 // Script files are often large, hard to read. 1057 // os << "\n - script ="; 1058 // script()->Print(os); 1059 if (is_named_expression()) { 1060 os << "\n - named expression"; 1061 } else if (is_anonymous_expression()) { 1062 os << "\n - anonymous expression"; 1063 } else if (is_declaration()) { 1064 os << "\n - declaration"; 1065 } 1066 os << "\n - function token position = " << function_token_position(); 1067 os << "\n - start position = " << start_position(); 1068 os << "\n - end position = " << end_position(); 1069 if (HasDebugInfo()) { 1070 os << "\n - debug info = " << Brief(debug_info()); 1071 } else { 1072 os << "\n - no debug info"; 1073 } 1074 os << "\n - length = " << length(); 1075 os << "\n - optimized_code_map = " << Brief(optimized_code_map()); 1076 os << "\n - feedback_metadata = "; 1077 feedback_metadata()->FeedbackMetadataPrint(os); 1078 if (HasBytecodeArray()) { 1079 os << "\n - bytecode_array = " << bytecode_array(); 1080 } 1081 os << "\n"; 1082 } 1083 1084 1085 void JSGlobalProxy::JSGlobalProxyPrint(std::ostream& os) { // NOLINT 1086 JSObjectPrintHeader(os, this, "JSGlobalProxy"); 1087 if (!GetIsolate()->bootstrapper()->IsActive()) { 1088 os << "\n - native context = " << Brief(native_context()); 1089 } 1090 os << "\n - hash = " << Brief(hash()); 1091 JSObjectPrintBody(os, this); 1092 } 1093 1094 1095 void JSGlobalObject::JSGlobalObjectPrint(std::ostream& os) { // NOLINT 1096 JSObjectPrintHeader(os, this, "JSGlobalObject"); 1097 if (!GetIsolate()->bootstrapper()->IsActive()) { 1098 os << "\n - native context = " << Brief(native_context()); 1099 } 1100 os << "\n - global proxy = " << Brief(global_proxy()); 1101 JSObjectPrintBody(os, this); 1102 } 1103 1104 1105 void Cell::CellPrint(std::ostream& os) { // NOLINT 1106 HeapObject::PrintHeader(os, "Cell"); 1107 os << "\n - value: " << Brief(value()); 1108 os << "\n"; 1109 } 1110 1111 1112 void PropertyCell::PropertyCellPrint(std::ostream& os) { // NOLINT 1113 HeapObject::PrintHeader(os, "PropertyCell"); 1114 os << "\n - value: " << Brief(value()); 1115 os << "\n - details: "; 1116 property_details().PrintAsSlowTo(os); 1117 PropertyCellType cell_type = property_details().cell_type(); 1118 os << "\n - cell_type: "; 1119 if (value()->IsTheHole(GetIsolate())) { 1120 switch (cell_type) { 1121 case PropertyCellType::kUninitialized: 1122 os << "Uninitialized"; 1123 break; 1124 case PropertyCellType::kInvalidated: 1125 os << "Invalidated"; 1126 break; 1127 default: 1128 os << "??? " << static_cast<int>(cell_type); 1129 break; 1130 } 1131 } else { 1132 switch (cell_type) { 1133 case PropertyCellType::kUndefined: 1134 os << "Undefined"; 1135 break; 1136 case PropertyCellType::kConstant: 1137 os << "Constant"; 1138 break; 1139 case PropertyCellType::kConstantType: 1140 os << "ConstantType" 1141 << " ("; 1142 switch (GetConstantType()) { 1143 case PropertyCellConstantType::kSmi: 1144 os << "Smi"; 1145 break; 1146 case PropertyCellConstantType::kStableMap: 1147 os << "StableMap"; 1148 break; 1149 } 1150 os << ")"; 1151 break; 1152 case PropertyCellType::kMutable: 1153 os << "Mutable"; 1154 break; 1155 } 1156 } 1157 os << "\n"; 1158 } 1159 1160 1161 void WeakCell::WeakCellPrint(std::ostream& os) { // NOLINT 1162 HeapObject::PrintHeader(os, "WeakCell"); 1163 if (cleared()) { 1164 os << "\n - cleared"; 1165 } else { 1166 os << "\n - value: " << Brief(value()); 1167 } 1168 os << "\n"; 1169 } 1170 1171 1172 void Code::CodePrint(std::ostream& os) { // NOLINT 1173 HeapObject::PrintHeader(os, "Code"); 1174 os << "\n"; 1175 #ifdef ENABLE_DISASSEMBLER 1176 if (FLAG_use_verbose_printer) { 1177 Disassemble(NULL, os); 1178 } 1179 #endif 1180 } 1181 1182 1183 void Foreign::ForeignPrint(std::ostream& os) { // NOLINT 1184 os << "foreign address : " << foreign_address(); 1185 os << "\n"; 1186 } 1187 1188 1189 void AccessorInfo::AccessorInfoPrint(std::ostream& os) { // NOLINT 1190 HeapObject::PrintHeader(os, "AccessorInfo"); 1191 os << "\n - name: " << Brief(name()); 1192 os << "\n - flag: " << flag(); 1193 os << "\n - getter: " << Brief(getter()); 1194 os << "\n - setter: " << Brief(setter()); 1195 os << "\n - js_getter: " << Brief(js_getter()); 1196 os << "\n - data: " << Brief(data()); 1197 os << "\n"; 1198 } 1199 1200 1201 void PromiseResolveThenableJobInfo::PromiseResolveThenableJobInfoPrint( 1202 std::ostream& os) { // NOLINT 1203 HeapObject::PrintHeader(os, "PromiseResolveThenableJobInfo"); 1204 os << "\n - thenable: " << Brief(thenable()); 1205 os << "\n - then: " << Brief(then()); 1206 os << "\n - resolve: " << Brief(resolve()); 1207 os << "\n - reject: " << Brief(reject()); 1208 os << "\n - context: " << Brief(context()); 1209 os << "\n"; 1210 } 1211 1212 void PromiseReactionJobInfo::PromiseReactionJobInfoPrint( 1213 std::ostream& os) { // NOLINT 1214 HeapObject::PrintHeader(os, "PromiseReactionJobInfo"); 1215 os << "\n - value: " << Brief(value()); 1216 os << "\n - tasks: " << Brief(tasks()); 1217 os << "\n - deferred_promise: " << Brief(deferred_promise()); 1218 os << "\n - deferred_on_resolve: " << Brief(deferred_on_resolve()); 1219 os << "\n - deferred_on_reject: " << Brief(deferred_on_reject()); 1220 os << "\n - reaction context: " << Brief(context()); 1221 os << "\n"; 1222 } 1223 1224 void ModuleInfoEntry::ModuleInfoEntryPrint(std::ostream& os) { // NOLINT 1225 HeapObject::PrintHeader(os, "ModuleInfoEntry"); 1226 os << "\n - export_name: " << Brief(export_name()); 1227 os << "\n - local_name: " << Brief(local_name()); 1228 os << "\n - import_name: " << Brief(import_name()); 1229 os << "\n - module_request: " << module_request(); 1230 os << "\n - cell_index: " << cell_index(); 1231 os << "\n - beg_pos: " << beg_pos(); 1232 os << "\n - end_pos: " << end_pos(); 1233 os << "\n"; 1234 } 1235 1236 void Module::ModulePrint(std::ostream& os) { // NOLINT 1237 HeapObject::PrintHeader(os, "Module"); 1238 // TODO(neis): Simplify once modules have a script field. 1239 if (!evaluated()) { 1240 SharedFunctionInfo* shared = code()->IsSharedFunctionInfo() 1241 ? SharedFunctionInfo::cast(code()) 1242 : JSFunction::cast(code())->shared(); 1243 Object* origin = Script::cast(shared->script())->GetNameOrSourceURL(); 1244 os << "\n - origin: " << Brief(origin); 1245 } 1246 os << "\n - code: " << Brief(code()); 1247 os << "\n - exports: " << Brief(exports()); 1248 os << "\n - requested_modules: " << Brief(requested_modules()); 1249 os << "\n - instantiated, evaluated: " << instantiated() << ", " 1250 << evaluated(); 1251 os << "\n"; 1252 } 1253 1254 void JSModuleNamespace::JSModuleNamespacePrint(std::ostream& os) { // NOLINT 1255 JSObjectPrintHeader(os, this, "JSModuleNamespace"); 1256 os << "\n - module: " << Brief(module()); 1257 JSObjectPrintBody(os, this); 1258 } 1259 1260 void PrototypeInfo::PrototypeInfoPrint(std::ostream& os) { // NOLINT 1261 HeapObject::PrintHeader(os, "PrototypeInfo"); 1262 os << "\n - weak cell: " << Brief(weak_cell()); 1263 os << "\n - prototype users: " << Brief(prototype_users()); 1264 os << "\n - registry slot: " << registry_slot(); 1265 os << "\n - validity cell: " << Brief(validity_cell()); 1266 os << "\n - object create map: " << Brief(object_create_map()); 1267 os << "\n"; 1268 } 1269 1270 void Tuple2::Tuple2Print(std::ostream& os) { // NOLINT 1271 HeapObject::PrintHeader(os, "Tuple2"); 1272 os << "\n - value1: " << Brief(value1()); 1273 os << "\n - value2: " << Brief(value2()); 1274 os << "\n"; 1275 } 1276 1277 void Tuple3::Tuple3Print(std::ostream& os) { // NOLINT 1278 HeapObject::PrintHeader(os, "Tuple3"); 1279 os << "\n - value1: " << Brief(value1()); 1280 os << "\n - value2: " << Brief(value2()); 1281 os << "\n - value3: " << Brief(value3()); 1282 os << "\n"; 1283 } 1284 1285 void ContextExtension::ContextExtensionPrint(std::ostream& os) { // NOLINT 1286 HeapObject::PrintHeader(os, "ContextExtension"); 1287 os << "\n - scope_info: " << Brief(scope_info()); 1288 os << "\n - extension: " << Brief(extension()); 1289 os << "\n"; 1290 } 1291 1292 void ConstantElementsPair::ConstantElementsPairPrint( 1293 std::ostream& os) { // NOLINT 1294 HeapObject::PrintHeader(os, "ConstantElementsPair"); 1295 os << "\n - elements_kind: " << static_cast<ElementsKind>(elements_kind()); 1296 os << "\n - constant_values: " << Brief(constant_values()); 1297 os << "\n"; 1298 } 1299 1300 void AccessorPair::AccessorPairPrint(std::ostream& os) { // NOLINT 1301 HeapObject::PrintHeader(os, "AccessorPair"); 1302 os << "\n - getter: " << Brief(getter()); 1303 os << "\n - setter: " << Brief(setter()); 1304 os << "\n"; 1305 } 1306 1307 1308 void AccessCheckInfo::AccessCheckInfoPrint(std::ostream& os) { // NOLINT 1309 HeapObject::PrintHeader(os, "AccessCheckInfo"); 1310 os << "\n - callback: " << Brief(callback()); 1311 os << "\n - named_interceptor: " << Brief(named_interceptor()); 1312 os << "\n - indexed_interceptor: " << Brief(indexed_interceptor()); 1313 os << "\n - data: " << Brief(data()); 1314 os << "\n"; 1315 } 1316 1317 1318 void InterceptorInfo::InterceptorInfoPrint(std::ostream& os) { // NOLINT 1319 HeapObject::PrintHeader(os, "InterceptorInfo"); 1320 os << "\n - getter: " << Brief(getter()); 1321 os << "\n - setter: " << Brief(setter()); 1322 os << "\n - query: " << Brief(query()); 1323 os << "\n - deleter: " << Brief(deleter()); 1324 os << "\n - enumerator: " << Brief(enumerator()); 1325 os << "\n - data: " << Brief(data()); 1326 os << "\n"; 1327 } 1328 1329 1330 void CallHandlerInfo::CallHandlerInfoPrint(std::ostream& os) { // NOLINT 1331 HeapObject::PrintHeader(os, "CallHandlerInfo"); 1332 os << "\n - callback: " << Brief(callback()); 1333 os << "\n - data: " << Brief(data()); 1334 os << "\n"; 1335 } 1336 1337 1338 void FunctionTemplateInfo::FunctionTemplateInfoPrint( 1339 std::ostream& os) { // NOLINT 1340 HeapObject::PrintHeader(os, "FunctionTemplateInfo"); 1341 os << "\n - class name: " << Brief(class_name()); 1342 os << "\n - tag: " << Brief(tag()); 1343 os << "\n - serial_number: " << Brief(serial_number()); 1344 os << "\n - property_list: " << Brief(property_list()); 1345 os << "\n - call_code: " << Brief(call_code()); 1346 os << "\n - property_accessors: " << Brief(property_accessors()); 1347 os << "\n - prototype_template: " << Brief(prototype_template()); 1348 os << "\n - parent_template: " << Brief(parent_template()); 1349 os << "\n - named_property_handler: " << Brief(named_property_handler()); 1350 os << "\n - indexed_property_handler: " << Brief(indexed_property_handler()); 1351 os << "\n - instance_template: " << Brief(instance_template()); 1352 os << "\n - signature: " << Brief(signature()); 1353 os << "\n - access_check_info: " << Brief(access_check_info()); 1354 os << "\n - cached_property_name: " << Brief(cached_property_name()); 1355 os << "\n - hidden_prototype: " << (hidden_prototype() ? "true" : "false"); 1356 os << "\n - undetectable: " << (undetectable() ? "true" : "false"); 1357 os << "\n - need_access_check: " << (needs_access_check() ? "true" : "false"); 1358 os << "\n - instantiated: " << (instantiated() ? "true" : "false"); 1359 os << "\n"; 1360 } 1361 1362 1363 void ObjectTemplateInfo::ObjectTemplateInfoPrint(std::ostream& os) { // NOLINT 1364 HeapObject::PrintHeader(os, "ObjectTemplateInfo"); 1365 os << "\n - tag: " << Brief(tag()); 1366 os << "\n - serial_number: " << Brief(serial_number()); 1367 os << "\n - property_list: " << Brief(property_list()); 1368 os << "\n - property_accessors: " << Brief(property_accessors()); 1369 os << "\n - constructor: " << Brief(constructor()); 1370 os << "\n - internal_field_count: " << internal_field_count(); 1371 os << "\n - immutable_proto: " << (immutable_proto() ? "true" : "false"); 1372 os << "\n"; 1373 } 1374 1375 1376 void AllocationSite::AllocationSitePrint(std::ostream& os) { // NOLINT 1377 HeapObject::PrintHeader(os, "AllocationSite"); 1378 os << "\n - weak_next: " << Brief(weak_next()); 1379 os << "\n - dependent code: " << Brief(dependent_code()); 1380 os << "\n - nested site: " << Brief(nested_site()); 1381 os << "\n - memento found count: " 1382 << Brief(Smi::FromInt(memento_found_count())); 1383 os << "\n - memento create count: " 1384 << Brief(Smi::FromInt(memento_create_count())); 1385 os << "\n - pretenure decision: " 1386 << Brief(Smi::FromInt(pretenure_decision())); 1387 os << "\n - transition_info: "; 1388 if (transition_info()->IsSmi()) { 1389 ElementsKind kind = GetElementsKind(); 1390 os << "Array allocation with ElementsKind " << ElementsKindToString(kind); 1391 } else if (transition_info()->IsJSArray()) { 1392 os << "Array literal " << Brief(transition_info()); 1393 } else { 1394 os << "unknown transition_info " << Brief(transition_info()); 1395 } 1396 os << "\n"; 1397 } 1398 1399 1400 void AllocationMemento::AllocationMementoPrint(std::ostream& os) { // NOLINT 1401 HeapObject::PrintHeader(os, "AllocationMemento"); 1402 os << "\n - allocation site: "; 1403 if (IsValid()) { 1404 GetAllocationSite()->Print(os); 1405 } else { 1406 os << "<invalid>\n"; 1407 } 1408 } 1409 1410 1411 void Script::ScriptPrint(std::ostream& os) { // NOLINT 1412 HeapObject::PrintHeader(os, "Script"); 1413 os << "\n - source: " << Brief(source()); 1414 os << "\n - name: " << Brief(name()); 1415 os << "\n - line_offset: " << line_offset(); 1416 os << "\n - column_offset: " << column_offset(); 1417 os << "\n - type: " << type(); 1418 os << "\n - id: " << id(); 1419 os << "\n - context data: " << Brief(context_data()); 1420 os << "\n - wrapper: " << Brief(wrapper()); 1421 os << "\n - compilation type: " << compilation_type(); 1422 os << "\n - line ends: " << Brief(line_ends()); 1423 os << "\n - eval from shared: " << Brief(eval_from_shared()); 1424 os << "\n - eval from position: " << eval_from_position(); 1425 os << "\n - shared function infos: " << Brief(shared_function_infos()); 1426 os << "\n"; 1427 } 1428 1429 1430 void DebugInfo::DebugInfoPrint(std::ostream& os) { // NOLINT 1431 HeapObject::PrintHeader(os, "DebugInfo"); 1432 os << "\n - shared: " << Brief(shared()); 1433 os << "\n - debug bytecode array: " << Brief(debug_bytecode_array()); 1434 os << "\n - break_points: "; 1435 break_points()->Print(os); 1436 } 1437 1438 1439 void BreakPointInfo::BreakPointInfoPrint(std::ostream& os) { // NOLINT 1440 HeapObject::PrintHeader(os, "BreakPointInfo"); 1441 os << "\n - source_position: " << source_position(); 1442 os << "\n - break_point_objects: " << Brief(break_point_objects()); 1443 os << "\n"; 1444 } 1445 1446 1447 static void PrintBitMask(std::ostream& os, uint32_t value) { // NOLINT 1448 for (int i = 0; i < 32; i++) { 1449 if ((i & 7) == 0) os << " "; 1450 os << (((value & 1) == 0) ? "_" : "x"); 1451 value >>= 1; 1452 } 1453 } 1454 1455 1456 void LayoutDescriptor::Print() { 1457 OFStream os(stdout); 1458 this->Print(os); 1459 os << std::flush; 1460 } 1461 1462 void LayoutDescriptor::ShortPrint(std::ostream& os) { 1463 if (IsSmi()) { 1464 os << this; // Print tagged value for easy use with "jld" gdb macro. 1465 } else { 1466 os << Brief(this); 1467 } 1468 } 1469 1470 void LayoutDescriptor::Print(std::ostream& os) { // NOLINT 1471 os << "Layout descriptor: "; 1472 if (IsFastPointerLayout()) { 1473 os << "<all tagged>"; 1474 } else if (IsSmi()) { 1475 os << "fast"; 1476 PrintBitMask(os, static_cast<uint32_t>(Smi::cast(this)->value())); 1477 } else if (IsOddball() && 1478 IsUninitialized(HeapObject::cast(this)->GetIsolate())) { 1479 os << "<uninitialized>"; 1480 } else { 1481 os << "slow"; 1482 int len = length(); 1483 for (int i = 0; i < len; i++) { 1484 if (i > 0) os << " |"; 1485 PrintBitMask(os, get_scalar(i)); 1486 } 1487 } 1488 os << "\n"; 1489 } 1490 1491 1492 #endif // OBJECT_PRINT 1493 1494 1495 #if TRACE_MAPS 1496 1497 1498 void Name::NameShortPrint() { 1499 if (this->IsString()) { 1500 PrintF("%s", String::cast(this)->ToCString().get()); 1501 } else { 1502 DCHECK(this->IsSymbol()); 1503 Symbol* s = Symbol::cast(this); 1504 if (s->name()->IsUndefined(GetIsolate())) { 1505 PrintF("#<%s>", s->PrivateSymbolToName()); 1506 } else { 1507 PrintF("<%s>", String::cast(s->name())->ToCString().get()); 1508 } 1509 } 1510 } 1511 1512 1513 int Name::NameShortPrint(Vector<char> str) { 1514 if (this->IsString()) { 1515 return SNPrintF(str, "%s", String::cast(this)->ToCString().get()); 1516 } else { 1517 DCHECK(this->IsSymbol()); 1518 Symbol* s = Symbol::cast(this); 1519 if (s->name()->IsUndefined(GetIsolate())) { 1520 return SNPrintF(str, "#<%s>", s->PrivateSymbolToName()); 1521 } else { 1522 return SNPrintF(str, "<%s>", String::cast(s->name())->ToCString().get()); 1523 } 1524 } 1525 } 1526 1527 1528 #endif // TRACE_MAPS 1529 1530 1531 #if defined(DEBUG) || defined(OBJECT_PRINT) 1532 // This method is only meant to be called from gdb for debugging purposes. 1533 // Since the string can also be in two-byte encoding, non-Latin1 characters 1534 // will be ignored in the output. 1535 char* String::ToAsciiArray() { 1536 // Static so that subsequent calls frees previously allocated space. 1537 // This also means that previous results will be overwritten. 1538 static char* buffer = NULL; 1539 if (buffer != NULL) delete[] buffer; 1540 buffer = new char[length() + 1]; 1541 WriteToFlat(this, reinterpret_cast<uint8_t*>(buffer), 0, length()); 1542 buffer[length()] = 0; 1543 return buffer; 1544 } 1545 1546 1547 void DescriptorArray::Print() { 1548 OFStream os(stdout); 1549 this->PrintDescriptors(os); 1550 os << std::flush; 1551 } 1552 1553 1554 void DescriptorArray::PrintDescriptors(std::ostream& os) { // NOLINT 1555 HandleScope scope(GetIsolate()); 1556 os << "Descriptor array #" << number_of_descriptors() << ":"; 1557 for (int i = 0; i < number_of_descriptors(); i++) { 1558 Name* key = GetKey(i); 1559 os << "\n [" << i << "]: "; 1560 #ifdef OBJECT_PRINT 1561 key->NamePrint(os); 1562 #else 1563 key->ShortPrint(os); 1564 #endif 1565 os << " "; 1566 PrintDescriptorDetails(os, i, PropertyDetails::kPrintFull); 1567 } 1568 os << "\n"; 1569 } 1570 1571 void DescriptorArray::PrintDescriptorDetails(std::ostream& os, int descriptor, 1572 PropertyDetails::PrintMode mode) { 1573 PropertyDetails details = GetDetails(descriptor); 1574 details.PrintAsFastTo(os, mode); 1575 os << " @ "; 1576 Object* value = GetValue(descriptor); 1577 switch (details.location()) { 1578 case kField: { 1579 FieldType* field_type = Map::UnwrapFieldType(value); 1580 field_type->PrintTo(os); 1581 break; 1582 } 1583 case kDescriptor: 1584 os << Brief(value); 1585 if (value->IsAccessorPair()) { 1586 AccessorPair* pair = AccessorPair::cast(value); 1587 os << "(get: " << Brief(pair->getter()) 1588 << ", set: " << Brief(pair->setter()) << ")"; 1589 } 1590 break; 1591 } 1592 } 1593 1594 void TransitionArray::Print() { 1595 OFStream os(stdout); 1596 TransitionArray::PrintTransitions(os, this); 1597 os << "\n" << std::flush; 1598 } 1599 1600 1601 void TransitionArray::PrintTransitions(std::ostream& os, Object* transitions, 1602 bool print_header) { // NOLINT 1603 int num_transitions = NumberOfTransitions(transitions); 1604 if (print_header) { 1605 os << "Transition array #" << num_transitions << ":"; 1606 } 1607 for (int i = 0; i < num_transitions; i++) { 1608 Name* key = GetKey(transitions, i); 1609 Map* target = GetTarget(transitions, i); 1610 os << "\n "; 1611 #ifdef OBJECT_PRINT 1612 key->NamePrint(os); 1613 #else 1614 key->ShortPrint(os); 1615 #endif 1616 os << ": "; 1617 Heap* heap = key->GetHeap(); 1618 if (key == heap->nonextensible_symbol()) { 1619 os << "(transition to non-extensible)"; 1620 } else if (key == heap->sealed_symbol()) { 1621 os << "(transition to sealed)"; 1622 } else if (key == heap->frozen_symbol()) { 1623 os << "(transition to frozen)"; 1624 } else if (key == heap->elements_transition_symbol()) { 1625 os << "(transition to " << ElementsKindToString(target->elements_kind()) 1626 << ")"; 1627 } else if (key == heap->strict_function_transition_symbol()) { 1628 os << " (transition to strict function)"; 1629 } else { 1630 DCHECK(!IsSpecialTransition(key)); 1631 os << "(transition to "; 1632 int descriptor = target->LastAdded(); 1633 DescriptorArray* descriptors = target->instance_descriptors(); 1634 descriptors->PrintDescriptorDetails(os, descriptor, 1635 PropertyDetails::kForTransitions); 1636 os << ")"; 1637 } 1638 os << " -> " << Brief(target); 1639 } 1640 } 1641 1642 1643 void JSObject::PrintTransitions(std::ostream& os) { // NOLINT 1644 Object* transitions = map()->raw_transitions(); 1645 int num_transitions = TransitionArray::NumberOfTransitions(transitions); 1646 if (num_transitions == 0) return; 1647 os << "\n - transitions"; 1648 TransitionArray::PrintTransitions(os, transitions, false); 1649 } 1650 #endif // defined(DEBUG) || defined(OBJECT_PRINT) 1651 } // namespace internal 1652 } // namespace v8 1653 1654 // 1655 // The following functions are used by our gdb macros. 1656 // 1657 extern void _v8_internal_Print_Object(void* object) { 1658 reinterpret_cast<i::Object*>(object)->Print(); 1659 } 1660 1661 extern void _v8_internal_Print_Code(void* object) { 1662 i::Isolate* isolate = i::Isolate::Current(); 1663 isolate->FindCodeObject(reinterpret_cast<i::Address>(object))->Print(); 1664 } 1665 1666 extern void _v8_internal_Print_FeedbackMetadata(void* object) { 1667 if (reinterpret_cast<i::Object*>(object)->IsSmi()) { 1668 printf("Not a feedback metadata object\n"); 1669 } else { 1670 reinterpret_cast<i::FeedbackMetadata*>(object)->Print(); 1671 } 1672 } 1673 1674 extern void _v8_internal_Print_FeedbackVector(void* object) { 1675 if (reinterpret_cast<i::Object*>(object)->IsSmi()) { 1676 printf("Not a feedback vector\n"); 1677 } else { 1678 reinterpret_cast<i::FeedbackVector*>(object)->Print(); 1679 } 1680 } 1681 1682 extern void _v8_internal_Print_DescriptorArray(void* object) { 1683 if (reinterpret_cast<i::Object*>(object)->IsSmi()) { 1684 printf("Not a descriptor array\n"); 1685 } else { 1686 reinterpret_cast<i::DescriptorArray*>(object)->Print(); 1687 } 1688 } 1689 1690 extern void _v8_internal_Print_LayoutDescriptor(void* object) { 1691 i::Object* o = reinterpret_cast<i::Object*>(object); 1692 if (!o->IsLayoutDescriptor()) { 1693 printf("Not a layout descriptor\n"); 1694 } else { 1695 reinterpret_cast<i::LayoutDescriptor*>(object)->Print(); 1696 } 1697 } 1698 1699 extern void _v8_internal_Print_TransitionArray(void* object) { 1700 if (reinterpret_cast<i::Object*>(object)->IsSmi()) { 1701 printf("Not a transition array\n"); 1702 } else { 1703 reinterpret_cast<i::TransitionArray*>(object)->Print(); 1704 } 1705 } 1706 1707 extern void _v8_internal_Print_StackTrace() { 1708 i::Isolate* isolate = i::Isolate::Current(); 1709 isolate->PrintStack(stdout); 1710 } 1711