objects-printer.cc 90.8 KB
Newer Older
1
// Copyright 2012 the V8 project authors. All rights reserved.
2 3
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
4

5
#include "src/objects/objects.h"
6

7
#include <iomanip>
8 9
#include <memory>

10 11
#include "src/diagnostics/disasm.h"
#include "src/diagnostics/disassembler.h"
12 13
#include "src/heap/heap-inl.h"                // For InOldSpace.
#include "src/heap/heap-write-barrier-inl.h"  // For GetIsolateFromWritableObj.
14
#include "src/init/bootstrapper.h"
15
#include "src/interpreter/bytecodes.h"
16
#include "src/objects/arguments-inl.h"
17
#include "src/objects/cell-inl.h"
18
#include "src/objects/data-handler-inl.h"
19
#include "src/objects/debug-objects-inl.h"
20
#include "src/objects/embedder-data-array-inl.h"
21
#include "src/objects/embedder-data-slot-inl.h"
22
#include "src/objects/feedback-cell-inl.h"
23
#include "src/objects/foreign-inl.h"
24
#include "src/objects/free-space-inl.h"
25
#include "src/objects/hash-table-inl.h"
26
#include "src/objects/heap-number-inl.h"
27 28
#include "src/objects/js-array-buffer-inl.h"
#include "src/objects/js-array-inl.h"
29
#include "src/objects/objects-inl.h"
30
#include "src/snapshot/embedded/embedded-data.h"
31
#ifdef V8_INTL_SUPPORT
32
#include "src/objects/js-break-iterator-inl.h"
33 34
#include "src/objects/js-collator-inl.h"
#endif  // V8_INTL_SUPPORT
35
#include "src/objects/js-collection-inl.h"
36 37
#ifdef V8_INTL_SUPPORT
#include "src/objects/js-date-time-format-inl.h"
38
#include "src/objects/js-display-names-inl.h"
39
#endif  // V8_INTL_SUPPORT
40
#include "src/objects/js-generator-inl.h"
41
#ifdef V8_INTL_SUPPORT
42
#include "src/objects/js-list-format-inl.h"
43
#include "src/objects/js-locale-inl.h"
44 45
#include "src/objects/js-number-format-inl.h"
#include "src/objects/js-plural-rules-inl.h"
46
#endif  // V8_INTL_SUPPORT
47 48
#include "src/objects/js-regexp-inl.h"
#include "src/objects/js-regexp-string-iterator-inl.h"
49 50
#ifdef V8_INTL_SUPPORT
#include "src/objects/js-relative-time-format-inl.h"
51
#include "src/objects/js-segment-iterator-inl.h"
52
#include "src/objects/js-segmenter-inl.h"
53
#endif  // V8_INTL_SUPPORT
54
#include "src/compiler/node.h"
55
#include "src/objects/js-weak-refs-inl.h"
56
#include "src/objects/literal-objects-inl.h"
57
#include "src/objects/microtask-inl.h"
58
#include "src/objects/module-inl.h"
59
#include "src/objects/oddball-inl.h"
60
#include "src/objects/promise-inl.h"
61
#include "src/objects/property-descriptor-object-inl.h"
62
#include "src/objects/stack-frame-info-inl.h"
63
#include "src/objects/struct-inl.h"
64
#include "src/objects/template-objects-inl.h"
65
#include "src/objects/transitions-inl.h"
66
#include "src/regexp/regexp.h"
67
#include "src/utils/ostreams.h"
68
#include "src/wasm/wasm-code-manager.h"
69
#include "src/wasm/wasm-engine.h"
70
#include "src/wasm/wasm-objects-inl.h"
71 72
#include "torque-generated/class-definitions-tq-inl.h"
#include "torque-generated/internal-class-definitions-tq-inl.h"
73 74 75 76 77 78

namespace v8 {
namespace internal {

#ifdef OBJECT_PRINT

79
void Object::Print() const {
80 81 82 83 84
  // Output into debugger's command window if a debugger is attached.
  DbgStdoutStream dbg_os;
  this->Print(dbg_os);
  dbg_os << std::flush;

85
  StdoutStream os;
86
  this->Print(os);
87
  os << std::flush;
88 89
}

90
void Object::Print(std::ostream& os) const {  // NOLINT
91
  if (IsSmi()) {
92 93
    os << "Smi: " << std::hex << "0x" << Smi::ToInt(*this);
    os << std::dec << " (" << Smi::ToInt(*this) << ")\n";
94
  } else {
95
    HeapObject::cast(*this).HeapObjectPrint(os);
96 97 98
  }
}

99
void HeapObject::PrintHeader(std::ostream& os, const char* id) {  // NOLINT
100 101 102 103
  os << reinterpret_cast<void*>(ptr()) << ": [";
  if (id != nullptr) {
    os << id;
  } else {
104
    os << map().instance_type();
105 106
  }
  os << "]";
107 108 109
  if (ReadOnlyHeap::Contains(*this)) {
    os << " in ReadOnlySpace";
  } else if (GetHeapFromWritableObject(*this)->InOldSpace(*this)) {
110 111
    os << " in OldSpace";
  }
112 113 114
  if (!IsMap()) os << "\n - map: " << Brief(map());
}

115
void HeapObject::HeapObjectPrint(std::ostream& os) {  // NOLINT
116
  InstanceType instance_type = map().instance_type();
117 118

  if (instance_type < FIRST_NONSTRING_TYPE) {
119
    String::cast(*this).StringPrint(os);
120
    os << "\n";
121 122 123 124 125
    return;
  }

  switch (instance_type) {
    case FIXED_ARRAY_TYPE:
126
      FixedArray::cast(*this).FixedArrayPrint(os);
127
      break;
128
    case AWAIT_CONTEXT_TYPE:
129 130 131 132 133 134 135 136
    case BLOCK_CONTEXT_TYPE:
    case CATCH_CONTEXT_TYPE:
    case DEBUG_EVALUATE_CONTEXT_TYPE:
    case EVAL_CONTEXT_TYPE:
    case FUNCTION_CONTEXT_TYPE:
    case MODULE_CONTEXT_TYPE:
    case SCRIPT_CONTEXT_TYPE:
    case WITH_CONTEXT_TYPE:
137
    case SCRIPT_CONTEXT_TABLE_TYPE:
138
      Context::cast(*this).ContextPrint(os);
139 140
      break;
    case NATIVE_CONTEXT_TYPE:
141
      NativeContext::cast(*this).NativeContextPrint(os);
142
      break;
143
    case HASH_TABLE_TYPE:
144 145
    case ORDERED_HASH_MAP_TYPE:
    case ORDERED_HASH_SET_TYPE:
146
    case ORDERED_NAME_DICTIONARY_TYPE:
147 148 149
    case NAME_DICTIONARY_TYPE:
    case GLOBAL_DICTIONARY_TYPE:
    case SIMPLE_NUMBER_DICTIONARY_TYPE:
150
      FixedArray::cast(*this).FixedArrayPrint(os);
151
      break;
152
    case STRING_TABLE_TYPE:
153
      ObjectHashTable::cast(*this).ObjectHashTablePrint(os);
154
      break;
155
    case NUMBER_DICTIONARY_TYPE:
156
      NumberDictionary::cast(*this).NumberDictionaryPrint(os);
157
      break;
158
    case EPHEMERON_HASH_TABLE_TYPE:
159
      EphemeronHashTable::cast(*this).EphemeronHashTablePrint(os);
160
      break;
161
    case OBJECT_BOILERPLATE_DESCRIPTION_TYPE:
162
      ObjectBoilerplateDescription::cast(*this)
163
          .ObjectBoilerplateDescriptionPrint(os);
164
      break;
165
    case TRANSITION_ARRAY_TYPE:
166
      TransitionArray::cast(*this).TransitionArrayPrint(os);
167
      break;
168
    case CLOSURE_FEEDBACK_CELL_ARRAY_TYPE:
169
      ClosureFeedbackCellArray::cast(*this).ClosureFeedbackCellArrayPrint(os);
170
      break;
171

172
    case FILLER_TYPE:
173
      os << "filler";
174 175
      break;
    case JS_OBJECT_TYPE:  // fall through
176
    case JS_API_OBJECT_TYPE:
177
    case JS_SPECIAL_API_OBJECT_TYPE:
178
    case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
179
    case JS_ERROR_TYPE:
180
      JSObject::cast(*this).JSObjectPrint(os);
181
      break;
182
    case WASM_INSTANCE_OBJECT_TYPE:
183
      WasmInstanceObject::cast(*this).WasmInstanceObjectPrint(os);
184
      break;
185
    case JS_GENERATOR_OBJECT_TYPE:
186
      JSGeneratorObject::cast(*this).JSGeneratorObjectPrint(os);
187
      break;
188
    case CODE_TYPE:
189
      Code::cast(*this).CodePrint(os);
190
      break;
191
    case CODE_DATA_CONTAINER_TYPE:
192
      CodeDataContainer::cast(*this).CodeDataContainerPrint(os);
193
      break;
194 195
    case JS_SET_KEY_VALUE_ITERATOR_TYPE:
    case JS_SET_VALUE_ITERATOR_TYPE:
196
      JSSetIterator::cast(*this).JSSetIteratorPrint(os);
197
      break;
198 199 200
    case JS_MAP_KEY_ITERATOR_TYPE:
    case JS_MAP_KEY_VALUE_ITERATOR_TYPE:
    case JS_MAP_VALUE_ITERATOR_TYPE:
201
      JSMapIterator::cast(*this).JSMapIteratorPrint(os);
202
      break;
203 204 205
#define MAKE_TORQUE_CASE(Name, TYPE)   \
  case TYPE:                           \
    Name::cast(*this).Name##Print(os); \
206
    break;
207 208 209 210
      // Every class that has its fields defined in a .tq file and corresponds
      // to exactly one InstanceType value is included in the following list.
      TORQUE_INSTANCE_CHECKERS_SINGLE_FULLY_DEFINED(MAKE_TORQUE_CASE)
#undef MAKE_TORQUE_CASE
211

212
    case ALLOCATION_SITE_TYPE:
213
      AllocationSite::cast(*this).AllocationSitePrint(os);
214
      break;
215
    case LOAD_HANDLER_TYPE:
216
      LoadHandler::cast(*this).LoadHandlerPrint(os);
217 218
      break;
    case STORE_HANDLER_TYPE:
219
      StoreHandler::cast(*this).StoreHandlerPrint(os);
220
      break;
221
    case SCOPE_INFO_TYPE:
222
      ScopeInfo::cast(*this).ScopeInfoPrint(os);
223
      break;
224
    case FEEDBACK_METADATA_TYPE:
225
      FeedbackMetadata::cast(*this).FeedbackMetadataPrint(os);
226
      break;
227
    case WEAK_FIXED_ARRAY_TYPE:
228
      WeakFixedArray::cast(*this).WeakFixedArrayPrint(os);
229 230 231 232 233
      break;
    case INTERNALIZED_STRING_TYPE:
    case EXTERNAL_INTERNALIZED_STRING_TYPE:
    case ONE_BYTE_INTERNALIZED_STRING_TYPE:
    case EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE:
234 235
    case UNCACHED_EXTERNAL_INTERNALIZED_STRING_TYPE:
    case UNCACHED_EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE:
236 237 238 239 240 241 242 243 244 245
    case STRING_TYPE:
    case CONS_STRING_TYPE:
    case EXTERNAL_STRING_TYPE:
    case SLICED_STRING_TYPE:
    case THIN_STRING_TYPE:
    case ONE_BYTE_STRING_TYPE:
    case CONS_ONE_BYTE_STRING_TYPE:
    case EXTERNAL_ONE_BYTE_STRING_TYPE:
    case SLICED_ONE_BYTE_STRING_TYPE:
    case THIN_ONE_BYTE_STRING_TYPE:
246 247
    case UNCACHED_EXTERNAL_STRING_TYPE:
    case UNCACHED_EXTERNAL_ONE_BYTE_STRING_TYPE:
248
      // TODO(all): Handle these types too.
249
      os << "UNKNOWN TYPE " << map().instance_type();
250 251 252 253
      UNREACHABLE();
  }
}

254
void ByteArray::ByteArrayPrint(std::ostream& os) {  // NOLINT
255 256 257 258
  PrintHeader(os, "ByteArray");
  os << "\n - length: " << length()
     << "\n - data-start: " << static_cast<void*>(GetDataStartAddress())
     << "\n";
259 260
}

261
void BytecodeArray::BytecodeArrayPrint(std::ostream& os) {  // NOLINT
262
  PrintHeader(os, "BytecodeArray");
263
  os << "\n";
264
  Disassemble(os);
265 266
}

267
void FreeSpace::FreeSpacePrint(std::ostream& os) {  // NOLINT
268
  os << "free space, size " << Size() << "\n";
269 270
}

271
bool JSObject::PrintProperties(std::ostream& os) {  // NOLINT
272
  if (HasFastProperties()) {
273 274
    DescriptorArray descs = map().instance_descriptors();
    int nof_inobject_properties = map().GetInObjectProperties();
275
    for (InternalIndex i : map().IterateOwnDescriptors()) {
276
      os << "\n    ";
277
      descs.GetKey(i).NamePrint(os);
278
      os << ": ";
279
      PropertyDetails details = descs.GetDetails(i);
280 281
      switch (details.location()) {
        case kField: {
282
          FieldIndex field_index = FieldIndex::ForDescriptor(map(), i);
283 284
          if (IsUnboxedDoubleField(field_index)) {
            os << "<unboxed double> " << RawFastDoublePropertyAt(field_index);
285
          } else {
286
            os << Brief(RawFastPropertyAt(field_index));
287
          }
288 289
          break;
        }
290
        case kDescriptor:
291
          os << Brief(descs.GetStrongValue(i));
292
          break;
293
      }
294 295
      os << " ";
      details.PrintAsFastTo(os, PropertyDetails::kForProperties);
296 297 298 299 300 301
      if (details.location() != kField) continue;
      int field_index = details.field_index();
      if (nof_inobject_properties <= field_index) {
        field_index -= nof_inobject_properties;
        os << " properties[" << field_index << "]";
      }
302
    }
303
    return map().NumberOfOwnDescriptors() > 0;
304
  } else if (IsJSGlobalObject()) {
305
    JSGlobalObject::cast(*this).global_dictionary().Print(os);
306
  } else {
307
    property_dictionary().Print(os);
308
  }
309
  return true;
310 311
}

312 313 314
namespace {

template <class T>
315
bool IsTheHoleAt(T array, int index) {
316
  return false;
317 318
}

319
template <>
320
bool IsTheHoleAt(FixedDoubleArray array, int index) {
321
  return array.is_the_hole(index);
322 323
}

324
template <class T>
325
double GetScalarElement(T array, int index) {
326 327 328
  if (IsTheHoleAt(array, index)) {
    return std::numeric_limits<double>::quiet_NaN();
  }
329
  return array.get_scalar(index);
330 331
}

332
template <class T>
333
void DoPrintElements(std::ostream& os, Object object, int length) {  // NOLINT
334
  const bool print_the_hole = std::is_same<T, FixedDoubleArray>::value;
335
  T array = T::cast(object);
336
  if (length == 0) return;
337
  int previous_index = 0;
338
  double previous_value = GetScalarElement(array, 0);
339 340
  double value = 0.0;
  int i;
341 342
  for (i = 1; i <= length; i++) {
    if (i < length) value = GetScalarElement(array, i);
343
    bool values_are_nan = std::isnan(previous_value) && std::isnan(value);
344
    if (i != length && (previous_value == value || values_are_nan) &&
345
        IsTheHoleAt(array, i - 1) == IsTheHoleAt(array, i)) {
346 347 348 349 350 351 352 353 354
      continue;
    }
    os << "\n";
    std::stringstream ss;
    ss << previous_index;
    if (previous_index != i - 1) {
      ss << '-' << (i - 1);
    }
    os << std::setw(12) << ss.str() << ": ";
355
    if (print_the_hole && IsTheHoleAt(array, i - 1)) {
356 357 358 359 360 361
      os << "<the_hole>";
    } else {
      os << previous_value;
    }
    previous_index = i;
    previous_value = value;
362 363 364
  }
}

365 366
template <typename ElementType>
void PrintTypedArrayElements(std::ostream& os, const ElementType* data_ptr,
367
                             size_t length, bool is_on_heap) {
368 369
  if (length == 0) return;
  size_t previous_index = 0;
370 371 372 373 374 375
  if (i::FLAG_mock_arraybuffer_allocator && !is_on_heap) {
    // Don't try to print data that's not actually allocated.
    os << "\n    0-" << length << ": <mocked array buffer bytes>";
    return;
  }

376 377 378 379 380 381 382 383 384 385 386 387 388
  ElementType previous_value = data_ptr[0];
  ElementType value = 0;
  for (size_t i = 1; i <= length; i++) {
    if (i < length) value = data_ptr[i];
    if (i != length && previous_value == value) {
      continue;
    }
    os << "\n";
    std::stringstream ss;
    ss << previous_index;
    if (previous_index != i - 1) {
      ss << '-' << (i - 1);
    }
389
    os << std::setw(12) << ss.str() << ": " << +previous_value;
390 391 392 393 394
    previous_index = i;
    previous_value = value;
  }
}

395
template <typename T>
396
void PrintFixedArrayElements(std::ostream& os, T array) {
397
  // Print in array notation for non-sparse arrays.
398
  Object previous_value = array.length() > 0 ? array.get(0) : Object();
399
  Object value;
400 401
  int previous_index = 0;
  int i;
402 403 404
  for (i = 1; i <= array.length(); i++) {
    if (i < array.length()) value = array.get(i);
    if (previous_value == value && i != array.length()) {
405 406 407 408 409 410 411 412 413 414 415 416 417 418
      continue;
    }
    os << "\n";
    std::stringstream ss;
    ss << previous_index;
    if (previous_index != i - 1) {
      ss << '-' << (i - 1);
    }
    os << std::setw(12) << ss.str() << ": " << Brief(previous_value);
    previous_index = i;
    previous_value = value;
  }
}

419
void PrintDictionaryElements(std::ostream& os, FixedArrayBase elements) {
420
  // Print some internal fields
421
  NumberDictionary dict = NumberDictionary::cast(elements);
422
  if (dict.requires_slow_elements()) {
423 424
    os << "\n   - requires_slow_elements";
  } else {
425
    os << "\n   - max_number_key: " << dict.max_number_key();
426
  }
427
  dict.Print(os);
428 429
}

430
void PrintSloppyArgumentElements(std::ostream& os, ElementsKind kind,
431
                                 SloppyArgumentsElements elements) {
432 433
  FixedArray arguments_store = elements.arguments();
  os << "\n    0: context: " << Brief(elements.context())
434
     << "\n    1: arguments_store: " << Brief(arguments_store)
435
     << "\n    parameter to context slot map:";
436
  for (uint32_t i = 0; i < elements.parameter_map_length(); i++) {
437
    uint32_t raw_index = i + SloppyArgumentsElements::kParameterMapStart;
438
    Object mapped_entry = elements.get_mapped_entry(i);
439
    os << "\n    " << raw_index << ": param(" << i
440
       << "): " << Brief(mapped_entry);
441
    if (mapped_entry.IsTheHole()) {
Mathias Bynens's avatar
Mathias Bynens committed
442
      os << " in the arguments_store[" << i << "]";
443 444 445
    } else {
      os << " in the context";
    }
446
  }
447
  if (arguments_store.length() == 0) return;
448
  os << "\n }"
449
     << "\n - arguments_store: " << Brief(arguments_store) << " "
450
     << ElementsKindToString(arguments_store.map().elements_kind()) << " {";
451 452 453 454
  if (kind == FAST_SLOPPY_ARGUMENTS_ELEMENTS) {
    PrintFixedArrayElements(os, arguments_store);
  } else {
    DCHECK_EQ(kind, SLOW_SLOPPY_ARGUMENTS_ELEMENTS);
455
    PrintDictionaryElements(os, arguments_store);
456 457 458
  }
}

459 460
void PrintEmbedderData(std::ostream& os, EmbedderDataSlot slot) {
  DisallowHeapAllocation no_gc;
461
  Object value = slot.load_tagged();
462 463 464 465 466 467 468
  os << Brief(value);
  void* raw_pointer;
  if (slot.ToAlignedPointer(&raw_pointer)) {
    os << ", aligned pointer: " << raw_pointer;
  }
}

469
}  // namespace
470

471
void JSObject::PrintElements(std::ostream& os) {  // NOLINT
472 473
  // Don't call GetElementsKind, its validation code can cause the printer to
  // fail when debugging.
474
  os << " - elements: " << Brief(elements()) << " {";
475
  switch (map().elements_kind()) {
476 477 478
    case HOLEY_SMI_ELEMENTS:
    case PACKED_SMI_ELEMENTS:
    case HOLEY_ELEMENTS:
479 480
    case HOLEY_FROZEN_ELEMENTS:
    case HOLEY_SEALED_ELEMENTS:
481
    case HOLEY_NONEXTENSIBLE_ELEMENTS:
482
    case PACKED_ELEMENTS:
483 484
    case PACKED_FROZEN_ELEMENTS:
    case PACKED_SEALED_ELEMENTS:
485
    case PACKED_NONEXTENSIBLE_ELEMENTS:
486
    case FAST_STRING_WRAPPER_ELEMENTS: {
487
      PrintFixedArrayElements(os, FixedArray::cast(elements()));
488 489
      break;
    }
490 491
    case HOLEY_DOUBLE_ELEMENTS:
    case PACKED_DOUBLE_ELEMENTS: {
492
      DoPrintElements<FixedDoubleArray>(os, elements(), elements().length());
493 494
      break;
    }
495

496 497 498
#define PRINT_ELEMENTS(Type, type, TYPE, elementType)                         \
  case TYPE##_ELEMENTS: {                                                     \
    size_t length = JSTypedArray::cast(*this).length();                       \
499
    bool is_on_heap = JSTypedArray::cast(*this).is_on_heap();                 \
500 501
    const elementType* data_ptr =                                             \
        static_cast<const elementType*>(JSTypedArray::cast(*this).DataPtr()); \
502
    PrintTypedArrayElements<elementType>(os, data_ptr, length, is_on_heap);   \
503
    break;                                                                    \
504
  }
505
      TYPED_ARRAYS(PRINT_ELEMENTS)
506 507
#undef PRINT_ELEMENTS

508
    case DICTIONARY_ELEMENTS:
509
    case SLOW_STRING_WRAPPER_ELEMENTS:
510
      PrintDictionaryElements(os, elements());
511
      break;
512
    case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
513
    case SLOW_SLOPPY_ARGUMENTS_ELEMENTS:
514
      PrintSloppyArgumentElements(os, map().elements_kind(),
515
                                  SloppyArgumentsElements::cast(elements()));
516
      break;
517 518
    case NO_ELEMENTS:
      break;
519
  }
520
  os << "\n }\n";
521 522
}

523
static void JSObjectPrintHeader(std::ostream& os, JSObject obj,
524
                                const char* id) {  // NOLINT
525 526
  Isolate* isolate = obj.GetIsolate();
  obj.PrintHeader(os, id);
527 528
  // Don't call GetElementsKind, its validation code can cause the printer to
  // fail when debugging.
529
  os << " [";
530
  if (obj.HasFastProperties()) {
531 532 533
    os << "FastProperties";
  } else {
    os << "DictionaryProperties";
534
  }
535
  PrototypeIterator iter(isolate, obj);
536
  os << "]\n - prototype: " << Brief(iter.GetCurrent());
537 538 539
  os << "\n - elements: " << Brief(obj.elements()) << " ["
     << ElementsKindToString(obj.map().elements_kind());
  if (obj.elements().IsCowArray()) os << " (COW)";
540
  os << "]";
541 542
  Object hash = obj.GetHash();
  if (hash.IsSmi()) {
543
    os << "\n - hash: " << Brief(hash);
544
  }
545 546
  if (obj.GetEmbedderFieldCount() > 0) {
    os << "\n - embedder fields: " << obj.GetEmbedderFieldCount();
547
  }
548 549
}

550
static void JSObjectPrintBody(std::ostream& os,
551
                              JSObject obj,  // NOLINT
552
                              bool print_elements = true) {
553
  os << "\n - properties: ";
554 555
  Object properties_or_hash = obj.raw_properties_or_hash();
  if (!properties_or_hash.IsSmi()) {
556 557 558
    os << Brief(properties_or_hash);
  }
  os << " {";
559
  if (obj.PrintProperties(os)) os << "\n ";
560
  os << "}\n";
561
  if (print_elements) {
562 563
    size_t length = obj.IsJSTypedArray() ? JSTypedArray::cast(obj).length()
                                         : obj.elements().length();
564
    if (length > 0) obj.PrintElements(os);
565
  }
566
  int embedder_fields = obj.GetEmbedderFieldCount();
567
  if (embedder_fields > 0) {
568
    os << " - embedder fields = {";
569
    for (int i = 0; i < embedder_fields; i++) {
570
      os << "\n    ";
571
      PrintEmbedderData(os, EmbedderDataSlot(obj, i));
572 573 574
    }
    os << "\n }\n";
  }
575 576
}

577
void JSObject::JSObjectPrint(std::ostream& os) {  // NOLINT
578 579
  JSObjectPrintHeader(os, *this, nullptr);
  JSObjectPrintBody(os, *this);
580 581
}

582
void JSGeneratorObject::JSGeneratorObjectPrint(std::ostream& os) {  // NOLINT
583
  JSObjectPrintHeader(os, *this, "JSGeneratorObject");
584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611
  os << "\n - function: " << Brief(function());
  os << "\n - context: " << Brief(context());
  os << "\n - receiver: " << Brief(receiver());
  if (is_executing() || is_closed()) {
    os << "\n - input: " << Brief(input_or_debug_pos());
  } else {
    DCHECK(is_suspended());
    os << "\n - debug pos: " << Brief(input_or_debug_pos());
  }
  const char* mode = "(invalid)";
  switch (resume_mode()) {
    case kNext:
      mode = ".next()";
      break;
    case kReturn:
      mode = ".return()";
      break;
    case kThrow:
      mode = ".throw()";
      break;
  }
  os << "\n - resume mode: " << mode;
  os << "\n - continuation: " << continuation();
  if (is_closed()) os << " (closed)";
  if (is_executing()) os << " (executing)";
  if (is_suspended()) os << " (suspended)";
  if (is_suspended()) {
    DisallowHeapAllocation no_gc;
612 613 614 615 616
    SharedFunctionInfo fun_info = function().shared();
    if (fun_info.HasSourceCode()) {
      Script script = Script::cast(fun_info.script());
      String script_name = script.name().IsString()
                               ? String::cast(script.name())
617
                               : GetReadOnlyRoots().empty_string();
618 619 620 621

      os << "\n - source position: ";
      // Can't collect source positions here if not available as that would
      // allocate memory.
622 623
      if (fun_info.HasBytecodeArray() &&
          fun_info.GetBytecodeArray().HasSourcePositionTable()) {
624 625
        os << source_position();
        os << " (";
626 627 628
        script_name.PrintUC16(os);
        int lin = script.GetLineNumber(source_position()) + 1;
        int col = script.GetColumnNumber(source_position()) + 1;
629 630 631 632 633
        os << ", lin " << lin;
        os << ", col " << col;
      } else {
        os << "unavailable";
      }
634 635 636
      os << ")";
    }
  }
637
  os << "\n - register file: " << Brief(parameters_and_registers());
638
  JSObjectPrintBody(os, *this);
639 640
}

641
void JSArray::JSArrayPrint(std::ostream& os) {  // NOLINT
642
  JSObjectPrintHeader(os, *this, "JSArray");
643
  os << "\n - length: " << Brief(this->length());
644
  JSObjectPrintBody(os, *this);
645 646
}

647
void JSPromise::JSPromisePrint(std::ostream& os) {  // NOLINT
648
  JSObjectPrintHeader(os, *this, "JSPromise");
649
  os << "\n - status: " << JSPromise::Status(status());
650
  if (status() == Promise::kPending) {
651
    os << "\n - reactions: " << Brief(reactions());
652
  } else {
653
    os << "\n - result: " << Brief(result());
654
  }
655
  os << "\n - has_handler: " << has_handler();
656
  os << "\n - handled_hint: " << handled_hint();
657
  JSObjectPrintBody(os, *this);
658
}
659

660
void JSRegExp::JSRegExpPrint(std::ostream& os) {  // NOLINT
661
  JSObjectPrintHeader(os, *this, "JSRegExp");
662 663
  os << "\n - data: " << Brief(data());
  os << "\n - source: " << Brief(source());
664
  JSObjectPrintBody(os, *this);
665 666
}

667 668
void JSRegExpStringIterator::JSRegExpStringIteratorPrint(
    std::ostream& os) {  // NOLINT
669
  JSObjectPrintHeader(os, *this, "JSRegExpStringIterator");
670 671
  os << "\n - regex: " << Brief(iterating_reg_exp());
  os << "\n - string: " << Brief(iterated_string());
672 673 674
  os << "\n - done: " << done();
  os << "\n - global: " << global();
  os << "\n - unicode: " << unicode();
675
  JSObjectPrintBody(os, *this);
676
}
677

678
void Symbol::SymbolPrint(std::ostream& os) {  // NOLINT
679
  PrintHeader(os, "Symbol");
680
  os << "\n - hash: " << Hash();
681 682
  os << "\n - description: " << Brief(description());
  if (description().IsUndefined()) {
683
    os << " (" << PrivateSymbolToName() << ")";
684
  }
685
  os << "\n - private: " << is_private();
686 687
}

688
void DescriptorArray::DescriptorArrayPrint(std::ostream& os) {
689
  PrintHeader(os, "DescriptorArray");
690
  os << "\n - enum_cache: ";
691
  if (enum_cache().keys().length() == 0) {
692 693
    os << "empty";
  } else {
694 695 696
    os << enum_cache().keys().length();
    os << "\n   - keys: " << Brief(enum_cache().keys());
    os << "\n   - indices: " << Brief(enum_cache().indices());
697
  }
698
  os << "\n - nof slack descriptors: " << number_of_slack_descriptors();
699
  os << "\n - nof descriptors: " << number_of_descriptors();
700 701 702 703
  int16_t raw_marked = raw_number_of_marked_descriptors();
  os << "\n - raw marked descriptors: mc epoch "
     << NumberOfMarkedDescriptors::Epoch::decode(raw_marked) << ", marked "
     << NumberOfMarkedDescriptors::Marked::decode(raw_marked);
704 705
  PrintDescriptors(os);
}
706

707 708
void AliasedArgumentsEntry::AliasedArgumentsEntryPrint(
    std::ostream& os) {  // NOLINT
709
  PrintHeader(os, "AliasedArgumentsEntry");
710
  os << "\n - aliased_context_slot: " << aliased_context_slot();
711 712
}

713
namespace {
714
void PrintFixedArrayWithHeader(std::ostream& os, FixedArray array,
715
                               const char* type) {
716 717
  array.PrintHeader(os, type);
  os << "\n - length: " << array.length();
718 719 720
  PrintFixedArrayElements(os, array);
  os << "\n";
}
721

722
template <typename T>
723
void PrintHashTableWithHeader(std::ostream& os, T table, const char* type) {
724 725 726 727 728
  table.PrintHeader(os, type);
  os << "\n - length: " << table.length();
  os << "\n - elements: " << table.NumberOfElements();
  os << "\n - deleted: " << table.NumberOfDeletedElements();
  os << "\n - capacity: " << table.Capacity();
729 730

  os << "\n - elements: {";
731
  for (InternalIndex i : table.IterateEntries()) {
732
    os << '\n'
733
       << std::setw(12) << i.as_int() << ": " << Brief(table.KeyAt(i)) << " -> "
734
       << Brief(table.ValueAt(i));
735 736 737 738
  }
  os << "\n }\n";
}

739 740
template <typename T>
void PrintWeakArrayElements(std::ostream& os, T* array) {
741
  // Print in array notation for non-sparse arrays.
742 743 744
  MaybeObject previous_value =
      array->length() > 0 ? array->Get(0) : MaybeObject(kNullAddress);
  MaybeObject value;
745 746 747 748 749 750 751 752 753 754 755 756 757
  int previous_index = 0;
  int i;
  for (i = 1; i <= array->length(); i++) {
    if (i < array->length()) value = array->Get(i);
    if (previous_value == value && i != array->length()) {
      continue;
    }
    os << "\n";
    std::stringstream ss;
    ss << previous_index;
    if (previous_index != i - 1) {
      ss << '-' << (i - 1);
    }
758
    os << std::setw(12) << ss.str() << ": " << Brief(previous_value);
759 760 761 762 763
    previous_index = i;
    previous_value = value;
  }
}

764
}  // namespace
765

766 767 768
void EmbedderDataArray::EmbedderDataArrayPrint(std::ostream& os) {
  PrintHeader(os, "EmbedderDataArray");
  os << "\n - length: " << length();
769 770 771
  EmbedderDataSlot start(*this, 0);
  EmbedderDataSlot end(*this, length());
  for (EmbedderDataSlot slot = start; slot < end; ++slot) {
772 773 774 775 776 777 778
    os << "\n    ";
    PrintEmbedderData(os, slot);
  }
  os << "\n";
}

void FixedArray::FixedArrayPrint(std::ostream& os) {
779
  PrintFixedArrayWithHeader(os, *this, "FixedArray");
780
}
781

782 783 784
namespace {
void PrintContextWithHeader(std::ostream& os, Context context,
                            const char* type) {
785 786 787 788 789
  context.PrintHeader(os, type);
  os << "\n - length: " << context.length();
  os << "\n - scope_info: " << Brief(context.scope_info());
  os << "\n - previous: " << Brief(context.unchecked_previous());
  os << "\n - native_context: " << Brief(context.native_context());
790 791 792 793 794
  PrintFixedArrayElements(os, context);
  os << "\n";
}
}  // namespace

795
void Context::ContextPrint(std::ostream& os) {
796
  PrintContextWithHeader(os, *this, "Context");
797 798 799
}

void NativeContext::NativeContextPrint(std::ostream& os) {
800
  PrintContextWithHeader(os, *this, "NativeContext");
801 802 803
  os << " - microtask_queue: " << microtask_queue() << "\n";
}

804
void ObjectHashTable::ObjectHashTablePrint(std::ostream& os) {
805
  PrintHashTableWithHeader(os, *this, "ObjectHashTable");
806
}
807

808
void NumberDictionary::NumberDictionaryPrint(std::ostream& os) {
809
  PrintHashTableWithHeader(os, *this, "NumberDictionary");
810 811
}

812
void EphemeronHashTable::EphemeronHashTablePrint(std::ostream& os) {
813
  PrintHashTableWithHeader(os, *this, "EphemeronHashTable");
814 815
}

816 817
void ObjectBoilerplateDescription::ObjectBoilerplateDescriptionPrint(
    std::ostream& os) {
818
  PrintFixedArrayWithHeader(os, *this, "ObjectBoilerplateDescription");
819 820
}

821
void PropertyArray::PropertyArrayPrint(std::ostream& os) {  // NOLINT
822
  PrintHeader(os, "PropertyArray");
823
  os << "\n - length: " << length();
824
  os << "\n - hash: " << Hash();
825
  PrintFixedArrayElements(os, *this);
826 827
  os << "\n";
}
828

829
void FixedDoubleArray::FixedDoubleArrayPrint(std::ostream& os) {  // NOLINT
830
  PrintHeader(os, "FixedDoubleArray");
831
  os << "\n - length: " << length();
832
  DoPrintElements<FixedDoubleArray>(os, *this, length());
833
  os << "\n";
834 835
}

836
void WeakFixedArray::WeakFixedArrayPrint(std::ostream& os) {
837 838 839 840
  PrintHeader(os, "WeakFixedArray");
  os << "\n - length: " << length() << "\n";
  PrintWeakArrayElements(os, this);
  os << "\n";
841
}
842

843
void WeakArrayList::WeakArrayListPrint(std::ostream& os) {
844 845 846 847 848
  PrintHeader(os, "WeakArrayList");
  os << "\n - capacity: " << capacity();
  os << "\n - length: " << length() << "\n";
  PrintWeakArrayElements(os, this);
  os << "\n";
849 850
}

851
void TransitionArray::TransitionArrayPrint(std::ostream& os) {  // NOLINT
852
  PrintHeader(os, "TransitionArray");
853
  PrintInternal(os);
854 855
}

856
void FeedbackCell::FeedbackCellPrint(std::ostream& os) {  // NOLINT
857
  PrintHeader(os, "FeedbackCell");
858 859
  ReadOnlyRoots roots = GetReadOnlyRoots();
  if (map() == roots.no_closures_cell_map()) {
860
    os << "\n - no closures";
861
  } else if (map() == roots.one_closure_cell_map()) {
862
    os << "\n - one closure";
863
  } else if (map() == roots.many_closures_cell_map()) {
864 865 866 867 868 869 870 871
    os << "\n - many closures";
  } else {
    os << "\n - Invalid FeedbackCell map";
  }
  os << " - value: " << Brief(value());
  os << "\n";
}

872
void FeedbackVectorSpec::Print() {
873
  StdoutStream os;
874

875
  FeedbackVectorSpecPrint(os);
876

877 878 879
  os << std::flush;
}

880 881
void FeedbackVectorSpec::FeedbackVectorSpecPrint(std::ostream& os) {  // NOLINT
  int slot_count = slots();
882 883 884 885 886 887
  os << " - slot_count: " << slot_count;
  if (slot_count == 0) {
    os << " (empty)\n";
    return;
  }

888
  for (int slot = 0; slot < slot_count;) {
889
    FeedbackSlotKind kind = GetKind(FeedbackSlot(slot));
890
    int entry_size = FeedbackMetadata::GetSlotSize(kind);
891 892 893 894 895 896
    DCHECK_LT(0, entry_size);
    os << "\n Slot #" << slot << " " << kind;
    slot += entry_size;
  }
  os << "\n";
}
897

898
void FeedbackMetadata::FeedbackMetadataPrint(std::ostream& os) {
899
  PrintHeader(os, "FeedbackMetadata");
900
  os << "\n - slot_count: " << slot_count();
901

902
  FeedbackMetadataIterator iter(*this);
903
  while (iter.HasNext()) {
904 905
    FeedbackSlot slot = iter.Next();
    FeedbackSlotKind kind = iter.kind();
906 907 908 909 910
    os << "\n Slot " << slot << " " << kind;
  }
  os << "\n";
}

911 912 913 914
void ClosureFeedbackCellArray::ClosureFeedbackCellArrayPrint(std::ostream& os) {
  PrintFixedArrayWithHeader(os, *this, "ClosureFeedbackCellArray");
}

915
void FeedbackVector::FeedbackVectorPrint(std::ostream& os) {  // NOLINT
916
  PrintHeader(os, "FeedbackVector");
917
  os << "\n - length: " << length();
918 919 920 921 922
  if (length() == 0) {
    os << " (empty)\n";
    return;
  }

923 924
  os << "\n - shared function info: " << Brief(shared_function_info());
  os << "\n - optimized code/marker: ";
925 926 927 928 929
  if (has_optimized_code()) {
    os << Brief(optimized_code());
  } else {
    os << optimization_marker();
  }
930
  os << "\n - invocation count: " << invocation_count();
931
  os << "\n - profiler ticks: " << profiler_ticks();
932

933
  FeedbackMetadataIterator iter(metadata());
934
  while (iter.HasNext()) {
935 936
    FeedbackSlot slot = iter.Next();
    FeedbackSlotKind kind = iter.kind();
937

938
    os << "\n - slot " << slot << " " << kind << " ";
939
    FeedbackSlotPrint(os, slot);
940

941
    int entry_size = iter.entry_size();
942
    if (entry_size > 0) os << " {";
943 944
    for (int i = 0; i < entry_size; i++) {
      int index = GetIndex(slot) + i;
945
      os << "\n     [" << index << "]: " << Brief(get(index));
946
    }
947
    if (entry_size > 0) os << "\n  }";
948 949 950 951
  }
  os << "\n";
}

952 953
void FeedbackVector::FeedbackSlotPrint(std::ostream& os,
                                       FeedbackSlot slot) {  // NOLINT
954
  FeedbackNexus nexus(*this, slot);
955
  nexus.Print(os);
956 957
}

958 959 960
void FeedbackNexus::Print(std::ostream& os) {  // NOLINT
  switch (kind()) {
    case FeedbackSlotKind::kCall:
961 962 963
    case FeedbackSlotKind::kCloneObject:
    case FeedbackSlotKind::kHasKeyed:
    case FeedbackSlotKind::kInstanceOf:
964
    case FeedbackSlotKind::kLoadGlobalInsideTypeof:
965
    case FeedbackSlotKind::kLoadGlobalNotInsideTypeof:
966 967 968
    case FeedbackSlotKind::kLoadKeyed:
    case FeedbackSlotKind::kLoadProperty:
    case FeedbackSlotKind::kStoreDataPropertyInLiteral:
969
    case FeedbackSlotKind::kStoreGlobalSloppy:
970
    case FeedbackSlotKind::kStoreGlobalStrict:
971
    case FeedbackSlotKind::kStoreInArrayLiteral:
972
    case FeedbackSlotKind::kStoreKeyedSloppy:
973
    case FeedbackSlotKind::kStoreKeyedStrict:
974 975 976
    case FeedbackSlotKind::kStoreNamedSloppy:
    case FeedbackSlotKind::kStoreNamedStrict:
    case FeedbackSlotKind::kStoreOwnNamed: {
977
      os << InlineCacheState2String(ic_state());
978 979 980
      break;
    }
    case FeedbackSlotKind::kBinaryOp: {
981
      os << "BinaryOp:" << GetBinaryOperationFeedback();
982 983 984
      break;
    }
    case FeedbackSlotKind::kCompareOp: {
985
      os << "CompareOp:" << GetCompareOperationFeedback();
986 987 988
      break;
    }
    case FeedbackSlotKind::kForIn: {
989
      os << "ForIn:" << GetForInFeedback();
990 991 992 993 994 995 996 997 998 999
      break;
    }
    case FeedbackSlotKind::kLiteral:
    case FeedbackSlotKind::kTypeProfile:
      break;
    case FeedbackSlotKind::kInvalid:
    case FeedbackSlotKind::kKindsNumber:
      UNREACHABLE();
  }
}
1000

1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033
void Oddball::OddballPrint(std::ostream& os) {  // NOLINT
  to_string().Print(os);
}

void JSAsyncFunctionObject::JSAsyncFunctionObjectPrint(
    std::ostream& os) {  // NOLINT
  JSGeneratorObjectPrint(os);
}

void JSAsyncGeneratorObject::JSAsyncGeneratorObjectPrint(
    std::ostream& os) {  // NOLINT
  JSGeneratorObjectPrint(os);
}

void JSArgumentsObject::JSArgumentsObjectPrint(std::ostream& os) {  // NOLINT
  JSObjectPrint(os);
}

void JSStringIterator::JSStringIteratorPrint(std::ostream& os) {  // NOLINT
  JSObjectPrintHeader(os, *this, "JSStringIterator");
  os << "\n - string: " << Brief(string());
  os << "\n - index: " << index();
  JSObjectPrintBody(os, *this);
}

void JSAsyncFromSyncIterator::JSAsyncFromSyncIteratorPrint(
    std::ostream& os) {  // NOLINT
  JSObjectPrintHeader(os, *this, "JSAsyncFromSyncIterator");
  os << "\n - sync_iterator: " << Brief(sync_iterator());
  os << "\n - next: " << Brief(next());
  JSObjectPrintBody(os, *this);
}

1034 1035
void JSPrimitiveWrapper::JSPrimitiveWrapperPrint(std::ostream& os) {  // NOLINT
  JSObjectPrintHeader(os, *this, "JSPrimitiveWrapper");
1036
  os << "\n - value: " << Brief(value());
1037
  JSObjectPrintBody(os, *this);
1038 1039
}

1040
void JSMessageObject::JSMessageObjectPrint(std::ostream& os) {  // NOLINT
1041
  JSObjectPrintHeader(os, *this, "JSMessageObject");
1042
  os << "\n - type: " << static_cast<int>(type());
1043
  os << "\n - arguments: " << Brief(argument());
1044 1045 1046 1047
  os << "\n - start_position: " << start_position();
  os << "\n - end_position: " << end_position();
  os << "\n - script: " << Brief(script());
  os << "\n - stack_frames: " << Brief(stack_frames());
1048
  JSObjectPrintBody(os, *this);
1049 1050
}

1051
void String::StringPrint(std::ostream& os) {  // NOLINT
1052
  if (!IsOneByteRepresentation()) {
1053 1054
    os << "u";
  }
1055
  if (StringShape(*this).IsInternalized()) {
1056
    os << "#";
1057
  } else if (StringShape(*this).IsCons()) {
1058
    os << "c\"";
1059
  } else if (StringShape(*this).IsThin()) {
1060
    os << ">\"";
1061
  } else {
1062
    os << "\"";
1063 1064 1065 1066 1067 1068 1069 1070 1071 1072
  }

  const char truncated_epilogue[] = "...<truncated>";
  int len = length();
  if (!FLAG_use_verbose_printer) {
    if (len > 100) {
      len = 100 - sizeof(truncated_epilogue);
    }
  }
  for (int i = 0; i < len; i++) {
1073
    os << AsUC16(Get(i));
1074 1075
  }
  if (len != length()) {
1076
    os << truncated_epilogue;
1077 1078
  }

1079
  if (!StringShape(*this).IsInternalized()) os << "\"";
1080 1081
}

1082
void Name::NamePrint(std::ostream& os) {  // NOLINT
1083
  if (IsString()) {
1084
    String::cast(*this).StringPrint(os);
1085
  } else {
1086
    os << Brief(*this);
1087
  }
1088 1089
}

1090 1091
static const char* const weekdays[] = {"???", "Sun", "Mon", "Tue",
                                       "Wed", "Thu", "Fri", "Sat"};
1092

1093
void JSDate::JSDatePrint(std::ostream& os) {  // NOLINT
1094
  JSObjectPrintHeader(os, *this, "JSDate");
1095
  os << "\n - value: " << Brief(value());
1096
  if (!year().IsSmi()) {
1097
    os << "\n - time = NaN\n";
1098
  } else {
1099
    // TODO(svenpanne) Add some basic formatting to our streams.
1100
    ScopedVector<char> buf(100);
jgruber's avatar
jgruber committed
1101
    SNPrintF(buf, "\n - time = %s %04d/%02d/%02d %02d:%02d:%02d\n",
1102 1103 1104 1105 1106 1107 1108
             weekdays[weekday().IsSmi() ? Smi::ToInt(weekday()) + 1 : 0],
             year().IsSmi() ? Smi::ToInt(year()) : -1,
             month().IsSmi() ? Smi::ToInt(month()) : -1,
             day().IsSmi() ? Smi::ToInt(day()) : -1,
             hour().IsSmi() ? Smi::ToInt(hour()) : -1,
             min().IsSmi() ? Smi::ToInt(min()) : -1,
             sec().IsSmi() ? Smi::ToInt(sec()) : -1);
1109
    os << buf.begin();
1110
  }
1111
  JSObjectPrintBody(os, *this);
1112 1113
}

1114
void JSProxy::JSProxyPrint(std::ostream& os) {  // NOLINT
1115
  PrintHeader(os, "JSProxy");
1116
  os << "\n - target: ";
1117
  target().ShortPrint(os);
1118
  os << "\n - handler: ";
1119
  handler().ShortPrint(os);
1120
  os << "\n";
1121 1122
}

1123
void JSSet::JSSetPrint(std::ostream& os) {  // NOLINT
1124
  JSObjectPrintHeader(os, *this, "JSSet");
1125
  os << " - table: " << Brief(table());
1126
  JSObjectPrintBody(os, *this);
1127 1128
}

1129
void JSMap::JSMapPrint(std::ostream& os) {  // NOLINT
1130
  JSObjectPrintHeader(os, *this, "JSMap");
1131
  os << " - table: " << Brief(table());
1132
  JSObjectPrintBody(os, *this);
1133 1134
}

1135
void JSCollectionIterator::JSCollectionIteratorPrint(
1136
    std::ostream& os, const char* name) {  // NOLINT
1137
  JSObjectPrintHeader(os, *this, name);
1138 1139
  os << "\n - table: " << Brief(table());
  os << "\n - index: " << Brief(index());
1140
  JSObjectPrintBody(os, *this);
1141 1142
}

1143
void JSSetIterator::JSSetIteratorPrint(std::ostream& os) {  // NOLINT
1144
  JSCollectionIteratorPrint(os, "JSSetIterator");
1145 1146
}

1147
void JSMapIterator::JSMapIteratorPrint(std::ostream& os) {  // NOLINT
1148
  JSCollectionIteratorPrint(os, "JSMapIterator");
1149 1150
}

1151 1152 1153
void WeakCell::WeakCellPrint(std::ostream& os) {
  PrintHeader(os, "WeakCell");
  os << "\n - finalization_group: " << Brief(finalization_group());
1154
  os << "\n - target: " << Brief(target());
1155
  os << "\n - holdings: " << Brief(holdings());
1156 1157
  os << "\n - prev: " << Brief(prev());
  os << "\n - next: " << Brief(next());
1158
  os << "\n - unregister_token: " << Brief(unregister_token());
1159 1160
  os << "\n - key_list_prev: " << Brief(key_list_prev());
  os << "\n - key_list_next: " << Brief(key_list_next());
1161 1162
}

1163 1164 1165 1166 1167 1168
void JSWeakRef::JSWeakRefPrint(std::ostream& os) {
  JSObjectPrintHeader(os, *this, "JSWeakRef");
  os << "\n - target: " << Brief(target());
  JSObjectPrintBody(os, *this);
}

1169 1170
void JSFinalizationGroup::JSFinalizationGroupPrint(std::ostream& os) {
  JSObjectPrintHeader(os, *this, "JSFinalizationGroup");
1171
  os << "\n - native_context: " << Brief(native_context());
1172 1173
  os << "\n - cleanup: " << Brief(cleanup());
  os << "\n - active_cells: " << Brief(active_cells());
1174 1175 1176 1177 1178
  Object active_cell = active_cells();
  while (active_cell.IsWeakCell()) {
    os << "\n   - " << Brief(active_cell);
    active_cell = WeakCell::cast(active_cell).next();
  }
1179
  os << "\n - cleared_cells: " << Brief(cleared_cells());
1180 1181 1182 1183 1184
  Object cleared_cell = cleared_cells();
  while (cleared_cell.IsWeakCell()) {
    os << "\n   - " << Brief(cleared_cell);
    cleared_cell = WeakCell::cast(cleared_cell).next();
  }
1185
  os << "\n - key_map: " << Brief(key_map());
1186
  JSObjectPrintBody(os, *this);
1187 1188
}

1189 1190 1191 1192
void JSFinalizationGroupCleanupIterator::
    JSFinalizationGroupCleanupIteratorPrint(std::ostream& os) {
  JSObjectPrintHeader(os, *this, "JSFinalizationGroupCleanupIterator");
  os << "\n - finalization_group: " << Brief(finalization_group());
1193
  JSObjectPrintBody(os, *this);
1194 1195
}

1196
void JSWeakMap::JSWeakMapPrint(std::ostream& os) {  // NOLINT
1197
  JSObjectPrintHeader(os, *this, "JSWeakMap");
1198
  os << "\n - table: " << Brief(table());
1199
  JSObjectPrintBody(os, *this);
1200 1201
}

1202
void JSWeakSet::JSWeakSetPrint(std::ostream& os) {  // NOLINT
1203
  JSObjectPrintHeader(os, *this, "JSWeakSet");
1204
  os << "\n - table: " << Brief(table());
1205
  JSObjectPrintBody(os, *this);
1206 1207
}

1208
void JSArrayBuffer::JSArrayBufferPrint(std::ostream& os) {  // NOLINT
1209
  JSObjectPrintHeader(os, *this, "JSArrayBuffer");
1210
  os << "\n - backing_store: " << backing_store();
1211
  os << "\n - byte_length: " << byte_length();
1212
  if (is_external()) os << "\n - external";
1213 1214
  if (is_detachable()) os << "\n - detachable";
  if (was_detached()) os << "\n - detached";
1215
  if (is_shared()) os << "\n - shared";
1216
  JSObjectPrintBody(os, *this, !was_detached());
1217 1218
}

1219
void JSTypedArray::JSTypedArrayPrint(std::ostream& os) {  // NOLINT
1220
  JSObjectPrintHeader(os, *this, "JSTypedArray");
1221
  os << "\n - buffer: " << Brief(buffer());
1222 1223
  os << "\n - byte_offset: " << byte_offset();
  os << "\n - byte_length: " << byte_length();
1224
  os << "\n - length: " << length();
1225 1226 1227 1228 1229 1230
  os << "\n - data_ptr: " << DataPtr();
  Tagged_t base_ptr = static_cast<Tagged_t>(base_pointer().ptr());
  os << "\n   - base_pointer: "
     << reinterpret_cast<void*>(static_cast<Address>(base_ptr));
  os << "\n   - external_pointer: "
     << reinterpret_cast<void*>(external_pointer());
1231
  if (!buffer().IsJSArrayBuffer()) {
1232 1233 1234
    os << "\n <invalid buffer>\n";
    return;
  }
1235 1236
  if (WasDetached()) os << "\n - detached";
  JSObjectPrintBody(os, *this, !WasDetached());
1237 1238
}

1239
void JSArrayIterator::JSArrayIteratorPrint(std::ostream& os) {  // NOLING
1240
  JSObjectPrintHeader(os, *this, "JSArrayIterator");
1241 1242 1243
  os << "\n - iterated_object: " << Brief(iterated_object());
  os << "\n - next_index: " << Brief(next_index());
  os << "\n - kind: " << kind();
1244
  JSObjectPrintBody(os, *this);
1245 1246
}

1247
void JSDataView::JSDataViewPrint(std::ostream& os) {  // NOLINT
1248
  JSObjectPrintHeader(os, *this, "JSDataView");
1249
  os << "\n - buffer =" << Brief(buffer());
1250 1251
  os << "\n - byte_offset: " << byte_offset();
  os << "\n - byte_length: " << byte_length();
1252
  if (!buffer().IsJSArrayBuffer()) {
1253 1254 1255
    os << "\n <invalid buffer>";
    return;
  }
1256 1257
  if (WasDetached()) os << "\n - detached";
  JSObjectPrintBody(os, *this, !WasDetached());
1258 1259
}

1260
void JSBoundFunction::JSBoundFunctionPrint(std::ostream& os) {  // NOLINT
1261
  JSObjectPrintHeader(os, *this, "JSBoundFunction");
1262 1263 1264
  os << "\n - bound_target_function: " << Brief(bound_target_function());
  os << "\n - bound_this: " << Brief(bound_this());
  os << "\n - bound_arguments: " << Brief(bound_arguments());
1265
  JSObjectPrintBody(os, *this);
1266 1267
}

1268 1269
void JSFunction::JSFunctionPrint(std::ostream& os) {  // NOLINT
  Isolate* isolate = GetIsolate();
1270
  JSObjectPrintHeader(os, *this, "Function");
1271
  os << "\n - function prototype: ";
1272 1273 1274
  if (has_prototype_slot()) {
    if (has_prototype()) {
      os << Brief(prototype());
1275
      if (map().has_non_instance_prototype()) {
1276 1277 1278
        os << " (non-instance prototype)";
      }
    }
1279
    os << "\n - initial_map: ";
1280 1281 1282 1283
    if (has_initial_map()) os << Brief(initial_map());
  } else {
    os << "<no-prototype-slot>";
  }
1284
  os << "\n - shared_info: " << Brief(shared());
1285
  os << "\n - name: " << Brief(shared().Name());
1286 1287

  // Print Builtin name for builtin functions
1288
  int builtin_index = code().builtin_index();
1289 1290
  if (Builtins::IsBuiltinId(builtin_index) && !IsInterpreted()) {
    os << "\n - builtin: " << isolate->builtins()->name(builtin_index);
1291 1292
  }

1293
  os << "\n - formal_parameter_count: "
1294 1295
     << shared().internal_formal_parameter_count();
  if (shared().is_safe_to_skip_arguments_adaptor()) {
1296 1297
    os << "\n - safe_to_skip_arguments_adaptor";
  }
1298
  os << "\n - kind: " << shared().kind();
1299 1300
  os << "\n - context: " << Brief(context());
  os << "\n - code: " << Brief(code());
1301 1302
  if (IsInterpreted()) {
    os << "\n - interpreted";
1303 1304
    if (shared().HasBytecodeArray()) {
      os << "\n - bytecode: " << shared().GetBytecodeArray();
1305 1306
    }
  }
1307 1308
  if (WasmExportedFunction::IsWasmExportedFunction(*this)) {
    WasmExportedFunction function = WasmExportedFunction::cast(*this);
1309 1310 1311 1312 1313 1314
    os << "\n - WASM instance: " << Brief(function.instance());
    os << "\n - WASM function index: " << function.function_index();
  }
  if (WasmJSFunction::IsWasmJSFunction(*this)) {
    WasmJSFunction function = WasmJSFunction::cast(*this);
    os << "\n - WASM wrapper around: " << Brief(function.GetCallable());
1315
  }
1316
  shared().PrintSourceCode(os);
1317
  JSObjectPrintBody(os, *this);
1318
  os << " - feedback vector: ";
1319
  if (!shared().HasFeedbackMetadata()) {
1320 1321
    os << "feedback metadata is not available in SFI\n";
  } else if (has_feedback_vector()) {
1322
    feedback_vector().FeedbackVectorPrint(os);
1323 1324 1325
  } else {
    os << "not available\n";
  }
1326 1327
}

1328 1329
void SharedFunctionInfo::PrintSourceCode(std::ostream& os) {
  if (HasSourceCode()) {
1330
    os << "\n - source code: ";
1331
    String source = String::cast(Script::cast(script()).source());
1332 1333
    int start = StartPosition();
    int length = EndPosition() - start;
1334
    std::unique_ptr<char[]> source_string = source.ToCString(
1335
        DISALLOW_NULLS, FAST_STRING_TRAVERSAL, start, length, nullptr);
1336 1337 1338 1339
    os << source_string.get();
  }
}

1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355
void SmallOrderedHashSet::SmallOrderedHashSetPrint(std::ostream& os) {
  PrintHeader(os, "SmallOrderedHashSet");
  // TODO(tebbi): Print all fields.
}

void SmallOrderedHashMap::SmallOrderedHashMapPrint(std::ostream& os) {
  PrintHeader(os, "SmallOrderedHashMap");
  // TODO(tebbi): Print all fields.
}

void SmallOrderedNameDictionary::SmallOrderedNameDictionaryPrint(
    std::ostream& os) {
  PrintHeader(os, "SmallOrderedNameDictionary");
  // TODO(tebbi): Print all fields.
}

1356
void SharedFunctionInfo::SharedFunctionInfoPrint(std::ostream& os) {  // NOLINT
1357
  PrintHeader(os, "SharedFunctionInfo");
1358
  os << "\n - name: ";
1359 1360
  if (HasSharedName()) {
    os << Brief(Name());
1361 1362 1363
  } else {
    os << "<no-shared-name>";
  }
1364 1365 1366
  if (HasInferredName()) {
    os << "\n - inferred name: " << Brief(inferred_name());
  }
1367
  os << "\n - kind: " << kind();
1368
  os << "\n - syntax kind: " << syntax_kind();
1369 1370 1371
  if (needs_home_object()) {
    os << "\n - needs_home_object";
  }
1372 1373
  os << "\n - function_map_index: " << function_map_index();
  os << "\n - formal_parameter_count: " << internal_formal_parameter_count();
1374 1375 1376
  if (is_safe_to_skip_arguments_adaptor()) {
    os << "\n - safe_to_skip_arguments_adaptor";
  }
1377 1378
  os << "\n - expected_nof_properties: " << expected_nof_properties();
  os << "\n - language_mode: " << language_mode();
1379 1380
  os << "\n - data: " << Brief(function_data());
  os << "\n - code (from data): " << Brief(GetCode());
1381
  PrintSourceCode(os);
1382 1383
  // Script files are often large, thus only print their {Brief} representation.
  os << "\n - script: " << Brief(script());
1384
  os << "\n - function token position: " << function_token_position();
1385 1386
  os << "\n - start position: " << StartPosition();
  os << "\n - end position: " << EndPosition();
1387
  if (HasDebugInfo()) {
1388
    os << "\n - debug info: " << Brief(GetDebugInfo());
1389 1390 1391
  } else {
    os << "\n - no debug info";
  }
1392
  os << "\n - scope info: " << Brief(scope_info());
1393 1394 1395
  if (HasOuterScopeInfo()) {
    os << "\n - outer scope info: " << Brief(GetOuterScopeInfo());
  }
1396 1397
  os << "\n - length: " << length();
  os << "\n - feedback_metadata: ";
1398
  if (HasFeedbackMetadata()) {
1399
    feedback_metadata().FeedbackMetadataPrint(os);
1400 1401 1402
  } else {
    os << "<none>";
  }
1403
  os << "\n";
1404 1405
}

1406
void JSGlobalProxy::JSGlobalProxyPrint(std::ostream& os) {  // NOLINT
1407
  JSObjectPrintHeader(os, *this, "JSGlobalProxy");
1408
  if (!GetIsolate()->bootstrapper()->IsActive()) {
1409
    os << "\n - native context: " << Brief(native_context());
1410
  }
1411
  JSObjectPrintBody(os, *this);
1412 1413
}

1414
void JSGlobalObject::JSGlobalObjectPrint(std::ostream& os) {  // NOLINT
1415
  JSObjectPrintHeader(os, *this, "JSGlobalObject");
1416
  if (!GetIsolate()->bootstrapper()->IsActive()) {
1417
    os << "\n - native context: " << Brief(native_context());
1418
  }
1419
  os << "\n - global proxy: " << Brief(global_proxy());
1420
  JSObjectPrintBody(os, *this);
1421 1422
}

1423
void Cell::CellPrint(std::ostream& os) {  // NOLINT
1424
  PrintHeader(os, "Cell");
1425
  os << "\n - value: " << Brief(value());
1426
  os << "\n";
1427 1428
}

1429
void PropertyCell::PropertyCellPrint(std::ostream& os) {  // NOLINT
1430
  PrintHeader(os, "PropertyCell");
1431
  os << "\n - name: ";
1432
  name().NamePrint(os);
1433
  os << "\n - value: " << Brief(value());
1434 1435
  os << "\n - details: ";
  property_details().PrintAsSlowTo(os);
1436 1437
  PropertyCellType cell_type = property_details().cell_type();
  os << "\n - cell_type: ";
1438
  if (value().IsTheHole()) {
1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475
    switch (cell_type) {
      case PropertyCellType::kUninitialized:
        os << "Uninitialized";
        break;
      case PropertyCellType::kInvalidated:
        os << "Invalidated";
        break;
      default:
        os << "??? " << static_cast<int>(cell_type);
        break;
    }
  } else {
    switch (cell_type) {
      case PropertyCellType::kUndefined:
        os << "Undefined";
        break;
      case PropertyCellType::kConstant:
        os << "Constant";
        break;
      case PropertyCellType::kConstantType:
        os << "ConstantType"
           << " (";
        switch (GetConstantType()) {
          case PropertyCellConstantType::kSmi:
            os << "Smi";
            break;
          case PropertyCellConstantType::kStableMap:
            os << "StableMap";
            break;
        }
        os << ")";
        break;
      case PropertyCellType::kMutable:
        os << "Mutable";
        break;
    }
  }
1476
  os << "\n";
1477 1478
}

1479
void Code::CodePrint(std::ostream& os) {  // NOLINT
1480
  PrintHeader(os, "Code");
1481
  os << "\n";
1482 1483
#ifdef ENABLE_DISASSEMBLER
  if (FLAG_use_verbose_printer) {
1484
    Disassemble(nullptr, os, GetIsolate());
1485 1486 1487 1488
  }
#endif
}

1489
void CodeDataContainer::CodeDataContainerPrint(std::ostream& os) {  // NOLINT
1490
  PrintHeader(os, "CodeDataContainer");
1491 1492 1493
  os << "\n - kind_specific_flags: " << kind_specific_flags();
  os << "\n";
}
1494

1495
void Foreign::ForeignPrint(std::ostream& os) {  // NOLINT
1496 1497
  PrintHeader(os, "Foreign");
  os << "\n - foreign address : " << reinterpret_cast<void*>(foreign_address());
1498
  os << "\n";
1499 1500
}

1501
void AccessorInfo::AccessorInfoPrint(std::ostream& os) {  // NOLINT
1502
  PrintHeader(os, "AccessorInfo");
1503
  os << "\n - name: " << Brief(name());
1504
  os << "\n - flags: " << flags();
1505 1506
  os << "\n - getter: " << Brief(getter());
  os << "\n - setter: " << Brief(setter());
1507
  os << "\n - js_getter: " << Brief(js_getter());
1508 1509
  os << "\n - data: " << Brief(data());
  os << "\n";
1510 1511
}

1512
void CallbackTask::CallbackTaskPrint(std::ostream& os) {  // NOLINT
1513
  PrintHeader(os, "CallbackTask");
1514 1515 1516 1517 1518 1519
  os << "\n - callback: " << Brief(callback());
  os << "\n - data: " << Brief(data());
  os << "\n";
}

void CallableTask::CallableTaskPrint(std::ostream& os) {  // NOLINT
1520
  PrintHeader(os, "CallableTask");
1521 1522
  os << "\n - context: " << Brief(context());
  os << "\n - callable: " << Brief(callable());
1523 1524 1525
  os << "\n";
}

1526
void PromiseFulfillReactionJobTask::PromiseFulfillReactionJobTaskPrint(
1527
    std::ostream& os) {  // NOLINT
1528
  PrintHeader(os, "PromiseFulfillReactionJobTask");
1529 1530 1531
  os << "\n - argument: " << Brief(argument());
  os << "\n - context: " << Brief(context());
  os << "\n - handler: " << Brief(handler());
1532
  os << "\n - promise_or_capability: " << Brief(promise_or_capability());
1533 1534 1535 1536 1537
  os << "\n";
}

void PromiseRejectReactionJobTask::PromiseRejectReactionJobTaskPrint(
    std::ostream& os) {  // NOLINT
1538
  PrintHeader(os, "PromiseRejectReactionJobTask");
1539 1540 1541
  os << "\n - argument: " << Brief(argument());
  os << "\n - context: " << Brief(context());
  os << "\n - handler: " << Brief(handler());
1542
  os << "\n - promise_or_capability: " << Brief(promise_or_capability());
1543 1544 1545 1546 1547
  os << "\n";
}

void PromiseResolveThenableJobTask::PromiseResolveThenableJobTaskPrint(
    std::ostream& os) {  // NOLINT
1548
  PrintHeader(os, "PromiseResolveThenableJobTask");
1549 1550
  os << "\n - context: " << Brief(context());
  os << "\n - promise_to_resolve: " << Brief(promise_to_resolve());
1551
  os << "\n - then: " << Brief(then());
1552 1553 1554 1555 1556
  os << "\n - thenable: " << Brief(thenable());
  os << "\n";
}

void PromiseCapability::PromiseCapabilityPrint(std::ostream& os) {  // NOLINT
1557
  PrintHeader(os, "PromiseCapability");
1558
  os << "\n - promise: " << Brief(promise());
1559 1560 1561 1562 1563
  os << "\n - resolve: " << Brief(resolve());
  os << "\n - reject: " << Brief(reject());
  os << "\n";
}

1564
void PromiseReaction::PromiseReactionPrint(std::ostream& os) {  // NOLINT
1565
  PrintHeader(os, "PromiseReaction");
1566 1567 1568
  os << "\n - next: " << Brief(next());
  os << "\n - reject_handler: " << Brief(reject_handler());
  os << "\n - fulfill_handler: " << Brief(fulfill_handler());
1569
  os << "\n - promise_or_capability: " << Brief(promise_or_capability());
1570 1571 1572
  os << "\n";
}

1573 1574
void AsyncGeneratorRequest::AsyncGeneratorRequestPrint(
    std::ostream& os) {  // NOLINT
1575
  PrintHeader(os, "AsyncGeneratorRequest");
1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593
  const char* mode = "Invalid!";
  switch (resume_mode()) {
    case JSGeneratorObject::kNext:
      mode = ".next()";
      break;
    case JSGeneratorObject::kReturn:
      mode = ".return()";
      break;
    case JSGeneratorObject::kThrow:
      mode = ".throw()";
      break;
  }
  os << "\n - resume mode: " << mode;
  os << "\n - value: " << Brief(value());
  os << "\n - next: " << Brief(next());
  os << "\n";
}

1594 1595 1596
void SourceTextModuleInfoEntry::SourceTextModuleInfoEntryPrint(
    std::ostream& os) {  // NOLINT
  PrintHeader(os, "SourceTextModuleInfoEntry");
1597 1598 1599 1600 1601 1602 1603 1604 1605 1606
  os << "\n - export_name: " << Brief(export_name());
  os << "\n - local_name: " << Brief(local_name());
  os << "\n - import_name: " << Brief(import_name());
  os << "\n - module_request: " << module_request();
  os << "\n - cell_index: " << cell_index();
  os << "\n - beg_pos: " << beg_pos();
  os << "\n - end_pos: " << end_pos();
  os << "\n";
}

1607 1608 1609 1610 1611 1612
static void PrintModuleFields(Module module, std::ostream& os) {
  os << "\n - exports: " << Brief(module.exports());
  os << "\n - status: " << module.status();
  os << "\n - exception: " << Brief(module.exception());
}

1613
void Module::ModulePrint(std::ostream& os) {  // NOLINT
1614 1615
  if (this->IsSourceTextModule()) {
    SourceTextModule::cast(*this).SourceTextModulePrint(os);
1616 1617
  } else if (this->IsSyntheticModule()) {
    SyntheticModule::cast(*this).SyntheticModulePrint(os);
1618 1619 1620 1621 1622 1623 1624 1625
  } else {
    UNREACHABLE();
  }
}

void SourceTextModule::SourceTextModulePrint(std::ostream& os) {  // NOLINT
  PrintHeader(os, "SourceTextModule");
  PrintModuleFields(*this, os);
1626
  os << "\n - origin: " << Brief(script().GetNameOrSourceURL());
1627
  os << "\n - code: " << Brief(code());
1628
  os << "\n - requested_modules: " << Brief(requested_modules());
1629
  os << "\n - script: " << Brief(script());
1630
  os << "\n - import_meta: " << Brief(import_meta());
1631 1632
  os << "\n";
}
1633

1634 1635 1636 1637 1638 1639 1640
void SyntheticModule::SyntheticModulePrint(std::ostream& os) {  // NOLINT
  PrintHeader(os, "SyntheticModule");
  PrintModuleFields(*this, os);
  os << "\n - export_names: " << Brief(export_names());
  os << "\n";
}

1641
void JSModuleNamespace::JSModuleNamespacePrint(std::ostream& os) {  // NOLINT
1642
  JSObjectPrintHeader(os, *this, "JSModuleNamespace");
1643
  os << "\n - module: " << Brief(module());
1644
  JSObjectPrintBody(os, *this);
1645 1646
}

1647
void PrototypeInfo::PrototypeInfoPrint(std::ostream& os) {  // NOLINT
1648
  PrintHeader(os, "PrototypeInfo");
1649
  os << "\n - module namespace: " << Brief(module_namespace());
1650
  os << "\n - prototype users: " << Brief(prototype_users());
1651
  os << "\n - registry slot: " << registry_slot();
1652
  os << "\n - object create map: " << Brief(object_create_map());
1653
  os << "\n - should_be_fast_map: " << should_be_fast_map();
1654 1655 1656
  os << "\n";
}

1657 1658 1659 1660 1661 1662 1663
void ClassPositions::ClassPositionsPrint(std::ostream& os) {  // NOLINT
  PrintHeader(os, "ClassPositions");
  os << "\n - start position: " << start();
  os << "\n - end position: " << end();
  os << "\n";
}

1664 1665
void ArrayBoilerplateDescription::ArrayBoilerplateDescriptionPrint(
    std::ostream& os) {  // NOLINT
1666
  PrintHeader(os, "ArrayBoilerplateDescription");
1667 1668 1669 1670 1671
  os << "\n - elements kind: " << elements_kind();
  os << "\n - constant elements: " << Brief(constant_elements());
  os << "\n";
}

1672
void AsmWasmData::AsmWasmDataPrint(std::ostream& os) {  // NOLINT
1673
  PrintHeader(os, "AsmWasmData");
1674 1675
  os << "\n - native module: " << Brief(managed_native_module());
  os << "\n - export_wrappers: " << Brief(export_wrappers());
1676
  os << "\n - uses bitset: " << uses_bitset().value();
1677 1678 1679
  os << "\n";
}

1680
void WasmDebugInfo::WasmDebugInfoPrint(std::ostream& os) {  // NOLINT
1681
  PrintHeader(os, "WasmDebugInfo");
1682 1683 1684 1685
  os << "\n - wasm_instance: " << Brief(wasm_instance());
  os << "\n";
}

1686
void WasmExceptionTag::WasmExceptionTagPrint(std::ostream& os) {  // NOLINT
1687
  PrintHeader(os, "WasmExceptionTag");
1688 1689 1690 1691
  os << "\n - index: " << index();
  os << "\n";
}

1692
void WasmInstanceObject::WasmInstanceObjectPrint(std::ostream& os) {  // NOLINT
1693
  JSObjectPrintHeader(os, *this, "WasmInstanceObject");
1694 1695 1696
  os << "\n - module_object: " << Brief(module_object());
  os << "\n - exports_object: " << Brief(exports_object());
  os << "\n - native_context: " << Brief(native_context());
1697 1698 1699
  if (has_memory_object()) {
    os << "\n - memory_object: " << Brief(memory_object());
  }
1700 1701 1702 1703 1704
  if (has_untagged_globals_buffer()) {
    os << "\n - untagged_globals_buffer: " << Brief(untagged_globals_buffer());
  }
  if (has_tagged_globals_buffer()) {
    os << "\n - tagged_globals_buffer: " << Brief(tagged_globals_buffer());
1705 1706 1707 1708 1709 1710 1711 1712
  }
  if (has_imported_mutable_globals_buffers()) {
    os << "\n - imported_mutable_globals_buffers: "
       << Brief(imported_mutable_globals_buffers());
  }
  if (has_debug_info()) {
    os << "\n - debug_info: " << Brief(debug_info());
  }
1713 1714
  for (int i = 0; i < tables().length(); i++) {
    os << "\n - table " << i << ": " << Brief(tables().get(i));
1715
  }
1716 1717 1718 1719
  os << "\n - imported_function_refs: " << Brief(imported_function_refs());
  if (has_indirect_function_table_refs()) {
    os << "\n - indirect_function_table_refs: "
       << Brief(indirect_function_table_refs());
1720 1721 1722 1723 1724
  }
  if (has_managed_native_allocations()) {
    os << "\n - managed_native_allocations: "
       << Brief(managed_native_allocations());
  }
1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737
  os << "\n - memory_start: " << static_cast<void*>(memory_start());
  os << "\n - memory_size: " << memory_size();
  os << "\n - memory_mask: " << AsHex(memory_mask());
  os << "\n - imported_function_targets: "
     << static_cast<void*>(imported_function_targets());
  os << "\n - globals_start: " << static_cast<void*>(globals_start());
  os << "\n - imported_mutable_globals: "
     << static_cast<void*>(imported_mutable_globals());
  os << "\n - indirect_function_table_size: " << indirect_function_table_size();
  os << "\n - indirect_function_table_sig_ids: "
     << static_cast<void*>(indirect_function_table_sig_ids());
  os << "\n - indirect_function_table_targets: "
     << static_cast<void*>(indirect_function_table_targets());
1738
  JSObjectPrintBody(os, *this);
1739 1740 1741
  os << "\n";
}

1742 1743
void WasmExportedFunctionData::WasmExportedFunctionDataPrint(
    std::ostream& os) {  // NOLINT
1744
  PrintHeader(os, "WasmExportedFunctionData");
1745 1746
  os << "\n - wrapper_code: " << Brief(wrapper_code());
  os << "\n - instance: " << Brief(instance());
1747
  os << "\n - jump_table_offset: " << jump_table_offset();
1748 1749 1750 1751
  os << "\n - function_index: " << function_index();
  os << "\n";
}

1752 1753 1754 1755 1756 1757
void WasmJSFunctionData::WasmJSFunctionDataPrint(std::ostream& os) {  // NOLINT
  PrintHeader(os, "WasmJSFunctionData");
  os << "\n - wrapper_code: " << Brief(wrapper_code());
  os << "\n";
}

1758
void WasmModuleObject::WasmModuleObjectPrint(std::ostream& os) {  // NOLINT
1759
  PrintHeader(os, "WasmModuleObject");
1760
  os << "\n - module: " << module();
1761 1762 1763
  os << "\n - native module: " << native_module();
  os << "\n - export wrappers: " << Brief(export_wrappers());
  os << "\n - script: " << Brief(script());
1764 1765 1766
  os << "\n";
}

1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802
void WasmTableObject::WasmTableObjectPrint(std::ostream& os) {  // NOLINT
  PrintHeader(os, "WasmTableObject");
  os << "\n - elements: " << Brief(elements());
  os << "\n - maximum_length: " << Brief(maximum_length());
  os << "\n - dispatch_tables: " << Brief(dispatch_tables());
  os << "\n - raw_type: " << raw_type();
  os << "\n";
}

void WasmGlobalObject::WasmGlobalObjectPrint(std::ostream& os) {  // NOLINT
  PrintHeader(os, "WasmGlobalObject");
  os << "\n - untagged_buffer: " << Brief(untagged_buffer());
  os << "\n - tagged_buffer: " << Brief(tagged_buffer());
  os << "\n - offset: " << offset();
  os << "\n - flags: " << flags();
  os << "\n - type: " << type();
  os << "\n - is_mutable: " << is_mutable();
  os << "\n";
}

void WasmMemoryObject::WasmMemoryObjectPrint(std::ostream& os) {  // NOLINT
  PrintHeader(os, "WasmMemoryObject");
  os << "\n - array_buffer: " << Brief(array_buffer());
  os << "\n - maximum_pages: " << maximum_pages();
  os << "\n - instances: " << Brief(instances());
  os << "\n";
}

void WasmExceptionObject::WasmExceptionObjectPrint(
    std::ostream& os) {  // NOLINT
  PrintHeader(os, "WasmExceptionObject");
  os << "\n - serialized_signature: " << Brief(serialized_signature());
  os << "\n - exception_tag: " << Brief(exception_tag());
  os << "\n";
}

1803
void LoadHandler::LoadHandlerPrint(std::ostream& os) {  // NOLINT
1804
  PrintHeader(os, "LoadHandler");
1805 1806 1807
  // TODO(ishell): implement printing based on handler kind
  os << "\n - handler: " << Brief(smi_handler());
  os << "\n - validity_cell: " << Brief(validity_cell());
1808 1809
  int data_count = data_field_count();
  if (data_count >= 1) {
1810
    os << "\n - data1: " << Brief(data1());
1811 1812
  }
  if (data_count >= 2) {
1813
    os << "\n - data2: " << Brief(data2());
1814
  }
1815
  if (data_count >= 3) {
1816
    os << "\n - data3: " << Brief(data3());
1817
  }
1818 1819 1820 1821
  os << "\n";
}

void StoreHandler::StoreHandlerPrint(std::ostream& os) {  // NOLINT
1822
  PrintHeader(os, "StoreHandler");
1823 1824 1825
  // TODO(ishell): implement printing based on handler kind
  os << "\n - handler: " << Brief(smi_handler());
  os << "\n - validity_cell: " << Brief(validity_cell());
1826 1827
  int data_count = data_field_count();
  if (data_count >= 1) {
1828
    os << "\n - data1: " << Brief(data1());
1829 1830
  }
  if (data_count >= 2) {
1831
    os << "\n - data2: " << Brief(data2());
1832
  }
1833
  if (data_count >= 3) {
1834
    os << "\n - data3: " << Brief(data3());
1835
  }
1836 1837 1838
  os << "\n";
}

1839
void AccessorPair::AccessorPairPrint(std::ostream& os) {  // NOLINT
1840
  PrintHeader(os, "AccessorPair");
1841 1842 1843 1844 1845
  os << "\n - getter: " << Brief(getter());
  os << "\n - setter: " << Brief(setter());
  os << "\n";
}

1846
void AccessCheckInfo::AccessCheckInfoPrint(std::ostream& os) {  // NOLINT
1847
  PrintHeader(os, "AccessCheckInfo");
1848
  os << "\n - callback: " << Brief(callback());
1849 1850
  os << "\n - named_interceptor: " << Brief(named_interceptor());
  os << "\n - indexed_interceptor: " << Brief(indexed_interceptor());
1851 1852 1853 1854
  os << "\n - data: " << Brief(data());
  os << "\n";
}

1855
void CallHandlerInfo::CallHandlerInfoPrint(std::ostream& os) {  // NOLINT
1856
  PrintHeader(os, "CallHandlerInfo");
1857 1858 1859 1860
  os << "\n - callback: " << Brief(callback());
  os << "\n - js_callback: " << Brief(js_callback());
  os << "\n - data: " << Brief(data());
  os << "\n - side_effect_free: "
1861
     << (IsSideEffectFreeCallHandlerInfo() ? "true" : "false");
1862 1863
  os << "\n";
}
1864

1865
void InterceptorInfo::InterceptorInfoPrint(std::ostream& os) {  // NOLINT
1866
  PrintHeader(os, "InterceptorInfo");
1867 1868 1869 1870 1871 1872 1873
  os << "\n - getter: " << Brief(getter());
  os << "\n - setter: " << Brief(setter());
  os << "\n - query: " << Brief(query());
  os << "\n - deleter: " << Brief(deleter());
  os << "\n - enumerator: " << Brief(enumerator());
  os << "\n - data: " << Brief(data());
  os << "\n";
1874 1875
}

1876 1877
void FunctionTemplateInfo::FunctionTemplateInfoPrint(
    std::ostream& os) {  // NOLINT
1878
  PrintHeader(os, "FunctionTemplateInfo");
1879 1880
  os << "\n - class name: " << Brief(class_name());
  os << "\n - tag: " << Brief(tag());
1881
  os << "\n - serial_number: " << Brief(serial_number());
1882
  os << "\n - property_list: " << Brief(property_list());
1883 1884 1885
  os << "\n - call_code: " << Brief(call_code());
  os << "\n - property_accessors: " << Brief(property_accessors());
  os << "\n - signature: " << Brief(signature());
1886
  os << "\n - cached_property_name: " << Brief(cached_property_name());
1887 1888
  os << "\n - undetectable: " << (undetectable() ? "true" : "false");
  os << "\n - need_access_check: " << (needs_access_check() ? "true" : "false");
1889
  os << "\n - instantiated: " << (instantiated() ? "true" : "false");
1890
  os << "\n - rare_data: " << Brief(rare_data());
1891 1892 1893
  os << "\n";
}

1894 1895
void FunctionTemplateRareData::FunctionTemplateRareDataPrint(
    std::ostream& os) {  // NOLINT
1896
  PrintHeader(os, "FunctionTemplateRareData");
1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907
  os << "\n - prototype_template: " << Brief(prototype_template());
  os << "\n - prototype_provider_template: "
     << Brief(prototype_provider_template());
  os << "\n - parent_template: " << Brief(parent_template());
  os << "\n - named_property_handler: " << Brief(named_property_handler());
  os << "\n - indexed_property_handler: " << Brief(indexed_property_handler());
  os << "\n - instance_template: " << Brief(instance_template());
  os << "\n - instance_call_handler: " << Brief(instance_call_handler());
  os << "\n - access_check_info: " << Brief(access_check_info());
  os << "\n";
}
1908

1909 1910 1911 1912
void WasmCapiFunctionData::WasmCapiFunctionDataPrint(
    std::ostream& os) {  // NOLINT
  PrintHeader(os, "WasmCapiFunctionData");
  os << "\n - call_target: " << call_target();
1913
  os << "\n - embedder_data: " << Brief(embedder_data());
1914 1915 1916 1917 1918
  os << "\n - wrapper_code: " << Brief(wrapper_code());
  os << "\n - serialized_signature: " << Brief(serialized_signature());
  os << "\n";
}

1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932
void WasmIndirectFunctionTable::WasmIndirectFunctionTablePrint(
    std::ostream& os) {
  PrintHeader(os, "WasmIndirectFunctionTable");
  os << "\n - size: " << size();
  os << "\n - sig_ids: " << static_cast<void*>(sig_ids());
  os << "\n - targets: " << static_cast<void*>(targets());
  if (has_managed_native_allocations()) {
    os << "\n - managed_native_allocations: "
       << Brief(managed_native_allocations());
  }
  os << "\n - refs: " << Brief(refs());
  os << "\n";
}

1933
void ObjectTemplateInfo::ObjectTemplateInfoPrint(std::ostream& os) {  // NOLINT
1934
  PrintHeader(os, "ObjectTemplateInfo");
1935 1936
  os << "\n - tag: " << Brief(tag());
  os << "\n - serial_number: " << Brief(serial_number());
1937 1938 1939
  os << "\n - property_list: " << Brief(property_list());
  os << "\n - property_accessors: " << Brief(property_accessors());
  os << "\n - constructor: " << Brief(constructor());
1940
  os << "\n - embedder_field_count: " << embedder_field_count();
1941
  os << "\n - immutable_proto: " << (immutable_proto() ? "true" : "false");
1942 1943 1944
  os << "\n";
}

1945
void AllocationSite::AllocationSitePrint(std::ostream& os) {  // NOLINT
1946
  PrintHeader(os, "AllocationSite");
1947
  if (this->HasWeakNext()) os << "\n - weak_next: " << Brief(weak_next());
1948 1949 1950 1951 1952 1953 1954 1955 1956
  os << "\n - dependent code: " << Brief(dependent_code());
  os << "\n - nested site: " << Brief(nested_site());
  os << "\n - memento found count: "
     << Brief(Smi::FromInt(memento_found_count()));
  os << "\n - memento create count: "
     << Brief(Smi::FromInt(memento_create_count()));
  os << "\n - pretenure decision: "
     << Brief(Smi::FromInt(pretenure_decision()));
  os << "\n - transition_info: ";
1957
  if (!PointsToLiteral()) {
1958
    ElementsKind kind = GetElementsKind();
1959
    os << "Array allocation with ElementsKind " << ElementsKindToString(kind);
1960
  } else if (boilerplate().IsJSArray()) {
1961
    os << "Array literal with boilerplate " << Brief(boilerplate());
1962
  } else {
1963
    os << "Object literal with boilerplate " << Brief(boilerplate());
1964
  }
1965
  os << "\n";
1966 1967
}

1968
void AllocationMemento::AllocationMementoPrint(std::ostream& os) {  // NOLINT
1969
  PrintHeader(os, "AllocationMemento");
1970
  os << "\n - allocation site: ";
1971
  if (IsValid()) {
1972
    GetAllocationSite().AllocationSitePrint(os);
1973
  } else {
1974
    os << "<invalid>\n";
1975 1976 1977
  }
}

1978
void Script::ScriptPrint(std::ostream& os) {  // NOLINT
1979
  PrintHeader(os, "Script");
1980 1981
  os << "\n - source: " << Brief(source());
  os << "\n - name: " << Brief(name());
1982 1983 1984 1985
  os << "\n - line_offset: " << line_offset();
  os << "\n - column_offset: " << column_offset();
  os << "\n - type: " << type();
  os << "\n - id: " << id();
1986 1987 1988
  os << "\n - context data: " << Brief(context_data());
  os << "\n - compilation type: " << compilation_type();
  os << "\n - line ends: " << Brief(line_ends());
1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000
  if (type() == TYPE_WASM) {
    if (has_wasm_breakpoint_infos()) {
      os << "\n - wasm_breakpoint_infos: " << Brief(wasm_breakpoint_infos());
    }
  } else {
    if (has_eval_from_shared()) {
      os << "\n - eval from shared: " << Brief(eval_from_shared());
    }
    if (is_wrapped()) {
      os << "\n - wrapped arguments: " << Brief(wrapped_arguments());
    }
    os << "\n - eval from position: " << eval_from_position();
2001
  }
2002
  os << "\n - shared function infos: " << Brief(shared_function_infos());
2003 2004 2005
  os << "\n";
}

2006
#ifdef V8_INTL_SUPPORT
2007
void JSV8BreakIterator::JSV8BreakIteratorPrint(std::ostream& os) {  // NOLINT
2008
  JSObjectPrintHeader(os, *this, "JSV8BreakIterator");
2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020
  os << "\n - locale: " << Brief(locale());
  os << "\n - type: " << TypeAsString();
  os << "\n - break iterator: " << Brief(break_iterator());
  os << "\n - unicode string: " << Brief(unicode_string());
  os << "\n - bound adopt text: " << Brief(bound_adopt_text());
  os << "\n - bound first: " << Brief(bound_first());
  os << "\n - bound next: " << Brief(bound_next());
  os << "\n - bound current: " << Brief(bound_current());
  os << "\n - bound break type: " << Brief(bound_break_type());
  os << "\n";
}

2021
void JSCollator::JSCollatorPrint(std::ostream& os) {  // NOLINT
2022
  JSObjectPrintHeader(os, *this, "JSCollator");
2023
  os << "\n - icu collator: " << Brief(icu_collator());
2024
  os << "\n - bound compare: " << Brief(bound_compare());
2025
  JSObjectPrintBody(os, *this);
2026 2027
}

2028
void JSDateTimeFormat::JSDateTimeFormatPrint(std::ostream& os) {  // NOLINT
2029
  JSObjectPrintHeader(os, *this, "JSDateTimeFormat");
2030
  os << "\n - locale: " << Brief(locale());
2031
  os << "\n - icu locale: " << Brief(icu_locale());
2032
  os << "\n - icu simple date format: " << Brief(icu_simple_date_format());
2033
  os << "\n - icu date interval format: " << Brief(icu_date_interval_format());
2034
  os << "\n - bound format: " << Brief(bound_format());
2035
  os << "\n - hour cycle: " << HourCycleAsString();
2036
  JSObjectPrintBody(os, *this);
2037 2038
}

2039 2040 2041 2042 2043 2044 2045 2046
void JSDisplayNames::JSDisplayNamesPrint(std::ostream& os) {  // NOLINT
  JSObjectPrintHeader(os, *this, "JSDisplayNames");
  os << "\n - internal: " << Brief(internal());
  os << "\n - style: " << StyleAsString();
  os << "\n - fallback: " << FallbackAsString();
  JSObjectPrintBody(os, *this);
}

2047
void JSListFormat::JSListFormatPrint(std::ostream& os) {  // NOLINT
2048
  JSObjectPrintHeader(os, *this, "JSListFormat");
2049 2050 2051
  os << "\n - locale: " << Brief(locale());
  os << "\n - style: " << StyleAsString();
  os << "\n - type: " << TypeAsString();
2052
  os << "\n - icu formatter: " << Brief(icu_formatter());
2053
  JSObjectPrintBody(os, *this);
2054 2055
}

2056
void JSLocale::JSLocalePrint(std::ostream& os) {  // NOLINT
2057
  JSObjectPrintHeader(os, *this, "JSLocale");
2058 2059
  os << "\n - icu locale: " << Brief(icu_locale());
  JSObjectPrintBody(os, *this);
2060
}
2061

2062
void JSNumberFormat::JSNumberFormatPrint(std::ostream& os) {  // NOLINT
2063
  JSObjectPrintHeader(os, *this, "JSNumberFormat");
2064
  os << "\n - locale: " << Brief(locale());
2065
  os << "\n - icu_number_formatter: " << Brief(icu_number_formatter());
2066
  os << "\n - bound_format: " << Brief(bound_format());
2067
  JSObjectPrintBody(os, *this);
2068 2069
}

2070
void JSPluralRules::JSPluralRulesPrint(std::ostream& os) {  // NOLINT
2071
  JSObjectPrintHeader(os, *this, "JSPluralRules");
2072
  os << "\n - locale: " << Brief(locale());
2073
  os << "\n - type: " << TypeAsString();
2074
  os << "\n - icu plural rules: " << Brief(icu_plural_rules());
2075
  os << "\n - icu_number_formatter: " << Brief(icu_number_formatter());
2076
  JSObjectPrintBody(os, *this);
2077 2078
}

2079 2080
void JSRelativeTimeFormat::JSRelativeTimeFormatPrint(
    std::ostream& os) {  // NOLINT
2081
  JSObjectPrintHeader(os, *this, "JSRelativeTimeFormat");
2082
  os << "\n - locale: " << Brief(locale());
2083
  os << "\n - numberingSystem: " << Brief(numberingSystem());
2084 2085
  os << "\n - style: " << StyleAsString();
  os << "\n - numeric: " << NumericAsString();
2086
  os << "\n - icu formatter: " << Brief(icu_formatter());
2087 2088
  os << "\n";
}
2089

2090
void JSSegmentIterator::JSSegmentIteratorPrint(std::ostream& os) {  // NOLINT
2091
  JSObjectPrintHeader(os, *this, "JSSegmentIterator");
2092 2093 2094 2095 2096 2097
  os << "\n - icu break iterator: " << Brief(icu_break_iterator());
  os << "\n - unicode string: " << Brief(unicode_string());
  os << "\n - granularity: " << GranularityAsString();
  os << "\n";
}

2098
void JSSegmenter::JSSegmenterPrint(std::ostream& os) {  // NOLINT
2099
  JSObjectPrintHeader(os, *this, "JSSegmenter");
2100 2101
  os << "\n - locale: " << Brief(locale());
  os << "\n - granularity: " << GranularityAsString();
2102
  os << "\n - icu break iterator: " << Brief(icu_break_iterator());
2103
  JSObjectPrintBody(os, *this);
2104
}
2105 2106
#endif  // V8_INTL_SUPPORT

2107
namespace {
2108
void PrintScopeInfoList(ScopeInfo scope_info, std::ostream& os,
2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119
                        const char* list_name, int nof_internal_slots,
                        int start, int length) {
  if (length <= 0) return;
  int end = start + length;
  os << "\n - " << list_name;
  if (nof_internal_slots > 0) {
    os << " " << start << "-" << end << " [internal slots]";
  }
  os << " {\n";
  for (int i = nof_internal_slots; start < end; ++i, ++start) {
    os << "    - " << i << ": ";
2120
    String::cast(scope_info.get(start)).ShortPrint(os);
2121 2122 2123 2124 2125 2126 2127
    os << "\n";
  }
  os << "  }";
}
}  // namespace

void ScopeInfo::ScopeInfoPrint(std::ostream& os) {  // NOLINT
2128
  PrintHeader(os, "ScopeInfo");
2129
  if (length() == 0) {
2130
    os << "\n - length = 0\n";
2131 2132
    return;
  }
2133 2134 2135 2136
  int flags = Flags();

  os << "\n - parameters: " << ParameterCount();
  os << "\n - context locals : " << ContextLocalCount();
2137

2138
  os << "\n - scope type: " << scope_type();
2139
  if (SloppyEvalCanExtendVars()) os << "\n - sloppy eval";
2140
  os << "\n - language mode: " << language_mode();
2141 2142
  if (is_declaration_scope()) os << "\n - declaration scope";
  if (HasReceiver()) {
2143
    os << "\n - receiver: " << ReceiverVariableBits::decode(flags);
2144
  }
2145
  if (HasClassBrand()) os << "\n - has class brand";
2146
  if (HasSavedClassVariableIndex()) os << "\n - has saved class variable index";
2147
  if (HasNewTarget()) os << "\n - needs new target";
2148
  if (HasFunctionName()) {
2149
    os << "\n - function name(" << FunctionVariableBits::decode(flags) << "): ";
2150
    FunctionName().ShortPrint(os);
2151 2152 2153 2154
  }
  if (IsAsmModule()) os << "\n - asm module";
  if (HasSimpleParameters()) os << "\n - simple parameters";
  os << "\n - function kind: " << function_kind();
2155 2156 2157
  if (HasOuterScopeInfo()) {
    os << "\n - outer scope info: " << Brief(OuterScopeInfo());
  }
2158 2159 2160
  if (HasLocalsBlackList()) {
    os << "\n - locals blacklist: " << Brief(LocalsBlackList());
  }
2161
  if (HasFunctionName()) {
2162
    os << "\n - function name: " << Brief(FunctionName());
2163
  }
2164 2165 2166
  if (HasInferredFunctionName()) {
    os << "\n - inferred function name: " << Brief(InferredFunctionName());
  }
2167 2168
  if (HasContextExtensionSlot()) {
    os << "\n - has context extension slot";
2169
  }
2170

2171
  if (HasPositionInfo()) {
2172 2173
    os << "\n - start position: " << StartPosition();
    os << "\n - end position: " << EndPosition();
2174
  }
2175 2176
  os << "\n - length: " << length();
  if (length() > 0) {
2177
    PrintScopeInfoList(*this, os, "context slots", Context::MIN_CONTEXT_SLOTS,
2178 2179 2180 2181 2182
                       ContextLocalNamesIndex(), ContextLocalCount());
    // TODO(neis): Print module stuff if present.
  }
  os << "\n";
}
2183

2184
void DebugInfo::DebugInfoPrint(std::ostream& os) {  // NOLINT
2185
  PrintHeader(os, "DebugInfo");
2186 2187
  os << "\n - flags: " << flags();
  os << "\n - debugger_hints: " << debugger_hints();
2188
  os << "\n - shared: " << Brief(shared());
2189
  os << "\n - script: " << Brief(script());
2190
  os << "\n - original bytecode array: " << Brief(original_bytecode_array());
2191
  os << "\n - debug bytecode array: " << Brief(debug_bytecode_array());
2192
  os << "\n - break_points: ";
2193
  break_points().FixedArrayPrint(os);
2194
  os << "\n - coverage_info: " << Brief(coverage_info());
2195 2196
}

2197 2198 2199 2200 2201 2202
void StackTraceFrame::StackTraceFramePrint(std::ostream& os) {  // NOLINT
  PrintHeader(os, "StackTraceFrame");
  os << "\n - frame_index: " << frame_index();
  os << "\n - id: " << id();
  os << "\n - frame_info: " << Brief(frame_info());
}
2203

2204
void StackFrameInfo::StackFrameInfoPrint(std::ostream& os) {  // NOLINT
2205
  PrintHeader(os, "StackFrame");
2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216
  os << "\n - line_number: " << line_number();
  os << "\n - column_number: " << column_number();
  os << "\n - script_id: " << script_id();
  os << "\n - script_name: " << Brief(script_name());
  os << "\n - script_name_or_source_url: "
     << Brief(script_name_or_source_url());
  os << "\n - function_name: " << Brief(function_name());
  os << "\n - is_eval: " << (is_eval() ? "true" : "false");
  os << "\n - is_constructor: " << (is_constructor() ? "true" : "false");
  os << "\n";
}
2217

2218 2219 2220 2221 2222 2223 2224 2225
static void PrintBitMask(std::ostream& os, uint32_t value) {  // NOLINT
  for (int i = 0; i < 32; i++) {
    if ((i & 7) == 0) os << " ";
    os << (((value & 1) == 0) ? "_" : "x");
    value >>= 1;
  }
}

2226
void LayoutDescriptor::Print() {
2227
  StdoutStream os;
2228 2229 2230 2231
  this->Print(os);
  os << std::flush;
}

2232 2233
void LayoutDescriptor::ShortPrint(std::ostream& os) {
  if (IsSmi()) {
2234 2235
    // Print tagged value for easy use with "jld" gdb macro.
    os << reinterpret_cast<void*>(ptr());
2236
  } else {
2237
    os << Brief(*this);
2238 2239
  }
}
2240 2241 2242

void LayoutDescriptor::Print(std::ostream& os) {  // NOLINT
  os << "Layout descriptor: ";
2243
  if (IsFastPointerLayout()) {
2244 2245 2246
    os << "<all tagged>";
  } else if (IsSmi()) {
    os << "fast";
2247
    PrintBitMask(os, static_cast<uint32_t>(Smi::ToInt(*this)));
2248
  } else if (IsOddball() && IsUninitialized()) {
2249
    os << "<uninitialized>";
2250 2251
  } else {
    os << "slow";
2252 2253
    int num_words = number_of_layout_words();
    for (int i = 0; i < num_words; i++) {
2254
      if (i > 0) os << " |";
2255
      PrintBitMask(os, get_layout_word(i));
2256 2257 2258 2259 2260
    }
  }
  os << "\n";
}

2261 2262
void PreparseData::PreparseDataPrint(std::ostream& os) {  // NOLINT
  PrintHeader(os, "PreparseData");
2263 2264
  os << "\n - data_length: " << data_length();
  os << "\n - children_length: " << children_length();
2265 2266 2267 2268 2269 2270
  if (data_length() > 0) {
    os << "\n - data-start: " << (address() + kDataStartOffset);
  }
  if (children_length() > 0) {
    os << "\n - children-start: " << inner_start_offset();
  }
2271 2272
  for (int i = 0; i < children_length(); ++i) {
    os << "\n - [" << i << "]: " << Brief(get_child(i));
2273
  }
2274 2275
  os << "\n";
}
2276

2277 2278 2279
void UncompiledDataWithoutPreparseData::UncompiledDataWithoutPreparseDataPrint(
    std::ostream& os) {  // NOLINT
  PrintHeader(os, "UncompiledDataWithoutPreparseData");
2280 2281 2282 2283 2284
  os << "\n - start position: " << start_position();
  os << "\n - end position: " << end_position();
  os << "\n";
}

2285
void UncompiledDataWithPreparseData::UncompiledDataWithPreparseDataPrint(
2286
    std::ostream& os) {  // NOLINT
2287
  PrintHeader(os, "UncompiledDataWithPreparseData");
2288 2289
  os << "\n - start position: " << start_position();
  os << "\n - end position: " << end_position();
2290
  os << "\n - preparse_data: " << Brief(preparse_data());
2291 2292 2293
  os << "\n";
}

2294
void InterpreterData::InterpreterDataPrint(std::ostream& os) {  // NOLINT
2295
  PrintHeader(os, "InterpreterData");
2296 2297 2298 2299 2300
  os << "\n - bytecode_array: " << Brief(bytecode_array());
  os << "\n - interpreter_trampoline: " << Brief(interpreter_trampoline());
  os << "\n";
}

2301 2302
template <HeapObjectReferenceType kRefType, typename StorageType>
void TaggedImpl<kRefType, StorageType>::Print() {
2303
  StdoutStream os;
2304
  this->Print(os);
2305 2306 2307
  os << std::flush;
}

2308 2309
template <HeapObjectReferenceType kRefType, typename StorageType>
void TaggedImpl<kRefType, StorageType>::Print(std::ostream& os) {
2310
  Smi smi;
2311
  HeapObject heap_object;
2312
  if (ToSmi(&smi)) {
2313
    smi.SmiPrint(os);
2314
  } else if (IsCleared()) {
2315
    os << "[cleared]";
2316
  } else if (GetHeapObjectIfWeak(&heap_object)) {
2317
    os << "[weak] ";
2318
    heap_object.HeapObjectPrint(os);
2319
  } else if (GetHeapObjectIfStrong(&heap_object)) {
2320
    heap_object.HeapObjectPrint(os);
2321 2322 2323 2324 2325
  } else {
    UNREACHABLE();
  }
}

2326 2327 2328 2329 2330
void HeapNumber::HeapNumberPrint(std::ostream& os) {
  HeapNumberShortPrint(os);
  os << "\n";
}

2331 2332
#endif  // OBJECT_PRINT

2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350
void HeapNumber::HeapNumberShortPrint(std::ostream& os) {
  static constexpr uint64_t kUint64AllBitsSet =
      static_cast<uint64_t>(int64_t{-1});
  // Min/max integer values representable by 52 bits of mantissa and 1 sign bit.
  static constexpr int64_t kMinSafeInteger =
      static_cast<int64_t>(kUint64AllBitsSet << 53);
  static constexpr int64_t kMaxSafeInteger = -(kMinSafeInteger + 1);

  double val = value();
  if (val == DoubleToInteger(val) &&
      val >= static_cast<double>(kMinSafeInteger) &&
      val <= static_cast<double>(kMaxSafeInteger)) {
    int64_t i = static_cast<int64_t>(val);
    os << i << ".0";
  } else {
    os << val;
  }
}
2351

2352
// TODO(cbruni): remove once the new maptracer is in place.
2353
void Name::NameShortPrint() {
2354
  if (this->IsString()) {
2355
    PrintF("%s", String::cast(*this).ToCString().get());
2356 2357
  } else {
    DCHECK(this->IsSymbol());
2358
    Symbol s = Symbol::cast(*this);
2359
    if (s.description().IsUndefined()) {
2360
      PrintF("#<%s>", s.PrivateSymbolToName());
2361
    } else {
2362
      PrintF("<%s>", String::cast(s.description()).ToCString().get());
2363 2364 2365 2366
    }
  }
}

2367
// TODO(cbruni): remove once the new maptracer is in place.
2368
int Name::NameShortPrint(Vector<char> str) {
2369
  if (this->IsString()) {
2370
    return SNPrintF(str, "%s", String::cast(*this).ToCString().get());
2371 2372
  } else {
    DCHECK(this->IsSymbol());
2373
    Symbol s = Symbol::cast(*this);
2374
    if (s.description().IsUndefined()) {
2375
      return SNPrintF(str, "#<%s>", s.PrivateSymbolToName());
2376
    } else {
2377 2378
      return SNPrintF(str, "<%s>",
                      String::cast(s.description()).ToCString().get());
2379 2380 2381 2382
    }
  }
}

2383
void Map::PrintMapDetails(std::ostream& os) {
2384
  DisallowHeapAllocation no_gc;
2385
  this->MapPrint(os);
2386
  instance_descriptors().PrintDescriptors(os);
2387 2388 2389 2390 2391
}

void Map::MapPrint(std::ostream& os) {  // NOLINT
#ifdef OBJECT_PRINT
  PrintHeader(os, "Map");
2392
#else
2393
  os << "Map=" << reinterpret_cast<void*>(ptr());
2394
#endif
2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428
  os << "\n - type: " << instance_type();
  os << "\n - instance size: ";
  if (instance_size() == kVariableSizeSentinel) {
    os << "variable";
  } else {
    os << instance_size();
  }
  if (IsJSObjectMap()) {
    os << "\n - inobject properties: " << GetInObjectProperties();
  }
  os << "\n - elements kind: " << ElementsKindToString(elements_kind());
  os << "\n - unused property fields: " << UnusedPropertyFields();
  os << "\n - enum length: ";
  if (EnumLength() == kInvalidEnumCacheSentinel) {
    os << "invalid";
  } else {
    os << EnumLength();
  }
  if (is_deprecated()) os << "\n - deprecated_map";
  if (is_stable()) os << "\n - stable_map";
  if (is_migration_target()) os << "\n - migration_target";
  if (is_dictionary_map()) os << "\n - dictionary_map";
  if (has_named_interceptor()) os << "\n - named_interceptor";
  if (has_indexed_interceptor()) os << "\n - indexed_interceptor";
  if (may_have_interesting_symbols()) os << "\n - may_have_interesting_symbols";
  if (is_undetectable()) os << "\n - undetectable";
  if (is_callable()) os << "\n - callable";
  if (is_constructor()) os << "\n - constructor";
  if (has_prototype_slot()) {
    os << "\n - has_prototype_slot";
    if (has_non_instance_prototype()) os << " (non-instance prototype)";
  }
  if (is_access_check_needed()) os << "\n - access_check_needed";
  if (!is_extensible()) os << "\n - non-extensible";
2429 2430 2431
  if (IsContextMap()) {
    os << "\n - native context: " << Brief(native_context());
  } else if (is_prototype_map()) {
2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442
    os << "\n - prototype_map";
    os << "\n - prototype info: " << Brief(prototype_info());
  } else {
    os << "\n - back pointer: " << Brief(GetBackPointer());
  }
  os << "\n - prototype_validity cell: " << Brief(prototype_validity_cell());
  os << "\n - instance descriptors " << (owns_descriptors() ? "(own) " : "")
     << "#" << NumberOfOwnDescriptors() << ": "
     << Brief(instance_descriptors());
  if (FLAG_unbox_double_fields) {
    os << "\n - layout descriptor: ";
2443
    layout_descriptor().ShortPrint(os);
2444 2445 2446 2447
  }

  // Read-only maps can't have transitions, which is fortunate because we need
  // the isolate to iterate over the transitions.
2448 2449
  if (!IsReadOnlyHeapObject(*this)) {
    Isolate* isolate = GetIsolateFromWritableObject(*this);
2450 2451 2452 2453 2454
    DisallowHeapAllocation no_gc;
    TransitionsAccessor transitions(isolate, *this, &no_gc);
    int nof_transitions = transitions.NumberOfTransitions();
    if (nof_transitions > 0) {
      os << "\n - transitions #" << nof_transitions << ": ";
2455
      HeapObject heap_object;
2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467
      Smi smi;
      if (raw_transitions()->ToSmi(&smi)) {
        os << Brief(smi);
      } else if (raw_transitions()->GetHeapObject(&heap_object)) {
        os << Brief(heap_object);
      }
#ifdef OBJECT_PRINT
      transitions.PrintTransitions(os);
#endif  // OBJECT_PRINT
    }
  }
  os << "\n - prototype: " << Brief(prototype());
2468 2469 2470
  if (!IsContextMap()) {
    os << "\n - constructor: " << Brief(GetConstructor());
  }
2471 2472
  os << "\n - dependent code: " << Brief(dependent_code());
  os << "\n - construction counter: " << construction_counter();
2473
  os << "\n";
2474 2475
}

2476
void DescriptorArray::PrintDescriptors(std::ostream& os) {
2477
  for (InternalIndex i : InternalIndex::Range(number_of_descriptors())) {
2478
    Name key = GetKey(i);
2479
    os << "\n  [" << i.as_int() << "]: ";
2480
#ifdef OBJECT_PRINT
2481
    key.NamePrint(os);
2482
#else
2483
    key.ShortPrint(os);
2484 2485 2486
#endif
    os << " ";
    PrintDescriptorDetails(os, i, PropertyDetails::kPrintFull);
2487 2488 2489 2490
  }
  os << "\n";
}

2491 2492
void DescriptorArray::PrintDescriptorDetails(std::ostream& os,
                                             InternalIndex descriptor,
2493 2494 2495 2496 2497 2498
                                             PropertyDetails::PrintMode mode) {
  PropertyDetails details = GetDetails(descriptor);
  details.PrintAsFastTo(os, mode);
  os << " @ ";
  switch (details.location()) {
    case kField: {
2499
      FieldType field_type = GetFieldType(descriptor);
2500
      field_type.PrintTo(os);
2501 2502 2503
      break;
    }
    case kDescriptor:
2504
      Object value = GetStrongValue(descriptor);
2505
      os << Brief(value);
2506
      if (value.IsAccessorPair()) {
2507
        AccessorPair pair = AccessorPair::cast(value);
2508 2509
        os << "(get: " << Brief(pair.getter())
           << ", set: " << Brief(pair.setter()) << ")";
2510 2511 2512 2513
      }
      break;
  }
}
2514

2515 2516 2517 2518 2519 2520 2521 2522 2523 2524
#if defined(DEBUG) || defined(OBJECT_PRINT)
// This method is only meant to be called from gdb for debugging purposes.
// Since the string can also be in two-byte encoding, non-Latin1 characters
// will be ignored in the output.
char* String::ToAsciiArray() {
  // Static so that subsequent calls frees previously allocated space.
  // This also means that previous results will be overwritten.
  static char* buffer = nullptr;
  if (buffer != nullptr) delete[] buffer;
  buffer = new char[length() + 1];
2525
  WriteToFlat(*this, reinterpret_cast<uint8_t*>(buffer), 0, length());
2526 2527 2528 2529
  buffer[length()] = 0;
  return buffer;
}

2530
// static
2531
void TransitionsAccessor::PrintOneTransition(std::ostream& os, Name key,
2532
                                             Map target) {
2533 2534
  os << "\n     ";
#ifdef OBJECT_PRINT
2535
  key.NamePrint(os);
2536
#else
2537
  key.ShortPrint(os);
2538 2539
#endif
  os << ": ";
2540
  ReadOnlyRoots roots = key.GetReadOnlyRoots();
2541
  if (key == roots.nonextensible_symbol()) {
2542
    os << "(transition to non-extensible)";
2543
  } else if (key == roots.sealed_symbol()) {
2544
    os << "(transition to sealed)";
2545
  } else if (key == roots.frozen_symbol()) {
2546
    os << "(transition to frozen)";
2547
  } else if (key == roots.elements_transition_symbol()) {
2548
    os << "(transition to " << ElementsKindToString(target.elements_kind())
2549
       << ")";
2550
  } else if (key == roots.strict_function_transition_symbol()) {
2551 2552
    os << " (transition to strict function)";
  } else {
2553
    DCHECK(!IsSpecialTransition(roots, key));
2554
    os << "(transition to ";
2555
    InternalIndex descriptor = target.LastAdded();
2556 2557 2558
    DescriptorArray descriptors = target.instance_descriptors();
    descriptors.PrintDescriptorDetails(os, descriptor,
                                       PropertyDetails::kForTransitions);
2559 2560 2561 2562 2563
    os << ")";
  }
  os << " -> " << Brief(target);
}

2564
void TransitionArray::PrintInternal(std::ostream& os) {
2565 2566
  int num_transitions = number_of_transitions();
  os << "Transition array #" << num_transitions << ":";
2567
  for (int i = 0; i < num_transitions; i++) {
2568
    Name key = GetKey(i);
2569
    Map target = GetTarget(i);
2570
    TransitionsAccessor::PrintOneTransition(os, key, target);
2571
  }
2572 2573 2574 2575 2576 2577 2578
  os << "\n" << std::flush;
}

void TransitionsAccessor::PrintTransitions(std::ostream& os) {  // NOLINT
  switch (encoding()) {
    case kPrototypeInfo:
    case kUninitialized:
2579
    case kMigrationTarget:
2580
      return;
2581
    case kWeakRef: {
2582
      Map target = Map::cast(raw_transitions_->GetHeapObjectAssumeWeak());
2583
      Name key = GetSimpleTransitionKey(target);
2584
      PrintOneTransition(os, key, target);
2585
      break;
2586
    }
2587
    case kFullTransitionArray:
2588
      return transitions().PrintInternal(os);
2589
  }
2590 2591
}

2592
void TransitionsAccessor::PrintTransitionTree() {
2593
  StdoutStream os;
2594 2595 2596
  os << "map= " << Brief(map_);
  DisallowHeapAllocation no_gc;
  PrintTransitionTree(os, 0, &no_gc);
2597 2598 2599
  os << "\n" << std::flush;
}

2600 2601
void TransitionsAccessor::PrintTransitionTree(std::ostream& os, int level,
                                              DisallowHeapAllocation* no_gc) {
2602
  ReadOnlyRoots roots = ReadOnlyRoots(isolate_);
2603
  int num_transitions = NumberOfTransitions();
2604 2605
  if (num_transitions == 0) return;
  for (int i = 0; i < num_transitions; i++) {
2606
    Name key = GetKey(i);
2607
    Map target = GetTarget(i);
2608 2609
    os << std::endl
       << "  " << level << "/" << i << ":" << std::setw(level * 2 + 2) << " ";
2610 2611 2612 2613
    std::stringstream ss;
    ss << Brief(target);
    os << std::left << std::setw(50) << ss.str() << ": ";

2614
    if (key == roots.nonextensible_symbol()) {
2615
      os << "to non-extensible";
2616
    } else if (key == roots.sealed_symbol()) {
2617
      os << "to sealed ";
2618
    } else if (key == roots.frozen_symbol()) {
2619
      os << "to frozen";
2620
    } else if (key == roots.elements_transition_symbol()) {
2621
      os << "to " << ElementsKindToString(target.elements_kind());
2622
    } else if (key == roots.strict_function_transition_symbol()) {
2623 2624 2625
      os << "to strict function";
    } else {
#ifdef OBJECT_PRINT
2626
      key.NamePrint(os);
2627
#else
2628
      key.ShortPrint(os);
2629 2630
#endif
      os << " ";
2631
      DCHECK(!IsSpecialTransition(ReadOnlyRoots(isolate_), key));
2632
      os << "to ";
2633
      InternalIndex descriptor = target.LastAdded();
2634 2635 2636
      DescriptorArray descriptors = target.instance_descriptors();
      descriptors.PrintDescriptorDetails(os, descriptor,
                                         PropertyDetails::kForTransitions);
2637
    }
2638
    TransitionsAccessor transitions(isolate_, target, no_gc);
2639
    transitions.PrintTransitionTree(os, level + 1, no_gc);
2640 2641
  }
}
2642

2643
void JSObject::PrintTransitions(std::ostream& os) {  // NOLINT
2644
  DisallowHeapAllocation no_gc;
2645
  TransitionsAccessor ta(GetIsolate(), map(), &no_gc);
2646
  if (ta.NumberOfTransitions() == 0) return;
2647
  os << "\n - transitions";
2648
  ta.PrintTransitions(os);
2649
}
2650

2651
#endif  // defined(DEBUG) || defined(OBJECT_PRINT)
2652 2653
}  // namespace internal
}  // namespace v8
2654

2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672
namespace {

inline i::Object GetObjectFromRaw(void* object) {
  i::Address object_ptr = reinterpret_cast<i::Address>(object);
#ifdef V8_COMPRESS_POINTERS
  if (RoundDown<i::kPtrComprIsolateRootAlignment>(object_ptr) ==
      i::kNullAddress) {
    // Try to decompress pointer.
    i::Isolate* isolate = i::Isolate::Current();
    object_ptr = i::DecompressTaggedAny(isolate->isolate_root(),
                                        static_cast<i::Tagged_t>(object_ptr));
  }
#endif
  return i::Object(object_ptr);
}

}  // namespace

2673 2674 2675
//
// The following functions are used by our gdb macros.
//
2676 2677 2678 2679
V8_EXPORT_PRIVATE extern i::Object _v8_internal_Get_Object(void* object) {
  return GetObjectFromRaw(object);
}

2680
V8_EXPORT_PRIVATE extern void _v8_internal_Print_Object(void* object) {
2681
  GetObjectFromRaw(object).Print();
2682 2683
}

2684
V8_EXPORT_PRIVATE extern void _v8_internal_Print_Code(void* object) {
2685
  i::Address address = reinterpret_cast<i::Address>(object);
2686
  i::Isolate* isolate = i::Isolate::Current();
2687

2688 2689 2690 2691 2692 2693 2694 2695 2696
  {
    i::wasm::WasmCodeRefScope scope;
    i::wasm::WasmCode* wasm_code =
        isolate->wasm_engine()->code_manager()->LookupCode(address);
    if (wasm_code) {
      i::StdoutStream os;
      wasm_code->Disassemble(nullptr, os, address);
      return;
    }
2697
  }
2698 2699

  if (!isolate->heap()->InSpaceSlow(address, i::CODE_SPACE) &&
2700
      !isolate->heap()->InSpaceSlow(address, i::LO_SPACE) &&
2701 2702
      !i::InstructionStream::PcIsOffHeap(isolate, address) &&
      !i::ReadOnlyHeap::Contains(address)) {
2703
    i::PrintF(
2704 2705
        "%p is not within the current isolate's large object, code, read_only "
        "or embedded spaces\n",
2706
        object);
2707 2708 2709
    return;
  }

2710
  i::Code code = isolate->FindCodeObject(address);
2711
  if (!code.IsCode()) {
2712
    i::PrintF("No code object found containing %p\n", object);
2713 2714 2715
    return;
  }
#ifdef ENABLE_DISASSEMBLER
2716
  i::StdoutStream os;
2717
  code.Disassemble(nullptr, os, isolate, address);
2718
#else   // ENABLE_DISASSEMBLER
2719
  code.Print();
2720
#endif  // ENABLE_DISASSEMBLER
2721 2722
}

2723 2724
V8_EXPORT_PRIVATE extern void _v8_internal_Print_LayoutDescriptor(
    void* object) {
2725
  i::Object o(GetObjectFromRaw(object));
2726
  if (!o.IsLayoutDescriptor()) {
2727
    printf("Please provide a layout descriptor\n");
2728
  } else {
2729
    i::LayoutDescriptor::cast(o).Print();
2730 2731 2732
  }
}

2733
V8_EXPORT_PRIVATE extern void _v8_internal_Print_StackTrace() {
2734 2735 2736
  i::Isolate* isolate = i::Isolate::Current();
  isolate->PrintStack(stdout);
}
2737

2738
V8_EXPORT_PRIVATE extern void _v8_internal_Print_TransitionTree(void* object) {
2739
  i::Object o(GetObjectFromRaw(object));
2740
  if (!o.IsMap()) {
2741 2742 2743
    printf("Please provide a valid Map\n");
  } else {
#if defined(DEBUG) || defined(OBJECT_PRINT)
2744
    i::DisallowHeapAllocation no_gc;
2745
    i::Map map = i::Map::unchecked_cast(o);
2746
    i::TransitionsAccessor transitions(i::Isolate::Current(), map, &no_gc);
2747
    transitions.PrintTransitionTree();
2748 2749 2750
#endif
  }
}
2751 2752 2753 2754

V8_EXPORT_PRIVATE extern void _v8_internal_Node_Print(void* object) {
  reinterpret_cast<i::compiler::Node*>(object)->Print();
}