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