objects-printer.cc 90.9 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
#include "torque-generated/class-definitions-tq-inl.h"
72
#include "torque-generated/exported-class-definitions-tq-inl.h"
73
#include "torque-generated/internal-class-definitions-tq-inl.h"
74 75 76 77 78 79

namespace v8 {
namespace internal {

#ifdef OBJECT_PRINT

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

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

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

100 101 102 103 104
namespace {

void PrintHeapObjectHeaderWithoutMap(HeapObject object, std::ostream& os,
                                     const char* id) {  // NOLINT
  os << reinterpret_cast<void*>(object.ptr()) << ": [";
105 106 107
  if (id != nullptr) {
    os << id;
  } else {
108
    os << object.map().instance_type();
109 110
  }
  os << "]";
111
  if (ReadOnlyHeap::Contains(object)) {
112
    os << " in ReadOnlySpace";
113
  } else if (GetHeapFromWritableObject(object)->InOldSpace(object)) {
114 115
    os << " in OldSpace";
  }
116 117 118 119 120 121
}

}  // namespace

void HeapObject::PrintHeader(std::ostream& os, const char* id) {  // NOLINT
  PrintHeapObjectHeaderWithoutMap(*this, os, id);
122 123 124
  if (!IsMap()) os << "\n - map: " << Brief(map());
}

125
void HeapObject::HeapObjectPrint(std::ostream& os) {  // NOLINT
126
  InstanceType instance_type = map().instance_type();
127 128

  if (instance_type < FIRST_NONSTRING_TYPE) {
129
    String::cast(*this).StringPrint(os);
130
    os << "\n";
131 132 133 134 135
    return;
  }

  switch (instance_type) {
    case FIXED_ARRAY_TYPE:
136
      FixedArray::cast(*this).FixedArrayPrint(os);
137
      break;
138
    case AWAIT_CONTEXT_TYPE:
139 140 141 142 143 144 145 146
    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:
147
    case SCRIPT_CONTEXT_TABLE_TYPE:
148
      Context::cast(*this).ContextPrint(os);
149 150
      break;
    case NATIVE_CONTEXT_TYPE:
151
      NativeContext::cast(*this).NativeContextPrint(os);
152
      break;
153
    case HASH_TABLE_TYPE:
154 155
    case ORDERED_HASH_MAP_TYPE:
    case ORDERED_HASH_SET_TYPE:
156
    case ORDERED_NAME_DICTIONARY_TYPE:
157 158 159
    case NAME_DICTIONARY_TYPE:
    case GLOBAL_DICTIONARY_TYPE:
    case SIMPLE_NUMBER_DICTIONARY_TYPE:
160
      FixedArray::cast(*this).FixedArrayPrint(os);
161
      break;
162
    case STRING_TABLE_TYPE:
163
      ObjectHashTable::cast(*this).ObjectHashTablePrint(os);
164
      break;
165
    case NUMBER_DICTIONARY_TYPE:
166
      NumberDictionary::cast(*this).NumberDictionaryPrint(os);
167
      break;
168
    case EPHEMERON_HASH_TABLE_TYPE:
169
      EphemeronHashTable::cast(*this).EphemeronHashTablePrint(os);
170
      break;
171
    case OBJECT_BOILERPLATE_DESCRIPTION_TYPE:
172
      ObjectBoilerplateDescription::cast(*this)
173
          .ObjectBoilerplateDescriptionPrint(os);
174
      break;
175
    case TRANSITION_ARRAY_TYPE:
176
      TransitionArray::cast(*this).TransitionArrayPrint(os);
177
      break;
178
    case CLOSURE_FEEDBACK_CELL_ARRAY_TYPE:
179
      ClosureFeedbackCellArray::cast(*this).ClosureFeedbackCellArrayPrint(os);
180
      break;
181

182
    case FILLER_TYPE:
183
      os << "filler";
184 185
      break;
    case JS_OBJECT_TYPE:  // fall through
186
    case JS_API_OBJECT_TYPE:
187
    case JS_SPECIAL_API_OBJECT_TYPE:
188
    case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
189
    case JS_ERROR_TYPE:
190
      JSObject::cast(*this).JSObjectPrint(os);
191
      break;
192
    case WASM_INSTANCE_OBJECT_TYPE:
193
      WasmInstanceObject::cast(*this).WasmInstanceObjectPrint(os);
194
      break;
195
    case JS_GENERATOR_OBJECT_TYPE:
196
      JSGeneratorObject::cast(*this).JSGeneratorObjectPrint(os);
197
      break;
198
    case CODE_TYPE:
199
      Code::cast(*this).CodePrint(os);
200
      break;
201
    case CODE_DATA_CONTAINER_TYPE:
202
      CodeDataContainer::cast(*this).CodeDataContainerPrint(os);
203
      break;
204 205
    case JS_SET_KEY_VALUE_ITERATOR_TYPE:
    case JS_SET_VALUE_ITERATOR_TYPE:
206
      JSSetIterator::cast(*this).JSSetIteratorPrint(os);
207
      break;
208 209 210
    case JS_MAP_KEY_ITERATOR_TYPE:
    case JS_MAP_KEY_VALUE_ITERATOR_TYPE:
    case JS_MAP_VALUE_ITERATOR_TYPE:
211
      JSMapIterator::cast(*this).JSMapIteratorPrint(os);
212
      break;
213 214 215
#define MAKE_TORQUE_CASE(Name, TYPE)   \
  case TYPE:                           \
    Name::cast(*this).Name##Print(os); \
216
    break;
217 218 219
      // 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)
220
      TORQUE_INSTANCE_CHECKERS_MULTIPLE_FULLY_DEFINED(MAKE_TORQUE_CASE)
221
#undef MAKE_TORQUE_CASE
222

223 224 225
    case FOREIGN_TYPE:
      Foreign::cast(*this).ForeignPrint(os);
      break;
226
    case ALLOCATION_SITE_TYPE:
227
      AllocationSite::cast(*this).AllocationSitePrint(os);
228
      break;
229
    case LOAD_HANDLER_TYPE:
230
      LoadHandler::cast(*this).LoadHandlerPrint(os);
231 232
      break;
    case STORE_HANDLER_TYPE:
233
      StoreHandler::cast(*this).StoreHandlerPrint(os);
234
      break;
235
    case SCOPE_INFO_TYPE:
236
      ScopeInfo::cast(*this).ScopeInfoPrint(os);
237
      break;
238
    case FEEDBACK_METADATA_TYPE:
239
      FeedbackMetadata::cast(*this).FeedbackMetadataPrint(os);
240
      break;
241
    case WEAK_FIXED_ARRAY_TYPE:
242
      WeakFixedArray::cast(*this).WeakFixedArrayPrint(os);
243 244 245 246 247
      break;
    case INTERNALIZED_STRING_TYPE:
    case EXTERNAL_INTERNALIZED_STRING_TYPE:
    case ONE_BYTE_INTERNALIZED_STRING_TYPE:
    case EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE:
248 249
    case UNCACHED_EXTERNAL_INTERNALIZED_STRING_TYPE:
    case UNCACHED_EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE:
250 251 252 253 254 255 256 257 258 259
    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:
260 261
    case UNCACHED_EXTERNAL_STRING_TYPE:
    case UNCACHED_EXTERNAL_ONE_BYTE_STRING_TYPE:
262
      // TODO(all): Handle these types too.
263
      os << "UNKNOWN TYPE " << map().instance_type();
264 265 266 267
      UNREACHABLE();
  }
}

268
void ByteArray::ByteArrayPrint(std::ostream& os) {  // NOLINT
269 270 271 272
  PrintHeader(os, "ByteArray");
  os << "\n - length: " << length()
     << "\n - data-start: " << static_cast<void*>(GetDataStartAddress())
     << "\n";
273 274
}

275
void BytecodeArray::BytecodeArrayPrint(std::ostream& os) {  // NOLINT
276
  PrintHeader(os, "BytecodeArray");
277
  os << "\n";
278
  Disassemble(os);
279 280
}

281
void FreeSpace::FreeSpacePrint(std::ostream& os) {  // NOLINT
282
  os << "free space, size " << Size() << "\n";
283 284
}

285
bool JSObject::PrintProperties(std::ostream& os) {  // NOLINT
286
  if (HasFastProperties()) {
287 288
    DescriptorArray descs = map().instance_descriptors();
    int nof_inobject_properties = map().GetInObjectProperties();
289
    for (InternalIndex i : map().IterateOwnDescriptors()) {
290
      os << "\n    ";
291
      descs.GetKey(i).NamePrint(os);
292
      os << ": ";
293
      PropertyDetails details = descs.GetDetails(i);
294 295
      switch (details.location()) {
        case kField: {
296
          FieldIndex field_index = FieldIndex::ForDescriptor(map(), i);
297 298
          if (IsUnboxedDoubleField(field_index)) {
            os << "<unboxed double> " << RawFastDoublePropertyAt(field_index);
299
          } else {
300
            os << Brief(RawFastPropertyAt(field_index));
301
          }
302 303
          break;
        }
304
        case kDescriptor:
305
          os << Brief(descs.GetStrongValue(i));
306
          break;
307
      }
308 309
      os << " ";
      details.PrintAsFastTo(os, PropertyDetails::kForProperties);
310 311 312 313 314 315
      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 << "]";
      }
316
    }
317
    return map().NumberOfOwnDescriptors() > 0;
318
  } else if (IsJSGlobalObject()) {
319
    JSGlobalObject::cast(*this).global_dictionary().Print(os);
320
  } else {
321
    property_dictionary().Print(os);
322
  }
323
  return true;
324 325
}

326 327 328
namespace {

template <class T>
329
bool IsTheHoleAt(T array, int index) {
330
  return false;
331 332
}

333
template <>
334
bool IsTheHoleAt(FixedDoubleArray array, int index) {
335
  return array.is_the_hole(index);
336 337
}

338
template <class T>
339
double GetScalarElement(T array, int index) {
340 341 342
  if (IsTheHoleAt(array, index)) {
    return std::numeric_limits<double>::quiet_NaN();
  }
343
  return array.get_scalar(index);
344 345
}

346
template <class T>
347
void DoPrintElements(std::ostream& os, Object object, int length) {  // NOLINT
348
  const bool print_the_hole = std::is_same<T, FixedDoubleArray>::value;
349
  T array = T::cast(object);
350
  if (length == 0) return;
351
  int previous_index = 0;
352
  double previous_value = GetScalarElement(array, 0);
353 354
  double value = 0.0;
  int i;
355 356
  for (i = 1; i <= length; i++) {
    if (i < length) value = GetScalarElement(array, i);
357
    bool values_are_nan = std::isnan(previous_value) && std::isnan(value);
358
    if (i != length && (previous_value == value || values_are_nan) &&
359
        IsTheHoleAt(array, i - 1) == IsTheHoleAt(array, i)) {
360 361 362 363 364 365 366 367 368
      continue;
    }
    os << "\n";
    std::stringstream ss;
    ss << previous_index;
    if (previous_index != i - 1) {
      ss << '-' << (i - 1);
    }
    os << std::setw(12) << ss.str() << ": ";
369
    if (print_the_hole && IsTheHoleAt(array, i - 1)) {
370 371 372 373 374 375
      os << "<the_hole>";
    } else {
      os << previous_value;
    }
    previous_index = i;
    previous_value = value;
376 377 378
  }
}

379 380
template <typename ElementType>
void PrintTypedArrayElements(std::ostream& os, const ElementType* data_ptr,
381
                             size_t length, bool is_on_heap) {
382 383
  if (length == 0) return;
  size_t previous_index = 0;
384 385 386 387 388 389
  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;
  }

390 391 392 393 394 395 396 397 398 399 400 401 402
  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);
    }
403
    os << std::setw(12) << ss.str() << ": " << +previous_value;
404 405 406 407 408
    previous_index = i;
    previous_value = value;
  }
}

409
template <typename T>
410
void PrintFixedArrayElements(std::ostream& os, T array) {
411
  // Print in array notation for non-sparse arrays.
412
  Object previous_value = array.length() > 0 ? array.get(0) : Object();
413
  Object value;
414 415
  int previous_index = 0;
  int i;
416 417 418
  for (i = 1; i <= array.length(); i++) {
    if (i < array.length()) value = array.get(i);
    if (previous_value == value && i != array.length()) {
419 420 421 422 423 424 425 426 427 428 429 430 431 432
      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;
  }
}

433
void PrintDictionaryElements(std::ostream& os, FixedArrayBase elements) {
434
  // Print some internal fields
435
  NumberDictionary dict = NumberDictionary::cast(elements);
436
  if (dict.requires_slow_elements()) {
437 438
    os << "\n   - requires_slow_elements";
  } else {
439
    os << "\n   - max_number_key: " << dict.max_number_key();
440
  }
441
  dict.Print(os);
442 443
}

444
void PrintSloppyArgumentElements(std::ostream& os, ElementsKind kind,
445
                                 SloppyArgumentsElements elements) {
446 447
  FixedArray arguments_store = elements.arguments();
  os << "\n    0: context: " << Brief(elements.context())
448
     << "\n    1: arguments_store: " << Brief(arguments_store)
449
     << "\n    parameter to context slot map:";
450 451 452
  for (int i = 0; i < elements.length(); i++) {
    Object mapped_entry = elements.mapped_entries(i);
    os << "\n    " << i << ": param(" << i << "): " << Brief(mapped_entry);
453
    if (mapped_entry.IsTheHole()) {
Mathias Bynens's avatar
Mathias Bynens committed
454
      os << " in the arguments_store[" << i << "]";
455 456 457
    } else {
      os << " in the context";
    }
458
  }
459
  if (arguments_store.length() == 0) return;
460
  os << "\n }"
461
     << "\n - arguments_store: " << Brief(arguments_store) << " "
462
     << ElementsKindToString(arguments_store.map().elements_kind()) << " {";
463 464 465 466
  if (kind == FAST_SLOPPY_ARGUMENTS_ELEMENTS) {
    PrintFixedArrayElements(os, arguments_store);
  } else {
    DCHECK_EQ(kind, SLOW_SLOPPY_ARGUMENTS_ELEMENTS);
467
    PrintDictionaryElements(os, arguments_store);
468 469 470
  }
}

471 472
void PrintEmbedderData(const Isolate* isolate, std::ostream& os,
                       EmbedderDataSlot slot) {
473
  DisallowHeapAllocation no_gc;
474
  Object value = slot.load_tagged();
475 476
  os << Brief(value);
  void* raw_pointer;
477
  if (slot.ToAlignedPointer(isolate, &raw_pointer)) {
478 479 480 481
    os << ", aligned pointer: " << raw_pointer;
  }
}

482
}  // namespace
483

484
void JSObject::PrintElements(std::ostream& os) {  // NOLINT
485 486
  // Don't call GetElementsKind, its validation code can cause the printer to
  // fail when debugging.
487
  os << " - elements: " << Brief(elements()) << " {";
488
  switch (map().elements_kind()) {
489 490 491
    case HOLEY_SMI_ELEMENTS:
    case PACKED_SMI_ELEMENTS:
    case HOLEY_ELEMENTS:
492 493
    case HOLEY_FROZEN_ELEMENTS:
    case HOLEY_SEALED_ELEMENTS:
494
    case HOLEY_NONEXTENSIBLE_ELEMENTS:
495
    case PACKED_ELEMENTS:
496 497
    case PACKED_FROZEN_ELEMENTS:
    case PACKED_SEALED_ELEMENTS:
498
    case PACKED_NONEXTENSIBLE_ELEMENTS:
499
    case FAST_STRING_WRAPPER_ELEMENTS: {
500
      PrintFixedArrayElements(os, FixedArray::cast(elements()));
501 502
      break;
    }
503 504
    case HOLEY_DOUBLE_ELEMENTS:
    case PACKED_DOUBLE_ELEMENTS: {
505
      DoPrintElements<FixedDoubleArray>(os, elements(), elements().length());
506 507
      break;
    }
508

509 510 511
#define PRINT_ELEMENTS(Type, type, TYPE, elementType)                         \
  case TYPE##_ELEMENTS: {                                                     \
    size_t length = JSTypedArray::cast(*this).length();                       \
512
    bool is_on_heap = JSTypedArray::cast(*this).is_on_heap();                 \
513 514
    const elementType* data_ptr =                                             \
        static_cast<const elementType*>(JSTypedArray::cast(*this).DataPtr()); \
515
    PrintTypedArrayElements<elementType>(os, data_ptr, length, is_on_heap);   \
516
    break;                                                                    \
517
  }
518
      TYPED_ARRAYS(PRINT_ELEMENTS)
519 520
#undef PRINT_ELEMENTS

521
    case DICTIONARY_ELEMENTS:
522
    case SLOW_STRING_WRAPPER_ELEMENTS:
523
      PrintDictionaryElements(os, elements());
524
      break;
525
    case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
526
    case SLOW_SLOPPY_ARGUMENTS_ELEMENTS:
527
      PrintSloppyArgumentElements(os, map().elements_kind(),
528
                                  SloppyArgumentsElements::cast(elements()));
529
      break;
530 531
    case NO_ELEMENTS:
      break;
532
  }
533
  os << "\n }\n";
534 535
}

536
static void JSObjectPrintHeader(std::ostream& os, JSObject obj,
537
                                const char* id) {  // NOLINT
538 539
  Isolate* isolate = obj.GetIsolate();
  obj.PrintHeader(os, id);
540 541
  // Don't call GetElementsKind, its validation code can cause the printer to
  // fail when debugging.
542
  os << " [";
543
  if (obj.HasFastProperties()) {
544 545 546
    os << "FastProperties";
  } else {
    os << "DictionaryProperties";
547
  }
548
  PrototypeIterator iter(isolate, obj);
549
  os << "]\n - prototype: " << Brief(iter.GetCurrent());
550 551 552
  os << "\n - elements: " << Brief(obj.elements()) << " ["
     << ElementsKindToString(obj.map().elements_kind());
  if (obj.elements().IsCowArray()) os << " (COW)";
553
  os << "]";
554 555
  Object hash = obj.GetHash();
  if (hash.IsSmi()) {
556
    os << "\n - hash: " << Brief(hash);
557
  }
558 559
  if (obj.GetEmbedderFieldCount() > 0) {
    os << "\n - embedder fields: " << obj.GetEmbedderFieldCount();
560
  }
561 562
}

563
static void JSObjectPrintBody(std::ostream& os,
564
                              JSObject obj,  // NOLINT
565
                              bool print_elements = true) {
566
  os << "\n - properties: ";
567 568
  Object properties_or_hash = obj.raw_properties_or_hash();
  if (!properties_or_hash.IsSmi()) {
569 570 571
    os << Brief(properties_or_hash);
  }
  os << " {";
572
  if (obj.PrintProperties(os)) os << "\n ";
573
  os << "}\n";
574
  if (print_elements) {
575 576
    size_t length = obj.IsJSTypedArray() ? JSTypedArray::cast(obj).length()
                                         : obj.elements().length();
577
    if (length > 0) obj.PrintElements(os);
578
  }
579
  int embedder_fields = obj.GetEmbedderFieldCount();
580
  if (embedder_fields > 0) {
581
    const Isolate* isolate = GetIsolateForPtrCompr(obj);
582
    os << " - embedder fields = {";
583
    for (int i = 0; i < embedder_fields; i++) {
584
      os << "\n    ";
585
      PrintEmbedderData(isolate, os, EmbedderDataSlot(obj, i));
586 587 588
    }
    os << "\n }\n";
  }
589 590
}

591
void JSObject::JSObjectPrint(std::ostream& os) {  // NOLINT
592 593
  JSObjectPrintHeader(os, *this, nullptr);
  JSObjectPrintBody(os, *this);
594 595
}

596
void JSGeneratorObject::JSGeneratorObjectPrint(std::ostream& os) {  // NOLINT
597
  JSObjectPrintHeader(os, *this, "JSGeneratorObject");
598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625
  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;
626 627 628 629 630
    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())
631
                               : GetReadOnlyRoots().empty_string();
632 633 634 635

      os << "\n - source position: ";
      // Can't collect source positions here if not available as that would
      // allocate memory.
636 637
      if (fun_info.HasBytecodeArray() &&
          fun_info.GetBytecodeArray().HasSourcePositionTable()) {
638 639
        os << source_position();
        os << " (";
640 641 642
        script_name.PrintUC16(os);
        int lin = script.GetLineNumber(source_position()) + 1;
        int col = script.GetColumnNumber(source_position()) + 1;
643 644 645 646 647
        os << ", lin " << lin;
        os << ", col " << col;
      } else {
        os << "unavailable";
      }
648 649 650
      os << ")";
    }
  }
651
  os << "\n - register file: " << Brief(parameters_and_registers());
652
  JSObjectPrintBody(os, *this);
653 654
}

655
void JSArray::JSArrayPrint(std::ostream& os) {  // NOLINT
656
  JSObjectPrintHeader(os, *this, "JSArray");
657
  os << "\n - length: " << Brief(this->length());
658
  JSObjectPrintBody(os, *this);
659 660
}

661
void JSPromise::JSPromisePrint(std::ostream& os) {  // NOLINT
662
  JSObjectPrintHeader(os, *this, "JSPromise");
663
  os << "\n - status: " << JSPromise::Status(status());
664
  if (status() == Promise::kPending) {
665
    os << "\n - reactions: " << Brief(reactions());
666
  } else {
667
    os << "\n - result: " << Brief(result());
668
  }
669
  os << "\n - has_handler: " << has_handler();
670
  os << "\n - handled_hint: " << handled_hint();
671
  JSObjectPrintBody(os, *this);
672
}
673

674
void JSRegExp::JSRegExpPrint(std::ostream& os) {  // NOLINT
675
  JSObjectPrintHeader(os, *this, "JSRegExp");
676 677
  os << "\n - data: " << Brief(data());
  os << "\n - source: " << Brief(source());
678
  JSObjectPrintBody(os, *this);
679 680
}

681 682
void JSRegExpStringIterator::JSRegExpStringIteratorPrint(
    std::ostream& os) {  // NOLINT
683
  JSObjectPrintHeader(os, *this, "JSRegExpStringIterator");
684 685
  os << "\n - regex: " << Brief(iterating_reg_exp());
  os << "\n - string: " << Brief(iterated_string());
686 687 688
  os << "\n - done: " << done();
  os << "\n - global: " << global();
  os << "\n - unicode: " << unicode();
689
  JSObjectPrintBody(os, *this);
690
}
691

692
void Symbol::SymbolPrint(std::ostream& os) {  // NOLINT
693
  PrintHeader(os, "Symbol");
694
  os << "\n - hash: " << Hash();
695 696
  os << "\n - description: " << Brief(description());
  if (description().IsUndefined()) {
697
    os << " (" << PrivateSymbolToName() << ")";
698
  }
699
  os << "\n - private: " << is_private();
700 701
}

702
void DescriptorArray::DescriptorArrayPrint(std::ostream& os) {
703
  PrintHeader(os, "DescriptorArray");
704
  os << "\n - enum_cache: ";
705
  if (enum_cache().keys().length() == 0) {
706 707
    os << "empty";
  } else {
708 709 710
    os << enum_cache().keys().length();
    os << "\n   - keys: " << Brief(enum_cache().keys());
    os << "\n   - indices: " << Brief(enum_cache().indices());
711
  }
712
  os << "\n - nof slack descriptors: " << number_of_slack_descriptors();
713
  os << "\n - nof descriptors: " << number_of_descriptors();
714 715 716 717
  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);
718 719
  PrintDescriptors(os);
}
720

721
namespace {
722
void PrintFixedArrayWithHeader(std::ostream& os, FixedArray array,
723
                               const char* type) {
724 725
  array.PrintHeader(os, type);
  os << "\n - length: " << array.length();
726 727 728
  PrintFixedArrayElements(os, array);
  os << "\n";
}
729

730
template <typename T>
731
void PrintHashTableWithHeader(std::ostream& os, T table, const char* type) {
732 733 734 735 736
  table.PrintHeader(os, type);
  os << "\n - length: " << table.length();
  os << "\n - elements: " << table.NumberOfElements();
  os << "\n - deleted: " << table.NumberOfDeletedElements();
  os << "\n - capacity: " << table.Capacity();
737 738

  os << "\n - elements: {";
739
  for (InternalIndex i : table.IterateEntries()) {
740
    os << '\n'
741
       << std::setw(12) << i.as_int() << ": " << Brief(table.KeyAt(i)) << " -> "
742
       << Brief(table.ValueAt(i));
743 744 745 746
  }
  os << "\n }\n";
}

747 748
template <typename T>
void PrintWeakArrayElements(std::ostream& os, T* array) {
749
  // Print in array notation for non-sparse arrays.
750 751 752
  MaybeObject previous_value =
      array->length() > 0 ? array->Get(0) : MaybeObject(kNullAddress);
  MaybeObject value;
753 754 755 756 757 758 759 760 761 762 763 764 765
  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);
    }
766
    os << std::setw(12) << ss.str() << ": " << Brief(previous_value);
767 768 769 770 771
    previous_index = i;
    previous_value = value;
  }
}

772
}  // namespace
773

774
void EmbedderDataArray::EmbedderDataArrayPrint(std::ostream& os) {
775
  const Isolate* isolate = GetIsolateForPtrCompr(*this);
776 777
  PrintHeader(os, "EmbedderDataArray");
  os << "\n - length: " << length();
778 779 780
  EmbedderDataSlot start(*this, 0);
  EmbedderDataSlot end(*this, length());
  for (EmbedderDataSlot slot = start; slot < end; ++slot) {
781
    os << "\n    ";
782
    PrintEmbedderData(isolate, os, slot);
783 784 785 786 787
  }
  os << "\n";
}

void FixedArray::FixedArrayPrint(std::ostream& os) {
788
  PrintFixedArrayWithHeader(os, *this, "FixedArray");
789
}
790

791 792 793
namespace {
void PrintContextWithHeader(std::ostream& os, Context context,
                            const char* type) {
794 795 796 797 798
  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());
799 800 801 802 803
  PrintFixedArrayElements(os, context);
  os << "\n";
}
}  // namespace

804
void Context::ContextPrint(std::ostream& os) {
805
  PrintContextWithHeader(os, *this, "Context");
806 807 808
}

void NativeContext::NativeContextPrint(std::ostream& os) {
809
  PrintContextWithHeader(os, *this, "NativeContext");
810 811 812
  os << " - microtask_queue: " << microtask_queue() << "\n";
}

813
void ObjectHashTable::ObjectHashTablePrint(std::ostream& os) {
814
  PrintHashTableWithHeader(os, *this, "ObjectHashTable");
815
}
816

817
void NumberDictionary::NumberDictionaryPrint(std::ostream& os) {
818
  PrintHashTableWithHeader(os, *this, "NumberDictionary");
819 820
}

821
void EphemeronHashTable::EphemeronHashTablePrint(std::ostream& os) {
822
  PrintHashTableWithHeader(os, *this, "EphemeronHashTable");
823 824
}

825 826
void ObjectBoilerplateDescription::ObjectBoilerplateDescriptionPrint(
    std::ostream& os) {
827
  PrintFixedArrayWithHeader(os, *this, "ObjectBoilerplateDescription");
828 829
}

830
void PropertyArray::PropertyArrayPrint(std::ostream& os) {  // NOLINT
831
  PrintHeader(os, "PropertyArray");
832
  os << "\n - length: " << length();
833
  os << "\n - hash: " << Hash();
834
  PrintFixedArrayElements(os, *this);
835 836
  os << "\n";
}
837

838
void FixedDoubleArray::FixedDoubleArrayPrint(std::ostream& os) {  // NOLINT
839
  PrintHeader(os, "FixedDoubleArray");
840
  os << "\n - length: " << length();
841
  DoPrintElements<FixedDoubleArray>(os, *this, length());
842
  os << "\n";
843 844
}

845
void WeakFixedArray::WeakFixedArrayPrint(std::ostream& os) {
846 847 848 849
  PrintHeader(os, "WeakFixedArray");
  os << "\n - length: " << length() << "\n";
  PrintWeakArrayElements(os, this);
  os << "\n";
850
}
851

852
void WeakArrayList::WeakArrayListPrint(std::ostream& os) {
853 854 855 856 857
  PrintHeader(os, "WeakArrayList");
  os << "\n - capacity: " << capacity();
  os << "\n - length: " << length() << "\n";
  PrintWeakArrayElements(os, this);
  os << "\n";
858 859
}

860
void TransitionArray::TransitionArrayPrint(std::ostream& os) {  // NOLINT
861
  PrintHeader(os, "TransitionArray");
862
  PrintInternal(os);
863 864
}

865
void FeedbackCell::FeedbackCellPrint(std::ostream& os) {  // NOLINT
866
  PrintHeader(os, "FeedbackCell");
867 868
  ReadOnlyRoots roots = GetReadOnlyRoots();
  if (map() == roots.no_closures_cell_map()) {
869
    os << "\n - no closures";
870
  } else if (map() == roots.one_closure_cell_map()) {
871
    os << "\n - one closure";
872
  } else if (map() == roots.many_closures_cell_map()) {
873 874 875 876 877 878 879 880
    os << "\n - many closures";
  } else {
    os << "\n - Invalid FeedbackCell map";
  }
  os << " - value: " << Brief(value());
  os << "\n";
}

881
void FeedbackVectorSpec::Print() {
882
  StdoutStream os;
883

884
  FeedbackVectorSpecPrint(os);
885

886 887 888
  os << std::flush;
}

889 890
void FeedbackVectorSpec::FeedbackVectorSpecPrint(std::ostream& os) {  // NOLINT
  int slot_count = slots();
891 892 893 894 895 896
  os << " - slot_count: " << slot_count;
  if (slot_count == 0) {
    os << " (empty)\n";
    return;
  }

897
  for (int slot = 0; slot < slot_count;) {
898
    FeedbackSlotKind kind = GetKind(FeedbackSlot(slot));
899
    int entry_size = FeedbackMetadata::GetSlotSize(kind);
900 901 902 903 904 905
    DCHECK_LT(0, entry_size);
    os << "\n Slot #" << slot << " " << kind;
    slot += entry_size;
  }
  os << "\n";
}
906

907
void FeedbackMetadata::FeedbackMetadataPrint(std::ostream& os) {
908
  PrintHeader(os, "FeedbackMetadata");
909
  os << "\n - slot_count: " << slot_count();
910

911
  FeedbackMetadataIterator iter(*this);
912
  while (iter.HasNext()) {
913 914
    FeedbackSlot slot = iter.Next();
    FeedbackSlotKind kind = iter.kind();
915 916 917 918 919
    os << "\n Slot " << slot << " " << kind;
  }
  os << "\n";
}

920 921 922 923
void ClosureFeedbackCellArray::ClosureFeedbackCellArrayPrint(std::ostream& os) {
  PrintFixedArrayWithHeader(os, *this, "ClosureFeedbackCellArray");
}

924
void FeedbackVector::FeedbackVectorPrint(std::ostream& os) {  // NOLINT
925
  PrintHeader(os, "FeedbackVector");
926
  os << "\n - length: " << length();
927 928 929 930 931
  if (length() == 0) {
    os << " (empty)\n";
    return;
  }

932 933
  os << "\n - shared function info: " << Brief(shared_function_info());
  os << "\n - optimized code/marker: ";
934 935 936 937 938
  if (has_optimized_code()) {
    os << Brief(optimized_code());
  } else {
    os << optimization_marker();
  }
939
  os << "\n - invocation count: " << invocation_count();
940
  os << "\n - profiler ticks: " << profiler_ticks();
941

942
  FeedbackMetadataIterator iter(metadata());
943
  while (iter.HasNext()) {
944 945
    FeedbackSlot slot = iter.Next();
    FeedbackSlotKind kind = iter.kind();
946

947
    os << "\n - slot " << slot << " " << kind << " ";
948
    FeedbackSlotPrint(os, slot);
949

950
    int entry_size = iter.entry_size();
951
    if (entry_size > 0) os << " {";
952 953
    for (int i = 0; i < entry_size; i++) {
      int index = GetIndex(slot) + i;
954
      os << "\n     [" << index << "]: " << Brief(get(index));
955
    }
956
    if (entry_size > 0) os << "\n  }";
957 958 959 960
  }
  os << "\n";
}

961 962
void FeedbackVector::FeedbackSlotPrint(std::ostream& os,
                                       FeedbackSlot slot) {  // NOLINT
963
  FeedbackNexus nexus(*this, slot);
964
  nexus.Print(os);
965 966
}

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

1010
void Oddball::OddballPrint(std::ostream& os) {  // NOLINT
1011 1012 1013 1014 1015 1016 1017
  PrintHeapObjectHeaderWithoutMap(*this, os, "Oddball");
  os << ": ";
  String s = to_string();
  os << s.PrefixForDebugPrint();
  s.PrintUC16(os);
  os << s.SuffixForDebugPrint();
  os << std::endl;
1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048
}

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);
}

1049 1050
void JSPrimitiveWrapper::JSPrimitiveWrapperPrint(std::ostream& os) {  // NOLINT
  JSObjectPrintHeader(os, *this, "JSPrimitiveWrapper");
1051
  os << "\n - value: " << Brief(value());
1052
  JSObjectPrintBody(os, *this);
1053 1054
}

1055
void JSMessageObject::JSMessageObjectPrint(std::ostream& os) {  // NOLINT
1056
  JSObjectPrintHeader(os, *this, "JSMessageObject");
1057
  os << "\n - type: " << static_cast<int>(type());
1058
  os << "\n - arguments: " << Brief(argument());
1059 1060 1061 1062
  os << "\n - start_position: " << start_position();
  os << "\n - end_position: " << end_position();
  os << "\n - script: " << Brief(script());
  os << "\n - stack_frames: " << Brief(stack_frames());
1063
  JSObjectPrintBody(os, *this);
1064 1065
}

1066
void String::StringPrint(std::ostream& os) {  // NOLINT
1067 1068
  PrintHeapObjectHeaderWithoutMap(*this, os, "String");
  os << ": ";
1069 1070 1071
  os << PrefixForDebugPrint();
  PrintUC16(os, 0, length());
  os << SuffixForDebugPrint();
1072 1073
}

1074
void Name::NamePrint(std::ostream& os) {  // NOLINT
1075
  if (IsString()) {
1076
    String::cast(*this).StringPrint(os);
1077
  } else {
1078
    os << Brief(*this);
1079
  }
1080 1081
}

1082 1083
static const char* const weekdays[] = {"???", "Sun", "Mon", "Tue",
                                       "Wed", "Thu", "Fri", "Sat"};
1084

1085
void JSDate::JSDatePrint(std::ostream& os) {  // NOLINT
1086
  JSObjectPrintHeader(os, *this, "JSDate");
1087
  os << "\n - value: " << Brief(value());
1088
  if (!year().IsSmi()) {
1089
    os << "\n - time = NaN\n";
1090
  } else {
1091
    // TODO(svenpanne) Add some basic formatting to our streams.
1092
    ScopedVector<char> buf(100);
jgruber's avatar
jgruber committed
1093
    SNPrintF(buf, "\n - time = %s %04d/%02d/%02d %02d:%02d:%02d\n",
1094 1095 1096 1097 1098 1099 1100
             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);
1101
    os << buf.begin();
1102
  }
1103
  JSObjectPrintBody(os, *this);
1104 1105
}

1106
void JSProxy::JSProxyPrint(std::ostream& os) {  // NOLINT
1107
  PrintHeader(os, "JSProxy");
1108
  os << "\n - target: ";
1109
  target().ShortPrint(os);
1110
  os << "\n - handler: ";
1111
  handler().ShortPrint(os);
1112
  os << "\n";
1113 1114
}

1115
void JSSet::JSSetPrint(std::ostream& os) {  // NOLINT
1116
  JSObjectPrintHeader(os, *this, "JSSet");
1117
  os << " - table: " << Brief(table());
1118
  JSObjectPrintBody(os, *this);
1119 1120
}

1121
void JSMap::JSMapPrint(std::ostream& os) {  // NOLINT
1122
  JSObjectPrintHeader(os, *this, "JSMap");
1123
  os << " - table: " << Brief(table());
1124
  JSObjectPrintBody(os, *this);
1125 1126
}

1127
void JSCollectionIterator::JSCollectionIteratorPrint(
1128
    std::ostream& os, const char* name) {  // NOLINT
1129
  JSObjectPrintHeader(os, *this, name);
1130 1131
  os << "\n - table: " << Brief(table());
  os << "\n - index: " << Brief(index());
1132
  JSObjectPrintBody(os, *this);
1133 1134
}

1135
void JSSetIterator::JSSetIteratorPrint(std::ostream& os) {  // NOLINT
1136
  JSCollectionIteratorPrint(os, "JSSetIterator");
1137 1138
}

1139
void JSMapIterator::JSMapIteratorPrint(std::ostream& os) {  // NOLINT
1140
  JSCollectionIteratorPrint(os, "JSMapIterator");
1141 1142
}

1143 1144
void WeakCell::WeakCellPrint(std::ostream& os) {
  PrintHeader(os, "WeakCell");
1145
  os << "\n - finalization_registry: " << Brief(finalization_registry());
1146
  os << "\n - target: " << Brief(target());
1147
  os << "\n - holdings: " << Brief(holdings());
1148 1149
  os << "\n - prev: " << Brief(prev());
  os << "\n - next: " << Brief(next());
1150
  os << "\n - unregister_token: " << Brief(unregister_token());
1151 1152
  os << "\n - key_list_prev: " << Brief(key_list_prev());
  os << "\n - key_list_next: " << Brief(key_list_next());
1153 1154
}

1155 1156 1157 1158 1159 1160
void JSWeakRef::JSWeakRefPrint(std::ostream& os) {
  JSObjectPrintHeader(os, *this, "JSWeakRef");
  os << "\n - target: " << Brief(target());
  JSObjectPrintBody(os, *this);
}

1161 1162
void JSFinalizationRegistry::JSFinalizationRegistryPrint(std::ostream& os) {
  JSObjectPrintHeader(os, *this, "JSFinalizationRegistry");
1163
  os << "\n - native_context: " << Brief(native_context());
1164 1165
  os << "\n - cleanup: " << Brief(cleanup());
  os << "\n - active_cells: " << Brief(active_cells());
1166 1167 1168 1169 1170
  Object active_cell = active_cells();
  while (active_cell.IsWeakCell()) {
    os << "\n   - " << Brief(active_cell);
    active_cell = WeakCell::cast(active_cell).next();
  }
1171
  os << "\n - cleared_cells: " << Brief(cleared_cells());
1172 1173 1174 1175 1176
  Object cleared_cell = cleared_cells();
  while (cleared_cell.IsWeakCell()) {
    os << "\n   - " << Brief(cleared_cell);
    cleared_cell = WeakCell::cast(cleared_cell).next();
  }
1177
  os << "\n - key_map: " << Brief(key_map());
1178
  JSObjectPrintBody(os, *this);
1179 1180
}

1181
void JSWeakMap::JSWeakMapPrint(std::ostream& os) {  // NOLINT
1182
  JSObjectPrintHeader(os, *this, "JSWeakMap");
1183
  os << "\n - table: " << Brief(table());
1184
  JSObjectPrintBody(os, *this);
1185 1186
}

1187
void JSWeakSet::JSWeakSetPrint(std::ostream& os) {  // NOLINT
1188
  JSObjectPrintHeader(os, *this, "JSWeakSet");
1189
  os << "\n - table: " << Brief(table());
1190
  JSObjectPrintBody(os, *this);
1191 1192
}

1193
void JSArrayBuffer::JSArrayBufferPrint(std::ostream& os) {  // NOLINT
1194
  JSObjectPrintHeader(os, *this, "JSArrayBuffer");
1195
  os << "\n - backing_store: " << backing_store();
1196
  os << "\n - byte_length: " << byte_length();
1197
  if (is_external()) os << "\n - external";
1198 1199
  if (is_detachable()) os << "\n - detachable";
  if (was_detached()) os << "\n - detached";
1200
  if (is_shared()) os << "\n - shared";
1201
  JSObjectPrintBody(os, *this, !was_detached());
1202 1203
}

1204
void JSTypedArray::JSTypedArrayPrint(std::ostream& os) {  // NOLINT
1205
  JSObjectPrintHeader(os, *this, "JSTypedArray");
1206
  os << "\n - buffer: " << Brief(buffer());
1207 1208
  os << "\n - byte_offset: " << byte_offset();
  os << "\n - byte_length: " << byte_length();
1209
  os << "\n - length: " << length();
1210 1211 1212 1213 1214 1215
  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());
1216
  if (!buffer().IsJSArrayBuffer()) {
1217 1218 1219
    os << "\n <invalid buffer>\n";
    return;
  }
1220 1221
  if (WasDetached()) os << "\n - detached";
  JSObjectPrintBody(os, *this, !WasDetached());
1222 1223
}

1224
void JSArrayIterator::JSArrayIteratorPrint(std::ostream& os) {  // NOLING
1225
  JSObjectPrintHeader(os, *this, "JSArrayIterator");
1226 1227 1228
  os << "\n - iterated_object: " << Brief(iterated_object());
  os << "\n - next_index: " << Brief(next_index());
  os << "\n - kind: " << kind();
1229
  JSObjectPrintBody(os, *this);
1230 1231
}

1232
void JSDataView::JSDataViewPrint(std::ostream& os) {  // NOLINT
1233
  JSObjectPrintHeader(os, *this, "JSDataView");
1234
  os << "\n - buffer =" << Brief(buffer());
1235 1236
  os << "\n - byte_offset: " << byte_offset();
  os << "\n - byte_length: " << byte_length();
1237
  if (!buffer().IsJSArrayBuffer()) {
1238 1239 1240
    os << "\n <invalid buffer>";
    return;
  }
1241 1242
  if (WasDetached()) os << "\n - detached";
  JSObjectPrintBody(os, *this, !WasDetached());
1243 1244
}

1245
void JSBoundFunction::JSBoundFunctionPrint(std::ostream& os) {  // NOLINT
1246
  JSObjectPrintHeader(os, *this, "JSBoundFunction");
1247 1248 1249
  os << "\n - bound_target_function: " << Brief(bound_target_function());
  os << "\n - bound_this: " << Brief(bound_this());
  os << "\n - bound_arguments: " << Brief(bound_arguments());
1250
  JSObjectPrintBody(os, *this);
1251 1252
}

1253 1254
void JSFunction::JSFunctionPrint(std::ostream& os) {  // NOLINT
  Isolate* isolate = GetIsolate();
1255
  JSObjectPrintHeader(os, *this, "Function");
1256
  os << "\n - function prototype: ";
1257 1258 1259
  if (has_prototype_slot()) {
    if (has_prototype()) {
      os << Brief(prototype());
1260
      if (map().has_non_instance_prototype()) {
1261 1262 1263
        os << " (non-instance prototype)";
      }
    }
1264
    os << "\n - initial_map: ";
1265 1266 1267 1268
    if (has_initial_map()) os << Brief(initial_map());
  } else {
    os << "<no-prototype-slot>";
  }
1269
  os << "\n - shared_info: " << Brief(shared());
1270
  os << "\n - name: " << Brief(shared().Name());
1271 1272

  // Print Builtin name for builtin functions
1273
  int builtin_index = code().builtin_index();
1274 1275
  if (Builtins::IsBuiltinId(builtin_index) && !IsInterpreted()) {
    os << "\n - builtin: " << isolate->builtins()->name(builtin_index);
1276 1277
  }

1278
  os << "\n - formal_parameter_count: "
1279 1280
     << shared().internal_formal_parameter_count();
  if (shared().is_safe_to_skip_arguments_adaptor()) {
1281 1282
    os << "\n - safe_to_skip_arguments_adaptor";
  }
1283
  os << "\n - kind: " << shared().kind();
1284 1285
  os << "\n - context: " << Brief(context());
  os << "\n - code: " << Brief(code());
1286 1287
  if (IsInterpreted()) {
    os << "\n - interpreted";
1288 1289
    if (shared().HasBytecodeArray()) {
      os << "\n - bytecode: " << shared().GetBytecodeArray();
1290 1291
    }
  }
1292 1293
  if (WasmExportedFunction::IsWasmExportedFunction(*this)) {
    WasmExportedFunction function = WasmExportedFunction::cast(*this);
1294 1295
    os << "\n - Wasm instance: " << Brief(function.instance());
    os << "\n - Wasm function index: " << function.function_index();
1296 1297 1298
  }
  if (WasmJSFunction::IsWasmJSFunction(*this)) {
    WasmJSFunction function = WasmJSFunction::cast(*this);
1299
    os << "\n - Wasm wrapper around: " << Brief(function.GetCallable());
1300
  }
1301
  shared().PrintSourceCode(os);
1302
  JSObjectPrintBody(os, *this);
1303
  os << " - feedback vector: ";
1304
  if (!shared().HasFeedbackMetadata()) {
1305 1306
    os << "feedback metadata is not available in SFI\n";
  } else if (has_feedback_vector()) {
1307
    feedback_vector().FeedbackVectorPrint(os);
1308 1309 1310
  } else {
    os << "not available\n";
  }
1311 1312
}

1313 1314
void SharedFunctionInfo::PrintSourceCode(std::ostream& os) {
  if (HasSourceCode()) {
1315
    os << "\n - source code: ";
1316
    String source = String::cast(Script::cast(script()).source());
1317 1318
    int start = StartPosition();
    int length = EndPosition() - start;
1319
    std::unique_ptr<char[]> source_string = source.ToCString(
1320
        DISALLOW_NULLS, FAST_STRING_TRAVERSAL, start, length, nullptr);
1321 1322 1323 1324
    os << source_string.get();
  }
}

1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340
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.
}

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

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

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

1419
void PropertyCell::PropertyCellPrint(std::ostream& os) {  // NOLINT
1420
  PrintHeader(os, "PropertyCell");
1421
  os << "\n - name: ";
1422
  name().NamePrint(os);
1423
  os << "\n - value: " << Brief(value());
1424 1425
  os << "\n - details: ";
  property_details().PrintAsSlowTo(os);
1426 1427
  PropertyCellType cell_type = property_details().cell_type();
  os << "\n - cell_type: ";
1428
  if (value().IsTheHole()) {
1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 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
    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;
    }
  }
1466
  os << "\n";
1467 1468
}

1469
void Code::CodePrint(std::ostream& os) {  // NOLINT
1470
  PrintHeader(os, "Code");
1471
  os << "\n";
1472
#ifdef ENABLE_DISASSEMBLER
1473
  Disassemble(nullptr, os, GetIsolate());
1474 1475 1476
#endif
}

1477
void CodeDataContainer::CodeDataContainerPrint(std::ostream& os) {  // NOLINT
1478
  PrintHeader(os, "CodeDataContainer");
1479 1480 1481
  os << "\n - kind_specific_flags: " << kind_specific_flags();
  os << "\n";
}
1482

1483
void Foreign::ForeignPrint(std::ostream& os) {  // NOLINT
1484 1485
  PrintHeader(os, "Foreign");
  os << "\n - foreign address : " << reinterpret_cast<void*>(foreign_address());
1486
  os << "\n";
1487 1488
}

1489
void CallbackTask::CallbackTaskPrint(std::ostream& os) {  // NOLINT
1490
  PrintHeader(os, "CallbackTask");
1491 1492 1493 1494 1495 1496
  os << "\n - callback: " << Brief(callback());
  os << "\n - data: " << Brief(data());
  os << "\n";
}

void CallableTask::CallableTaskPrint(std::ostream& os) {  // NOLINT
1497
  PrintHeader(os, "CallableTask");
1498 1499
  os << "\n - context: " << Brief(context());
  os << "\n - callable: " << Brief(callable());
1500 1501 1502
  os << "\n";
}

1503
void PromiseFulfillReactionJobTask::PromiseFulfillReactionJobTaskPrint(
1504
    std::ostream& os) {  // NOLINT
1505
  PrintHeader(os, "PromiseFulfillReactionJobTask");
1506 1507 1508
  os << "\n - argument: " << Brief(argument());
  os << "\n - context: " << Brief(context());
  os << "\n - handler: " << Brief(handler());
1509
  os << "\n - promise_or_capability: " << Brief(promise_or_capability());
1510 1511 1512 1513 1514
  os << "\n";
}

void PromiseRejectReactionJobTask::PromiseRejectReactionJobTaskPrint(
    std::ostream& os) {  // NOLINT
1515
  PrintHeader(os, "PromiseRejectReactionJobTask");
1516 1517 1518
  os << "\n - argument: " << Brief(argument());
  os << "\n - context: " << Brief(context());
  os << "\n - handler: " << Brief(handler());
1519
  os << "\n - promise_or_capability: " << Brief(promise_or_capability());
1520 1521 1522 1523 1524
  os << "\n";
}

void PromiseResolveThenableJobTask::PromiseResolveThenableJobTaskPrint(
    std::ostream& os) {  // NOLINT
1525
  PrintHeader(os, "PromiseResolveThenableJobTask");
1526 1527
  os << "\n - context: " << Brief(context());
  os << "\n - promise_to_resolve: " << Brief(promise_to_resolve());
1528
  os << "\n - then: " << Brief(then());
1529 1530 1531 1532 1533
  os << "\n - thenable: " << Brief(thenable());
  os << "\n";
}

void PromiseCapability::PromiseCapabilityPrint(std::ostream& os) {  // NOLINT
1534
  PrintHeader(os, "PromiseCapability");
1535
  os << "\n - promise: " << Brief(promise());
1536 1537 1538 1539 1540
  os << "\n - resolve: " << Brief(resolve());
  os << "\n - reject: " << Brief(reject());
  os << "\n";
}

1541
void PromiseReaction::PromiseReactionPrint(std::ostream& os) {  // NOLINT
1542
  PrintHeader(os, "PromiseReaction");
1543 1544 1545
  os << "\n - next: " << Brief(next());
  os << "\n - reject_handler: " << Brief(reject_handler());
  os << "\n - fulfill_handler: " << Brief(fulfill_handler());
1546
  os << "\n - promise_or_capability: " << Brief(promise_or_capability());
1547 1548 1549
  os << "\n";
}

1550 1551
void AsyncGeneratorRequest::AsyncGeneratorRequestPrint(
    std::ostream& os) {  // NOLINT
1552
  PrintHeader(os, "AsyncGeneratorRequest");
1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570
  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";
}

1571 1572 1573
void SourceTextModuleInfoEntry::SourceTextModuleInfoEntryPrint(
    std::ostream& os) {  // NOLINT
  PrintHeader(os, "SourceTextModuleInfoEntry");
1574 1575 1576 1577 1578 1579 1580 1581 1582 1583
  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";
}

1584 1585 1586 1587 1588 1589
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());
}

1590
void Module::ModulePrint(std::ostream& os) {  // NOLINT
1591 1592
  if (this->IsSourceTextModule()) {
    SourceTextModule::cast(*this).SourceTextModulePrint(os);
1593 1594
  } else if (this->IsSyntheticModule()) {
    SyntheticModule::cast(*this).SyntheticModulePrint(os);
1595 1596 1597 1598 1599 1600 1601 1602
  } else {
    UNREACHABLE();
  }
}

void SourceTextModule::SourceTextModulePrint(std::ostream& os) {  // NOLINT
  PrintHeader(os, "SourceTextModule");
  PrintModuleFields(*this, os);
1603
  os << "\n - origin: " << Brief(script().GetNameOrSourceURL());
1604
  os << "\n - code: " << Brief(code());
1605
  os << "\n - requested_modules: " << Brief(requested_modules());
1606
  os << "\n - script: " << Brief(script());
1607
  os << "\n - import_meta: " << Brief(import_meta());
1608 1609
  os << "\n";
}
1610

1611 1612 1613 1614 1615 1616 1617
void SyntheticModule::SyntheticModulePrint(std::ostream& os) {  // NOLINT
  PrintHeader(os, "SyntheticModule");
  PrintModuleFields(*this, os);
  os << "\n - export_names: " << Brief(export_names());
  os << "\n";
}

1618
void JSModuleNamespace::JSModuleNamespacePrint(std::ostream& os) {  // NOLINT
1619
  JSObjectPrintHeader(os, *this, "JSModuleNamespace");
1620
  os << "\n - module: " << Brief(module());
1621
  JSObjectPrintBody(os, *this);
1622 1623
}

1624
void PrototypeInfo::PrototypeInfoPrint(std::ostream& os) {  // NOLINT
1625
  PrintHeader(os, "PrototypeInfo");
1626
  os << "\n - module namespace: " << Brief(module_namespace());
1627
  os << "\n - prototype users: " << Brief(prototype_users());
1628
  os << "\n - registry slot: " << registry_slot();
1629
  os << "\n - object create map: " << Brief(object_create_map());
1630
  os << "\n - should_be_fast_map: " << should_be_fast_map();
1631 1632 1633
  os << "\n";
}

1634 1635 1636 1637 1638 1639 1640
void ClassPositions::ClassPositionsPrint(std::ostream& os) {  // NOLINT
  PrintHeader(os, "ClassPositions");
  os << "\n - start position: " << start();
  os << "\n - end position: " << end();
  os << "\n";
}

1641 1642
void ArrayBoilerplateDescription::ArrayBoilerplateDescriptionPrint(
    std::ostream& os) {  // NOLINT
1643
  PrintHeader(os, "ArrayBoilerplateDescription");
1644 1645 1646 1647 1648
  os << "\n - elements kind: " << elements_kind();
  os << "\n - constant elements: " << Brief(constant_elements());
  os << "\n";
}

1649
void AsmWasmData::AsmWasmDataPrint(std::ostream& os) {  // NOLINT
1650
  PrintHeader(os, "AsmWasmData");
1651 1652
  os << "\n - native module: " << Brief(managed_native_module());
  os << "\n - export_wrappers: " << Brief(export_wrappers());
1653
  os << "\n - uses bitset: " << uses_bitset().value();
1654 1655 1656
  os << "\n";
}

1657 1658 1659 1660 1661 1662 1663
void WasmTypeInfo::WasmTypeInfoPrint(std::ostream& os) {  // NOLINT
  PrintHeader(os, "WasmTypeInfo");
  os << "\n - type address: " << reinterpret_cast<void*>(foreign_address());
  os << "\n - parent: " << Brief(parent());
  os << "\n";
}

1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685
void WasmStruct::WasmStructPrint(std::ostream& os) {  // NOLINT
  PrintHeader(os, "WasmStruct");
  wasm::StructType* struct_type = type();
  os << "\n - fields (" << struct_type->field_count() << "):";
  for (uint32_t i = 0; i < struct_type->field_count(); i++) {
    wasm::ValueType field = struct_type->field(i);
    os << "\n   - " << field.short_name() << ": ";
    uint32_t field_offset = struct_type->field_offset(i);
    Address field_address = RawField(field_offset).address();
    switch (field.kind()) {
      case wasm::ValueType::kI32:
        os << base::ReadUnalignedValue<int32_t>(field_address);
        break;
      case wasm::ValueType::kI64:
        os << base::ReadUnalignedValue<int64_t>(field_address);
        break;
      case wasm::ValueType::kF32:
        os << base::ReadUnalignedValue<float>(field_address);
        break;
      case wasm::ValueType::kF64:
        os << base::ReadUnalignedValue<double>(field_address);
        break;
1686 1687
      case wasm::ValueType::kI8:
      case wasm::ValueType::kI16:
1688 1689 1690
      case wasm::ValueType::kS128:
      case wasm::ValueType::kRef:
      case wasm::ValueType::kOptRef:
1691
      case wasm::ValueType::kRtt:
1692 1693 1694 1695 1696 1697 1698 1699 1700
      case wasm::ValueType::kBottom:
      case wasm::ValueType::kStmt:
        UNIMPLEMENTED();  // TODO(7748): Implement.
        break;
    }
  }
  os << "\n";
}

1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724
void WasmArray::WasmArrayPrint(std::ostream& os) {  // NOLINT
  PrintHeader(os, "WasmArray");
  wasm::ArrayType* array_type = type();
  uint32_t len = length();
  os << "\n - type: " << array_type->element_type().type_name();
  os << "\n - length: " << len;
  Address data_ptr = ptr() + WasmArray::kHeaderSize - kHeapObjectTag;
  switch (array_type->element_type().kind()) {
    case wasm::ValueType::kI32:
      PrintTypedArrayElements(os, reinterpret_cast<int32_t*>(data_ptr), len,
                              true);
      break;
    case wasm::ValueType::kI64:
      PrintTypedArrayElements(os, reinterpret_cast<int64_t*>(data_ptr), len,
                              true);
      break;
    case wasm::ValueType::kF32:
      PrintTypedArrayElements(os, reinterpret_cast<float*>(data_ptr), len,
                              true);
      break;
    case wasm::ValueType::kF64:
      PrintTypedArrayElements(os, reinterpret_cast<double*>(data_ptr), len,
                              true);
      break;
1725 1726
    case wasm::ValueType::kI8:
    case wasm::ValueType::kI16:
1727 1728 1729
    case wasm::ValueType::kS128:
    case wasm::ValueType::kRef:
    case wasm::ValueType::kOptRef:
1730
    case wasm::ValueType::kRtt:
1731 1732 1733 1734 1735 1736 1737 1738
    case wasm::ValueType::kBottom:
    case wasm::ValueType::kStmt:
      UNIMPLEMENTED();  // TODO(7748): Implement.
      break;
  }
  os << "\n";
}

1739
void WasmExceptionTag::WasmExceptionTagPrint(std::ostream& os) {  // NOLINT
1740
  PrintHeader(os, "WasmExceptionTag");
1741 1742 1743 1744
  os << "\n - index: " << index();
  os << "\n";
}

1745
void WasmInstanceObject::WasmInstanceObjectPrint(std::ostream& os) {  // NOLINT
1746
  JSObjectPrintHeader(os, *this, "WasmInstanceObject");
1747 1748 1749
  os << "\n - module_object: " << Brief(module_object());
  os << "\n - exports_object: " << Brief(exports_object());
  os << "\n - native_context: " << Brief(native_context());
1750 1751 1752
  if (has_memory_object()) {
    os << "\n - memory_object: " << Brief(memory_object());
  }
1753 1754 1755 1756 1757
  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());
1758 1759 1760 1761 1762
  }
  if (has_imported_mutable_globals_buffers()) {
    os << "\n - imported_mutable_globals_buffers: "
       << Brief(imported_mutable_globals_buffers());
  }
1763 1764
  for (int i = 0; i < tables().length(); i++) {
    os << "\n - table " << i << ": " << Brief(tables().get(i));
1765
  }
1766 1767 1768 1769
  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());
1770 1771 1772 1773 1774
  }
  if (has_managed_native_allocations()) {
    os << "\n - managed_native_allocations: "
       << Brief(managed_native_allocations());
  }
1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787
  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());
1788
  JSObjectPrintBody(os, *this);
1789 1790 1791
  os << "\n";
}

1792 1793
void WasmExportedFunctionData::WasmExportedFunctionDataPrint(
    std::ostream& os) {  // NOLINT
1794
  PrintHeader(os, "WasmExportedFunctionData");
1795 1796
  os << "\n - wrapper_code: " << Brief(wrapper_code());
  os << "\n - instance: " << Brief(instance());
1797
  os << "\n - jump_table_offset: " << jump_table_offset();
1798 1799 1800 1801
  os << "\n - function_index: " << function_index();
  os << "\n";
}

1802 1803 1804 1805 1806 1807
void WasmJSFunctionData::WasmJSFunctionDataPrint(std::ostream& os) {  // NOLINT
  PrintHeader(os, "WasmJSFunctionData");
  os << "\n - wrapper_code: " << Brief(wrapper_code());
  os << "\n";
}

1808
void WasmModuleObject::WasmModuleObjectPrint(std::ostream& os) {  // NOLINT
1809
  PrintHeader(os, "WasmModuleObject");
1810
  os << "\n - module: " << module();
1811 1812 1813
  os << "\n - native module: " << native_module();
  os << "\n - export wrappers: " << Brief(export_wrappers());
  os << "\n - script: " << Brief(script());
1814 1815 1816
  os << "\n";
}

1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827
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");
1828 1829 1830 1831 1832
  if (type().is_reference_type()) {
    os << "\n - tagged_buffer: " << Brief(tagged_buffer());
  } else {
    os << "\n - untagged_buffer: " << Brief(untagged_buffer());
  }
1833
  os << "\n - offset: " << offset();
1834 1835
  os << "\n - raw_type: " << raw_type();
  os << "\n - is_mutable: " << is_mutable();
1836
  os << "\n - type: " << type().kind();
1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856
  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";
}

1857
void LoadHandler::LoadHandlerPrint(std::ostream& os) {  // NOLINT
1858
  PrintHeader(os, "LoadHandler");
1859 1860 1861
  // TODO(ishell): implement printing based on handler kind
  os << "\n - handler: " << Brief(smi_handler());
  os << "\n - validity_cell: " << Brief(validity_cell());
1862 1863
  int data_count = data_field_count();
  if (data_count >= 1) {
1864
    os << "\n - data1: " << Brief(data1());
1865 1866
  }
  if (data_count >= 2) {
1867
    os << "\n - data2: " << Brief(data2());
1868
  }
1869
  if (data_count >= 3) {
1870
    os << "\n - data3: " << Brief(data3());
1871
  }
1872 1873 1874 1875
  os << "\n";
}

void StoreHandler::StoreHandlerPrint(std::ostream& os) {  // NOLINT
1876
  PrintHeader(os, "StoreHandler");
1877 1878 1879
  // TODO(ishell): implement printing based on handler kind
  os << "\n - handler: " << Brief(smi_handler());
  os << "\n - validity_cell: " << Brief(validity_cell());
1880 1881
  int data_count = data_field_count();
  if (data_count >= 1) {
1882
    os << "\n - data1: " << Brief(data1());
1883 1884
  }
  if (data_count >= 2) {
1885
    os << "\n - data2: " << Brief(data2());
1886
  }
1887
  if (data_count >= 3) {
1888
    os << "\n - data3: " << Brief(data3());
1889
  }
1890 1891 1892
  os << "\n";
}

1893
void AccessorPair::AccessorPairPrint(std::ostream& os) {  // NOLINT
1894
  PrintHeader(os, "AccessorPair");
1895 1896 1897 1898 1899
  os << "\n - getter: " << Brief(getter());
  os << "\n - setter: " << Brief(setter());
  os << "\n";
}

1900
void CallHandlerInfo::CallHandlerInfoPrint(std::ostream& os) {  // NOLINT
1901
  PrintHeader(os, "CallHandlerInfo");
1902 1903 1904 1905
  os << "\n - callback: " << Brief(callback());
  os << "\n - js_callback: " << Brief(js_callback());
  os << "\n - data: " << Brief(data());
  os << "\n - side_effect_free: "
1906
     << (IsSideEffectFreeCallHandlerInfo() ? "true" : "false");
1907 1908
  os << "\n";
}
1909

1910 1911
void FunctionTemplateInfo::FunctionTemplateInfoPrint(
    std::ostream& os) {  // NOLINT
1912
  PrintHeader(os, "FunctionTemplateInfo");
1913
  os << "\n - class name: " << Brief(class_name());
1914 1915
  os << "\n - tag: " << tag();
  os << "\n - serial_number: " << serial_number();
1916
  os << "\n - property_list: " << Brief(property_list());
1917 1918 1919
  os << "\n - call_code: " << Brief(call_code());
  os << "\n - property_accessors: " << Brief(property_accessors());
  os << "\n - signature: " << Brief(signature());
1920
  os << "\n - cached_property_name: " << Brief(cached_property_name());
1921 1922
  os << "\n - undetectable: " << (undetectable() ? "true" : "false");
  os << "\n - need_access_check: " << (needs_access_check() ? "true" : "false");
1923
  os << "\n - instantiated: " << (instantiated() ? "true" : "false");
1924
  os << "\n - rare_data: " << Brief(rare_data());
1925 1926 1927
  os << "\n";
}

1928 1929 1930 1931
void WasmCapiFunctionData::WasmCapiFunctionDataPrint(
    std::ostream& os) {  // NOLINT
  PrintHeader(os, "WasmCapiFunctionData");
  os << "\n - call_target: " << call_target();
1932
  os << "\n - embedder_data: " << Brief(embedder_data());
1933 1934 1935 1936 1937
  os << "\n - wrapper_code: " << Brief(wrapper_code());
  os << "\n - serialized_signature: " << Brief(serialized_signature());
  os << "\n";
}

1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951
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";
}

1952
void ObjectTemplateInfo::ObjectTemplateInfoPrint(std::ostream& os) {  // NOLINT
1953
  PrintHeader(os, "ObjectTemplateInfo");
1954 1955
  os << "\n - tag: " << tag();
  os << "\n - serial_number: " << serial_number();
1956 1957 1958
  os << "\n - property_list: " << Brief(property_list());
  os << "\n - property_accessors: " << Brief(property_accessors());
  os << "\n - constructor: " << Brief(constructor());
1959
  os << "\n - embedder_field_count: " << embedder_field_count();
1960
  os << "\n - immutable_proto: " << (immutable_proto() ? "true" : "false");
1961 1962 1963
  os << "\n";
}

1964
void AllocationSite::AllocationSitePrint(std::ostream& os) {  // NOLINT
1965
  PrintHeader(os, "AllocationSite");
1966
  if (this->HasWeakNext()) os << "\n - weak_next: " << Brief(weak_next());
1967 1968 1969 1970 1971 1972 1973 1974 1975
  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: ";
1976
  if (!PointsToLiteral()) {
1977
    ElementsKind kind = GetElementsKind();
1978
    os << "Array allocation with ElementsKind " << ElementsKindToString(kind);
1979
  } else if (boilerplate().IsJSArray()) {
1980
    os << "Array literal with boilerplate " << Brief(boilerplate());
1981
  } else {
1982
    os << "Object literal with boilerplate " << Brief(boilerplate());
1983
  }
1984
  os << "\n";
1985 1986
}

1987
void AllocationMemento::AllocationMementoPrint(std::ostream& os) {  // NOLINT
1988
  PrintHeader(os, "AllocationMemento");
1989
  os << "\n - allocation site: ";
1990
  if (IsValid()) {
1991
    GetAllocationSite().AllocationSitePrint(os);
1992
  } else {
1993
    os << "<invalid>\n";
1994 1995 1996
  }
}

1997
void Script::ScriptPrint(std::ostream& os) {  // NOLINT
1998
  PrintHeader(os, "Script");
1999 2000
  os << "\n - source: " << Brief(source());
  os << "\n - name: " << Brief(name());
2001 2002 2003 2004
  os << "\n - line_offset: " << line_offset();
  os << "\n - column_offset: " << column_offset();
  os << "\n - type: " << type();
  os << "\n - id: " << id();
2005 2006 2007
  os << "\n - context data: " << Brief(context_data());
  os << "\n - compilation type: " << compilation_type();
  os << "\n - line ends: " << Brief(line_ends());
2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019
  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();
2020
  }
2021
  os << "\n - shared function infos: " << Brief(shared_function_infos());
2022 2023 2024
  os << "\n";
}

2025
#ifdef V8_INTL_SUPPORT
2026
void JSV8BreakIterator::JSV8BreakIteratorPrint(std::ostream& os) {  // NOLINT
2027
  JSObjectPrintHeader(os, *this, "JSV8BreakIterator");
2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038
  os << "\n - locale: " << Brief(locale());
  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";
}

2039
void JSCollator::JSCollatorPrint(std::ostream& os) {  // NOLINT
2040
  JSObjectPrintHeader(os, *this, "JSCollator");
2041
  os << "\n - icu collator: " << Brief(icu_collator());
2042
  os << "\n - bound compare: " << Brief(bound_compare());
2043
  JSObjectPrintBody(os, *this);
2044 2045
}

2046
void JSDateTimeFormat::JSDateTimeFormatPrint(std::ostream& os) {  // NOLINT
2047
  JSObjectPrintHeader(os, *this, "JSDateTimeFormat");
2048
  os << "\n - locale: " << Brief(locale());
2049
  os << "\n - icu locale: " << Brief(icu_locale());
2050
  os << "\n - icu simple date format: " << Brief(icu_simple_date_format());
2051
  os << "\n - icu date interval format: " << Brief(icu_date_interval_format());
2052
  os << "\n - bound format: " << Brief(bound_format());
2053
  os << "\n - hour cycle: " << HourCycleAsString();
2054
  JSObjectPrintBody(os, *this);
2055 2056
}

2057 2058 2059 2060 2061 2062 2063 2064
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);
}

2065
void JSListFormat::JSListFormatPrint(std::ostream& os) {  // NOLINT
2066
  JSObjectPrintHeader(os, *this, "JSListFormat");
2067 2068 2069
  os << "\n - locale: " << Brief(locale());
  os << "\n - style: " << StyleAsString();
  os << "\n - type: " << TypeAsString();
2070
  os << "\n - icu formatter: " << Brief(icu_formatter());
2071
  JSObjectPrintBody(os, *this);
2072 2073
}

2074
void JSLocale::JSLocalePrint(std::ostream& os) {  // NOLINT
2075
  JSObjectPrintHeader(os, *this, "JSLocale");
2076 2077
  os << "\n - icu locale: " << Brief(icu_locale());
  JSObjectPrintBody(os, *this);
2078
}
2079

2080
void JSNumberFormat::JSNumberFormatPrint(std::ostream& os) {  // NOLINT
2081
  JSObjectPrintHeader(os, *this, "JSNumberFormat");
2082
  os << "\n - locale: " << Brief(locale());
2083
  os << "\n - icu_number_formatter: " << Brief(icu_number_formatter());
2084
  os << "\n - bound_format: " << Brief(bound_format());
2085
  JSObjectPrintBody(os, *this);
2086 2087
}

2088
void JSPluralRules::JSPluralRulesPrint(std::ostream& os) {  // NOLINT
2089
  JSObjectPrintHeader(os, *this, "JSPluralRules");
2090
  os << "\n - locale: " << Brief(locale());
2091
  os << "\n - type: " << TypeAsString();
2092
  os << "\n - icu plural rules: " << Brief(icu_plural_rules());
2093
  os << "\n - icu_number_formatter: " << Brief(icu_number_formatter());
2094
  JSObjectPrintBody(os, *this);
2095 2096
}

2097 2098
void JSRelativeTimeFormat::JSRelativeTimeFormatPrint(
    std::ostream& os) {  // NOLINT
2099
  JSObjectPrintHeader(os, *this, "JSRelativeTimeFormat");
2100
  os << "\n - locale: " << Brief(locale());
2101
  os << "\n - numberingSystem: " << Brief(numberingSystem());
2102
  os << "\n - numeric: " << NumericAsString();
2103
  os << "\n - icu formatter: " << Brief(icu_formatter());
2104 2105
  os << "\n";
}
2106

2107
void JSSegmentIterator::JSSegmentIteratorPrint(std::ostream& os) {  // NOLINT
2108
  JSObjectPrintHeader(os, *this, "JSSegmentIterator");
2109 2110 2111 2112 2113 2114
  os << "\n - icu break iterator: " << Brief(icu_break_iterator());
  os << "\n - unicode string: " << Brief(unicode_string());
  os << "\n - granularity: " << GranularityAsString();
  os << "\n";
}

2115
void JSSegmenter::JSSegmenterPrint(std::ostream& os) {  // NOLINT
2116
  JSObjectPrintHeader(os, *this, "JSSegmenter");
2117 2118
  os << "\n - locale: " << Brief(locale());
  os << "\n - granularity: " << GranularityAsString();
2119
  os << "\n - icu break iterator: " << Brief(icu_break_iterator());
2120
  JSObjectPrintBody(os, *this);
2121
}
2122 2123
#endif  // V8_INTL_SUPPORT

2124
namespace {
2125
void PrintScopeInfoList(ScopeInfo scope_info, std::ostream& os,
2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136
                        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 << ": ";
2137
    String::cast(scope_info.get(start)).ShortPrint(os);
2138 2139 2140 2141 2142 2143 2144
    os << "\n";
  }
  os << "  }";
}
}  // namespace

void ScopeInfo::ScopeInfoPrint(std::ostream& os) {  // NOLINT
2145
  PrintHeader(os, "ScopeInfo");
2146
  if (length() == 0) {
2147
    os << "\n - length = 0\n";
2148 2149
    return;
  }
2150 2151 2152 2153
  int flags = Flags();

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

2155
  os << "\n - scope type: " << scope_type();
2156
  if (SloppyEvalCanExtendVars()) os << "\n - sloppy eval";
2157
  os << "\n - language mode: " << language_mode();
2158 2159
  if (is_declaration_scope()) os << "\n - declaration scope";
  if (HasReceiver()) {
2160
    os << "\n - receiver: " << ReceiverVariableBits::decode(flags);
2161
  }
2162
  if (HasClassBrand()) os << "\n - has class brand";
2163
  if (HasSavedClassVariableIndex()) os << "\n - has saved class variable index";
2164
  if (HasNewTarget()) os << "\n - needs new target";
2165
  if (HasFunctionName()) {
2166
    os << "\n - function name(" << FunctionVariableBits::decode(flags) << "): ";
2167
    FunctionName().ShortPrint(os);
2168 2169 2170 2171
  }
  if (IsAsmModule()) os << "\n - asm module";
  if (HasSimpleParameters()) os << "\n - simple parameters";
  os << "\n - function kind: " << function_kind();
2172 2173 2174
  if (HasOuterScopeInfo()) {
    os << "\n - outer scope info: " << Brief(OuterScopeInfo());
  }
Dan Elphick's avatar
Dan Elphick committed
2175 2176
  if (HasLocalsBlockList()) {
    os << "\n - locals blocklist: " << Brief(LocalsBlockList());
2177
  }
2178
  if (HasFunctionName()) {
2179
    os << "\n - function name: " << Brief(FunctionName());
2180
  }
2181 2182 2183
  if (HasInferredFunctionName()) {
    os << "\n - inferred function name: " << Brief(InferredFunctionName());
  }
2184 2185
  if (HasContextExtensionSlot()) {
    os << "\n - has context extension slot";
2186
  }
2187

2188
  if (HasPositionInfo()) {
2189 2190
    os << "\n - start position: " << StartPosition();
    os << "\n - end position: " << EndPosition();
2191
  }
2192 2193
  os << "\n - length: " << length();
  if (length() > 0) {
2194
    PrintScopeInfoList(*this, os, "context slots", Context::MIN_CONTEXT_SLOTS,
2195 2196 2197 2198 2199
                       ContextLocalNamesIndex(), ContextLocalCount());
    // TODO(neis): Print module stuff if present.
  }
  os << "\n";
}
2200

2201 2202 2203 2204 2205
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());
2206
  os << "\n";
2207
}
2208

2209
void StackFrameInfo::StackFrameInfoPrint(std::ostream& os) {  // NOLINT
2210
  PrintHeader(os, "StackFrame");
2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221
  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";
}
2222

2223 2224 2225 2226 2227 2228 2229 2230
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;
  }
}

2231
void LayoutDescriptor::Print() {
2232
  StdoutStream os;
2233 2234 2235 2236
  this->Print(os);
  os << std::flush;
}

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

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

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

2282 2283 2284
void UncompiledDataWithoutPreparseData::UncompiledDataWithoutPreparseDataPrint(
    std::ostream& os) {  // NOLINT
  PrintHeader(os, "UncompiledDataWithoutPreparseData");
2285 2286 2287 2288 2289
  os << "\n - start position: " << start_position();
  os << "\n - end position: " << end_position();
  os << "\n";
}

2290
void UncompiledDataWithPreparseData::UncompiledDataWithPreparseDataPrint(
2291
    std::ostream& os) {  // NOLINT
2292
  PrintHeader(os, "UncompiledDataWithPreparseData");
2293 2294
  os << "\n - start position: " << start_position();
  os << "\n - end position: " << end_position();
2295
  os << "\n - preparse_data: " << Brief(preparse_data());
2296 2297 2298
  os << "\n";
}

2299
void InterpreterData::InterpreterDataPrint(std::ostream& os) {  // NOLINT
2300
  PrintHeader(os, "InterpreterData");
2301 2302 2303 2304 2305
  os << "\n - bytecode_array: " << Brief(bytecode_array());
  os << "\n - interpreter_trampoline: " << Brief(interpreter_trampoline());
  os << "\n";
}

2306 2307
template <HeapObjectReferenceType kRefType, typename StorageType>
void TaggedImpl<kRefType, StorageType>::Print() {
2308
  StdoutStream os;
2309
  this->Print(os);
2310 2311 2312
  os << std::flush;
}

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

2331 2332 2333 2334 2335
void HeapNumber::HeapNumberPrint(std::ostream& os) {
  HeapNumberShortPrint(os);
  os << "\n";
}

2336 2337
#endif  // OBJECT_PRINT

2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355
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;
  }
}
2356

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

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

2388
void Map::PrintMapDetails(std::ostream& os) {
2389
  DisallowHeapAllocation no_gc;
2390
  this->MapPrint(os);
2391
  instance_descriptors().PrintDescriptors(os);
2392 2393 2394 2395 2396
}

void Map::MapPrint(std::ostream& os) {  // NOLINT
#ifdef OBJECT_PRINT
  PrintHeader(os, "Map");
2397
#else
2398
  os << "Map=" << reinterpret_cast<void*>(ptr());
2399
#endif
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 2429 2430 2431 2432 2433
  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";
2434 2435 2436
  if (IsContextMap()) {
    os << "\n - native context: " << Brief(native_context());
  } else if (is_prototype_map()) {
2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447
    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: ";
2448
    layout_descriptor().ShortPrint(os);
2449 2450 2451 2452
  }

  // Read-only maps can't have transitions, which is fortunate because we need
  // the isolate to iterate over the transitions.
2453 2454
  if (!IsReadOnlyHeapObject(*this)) {
    Isolate* isolate = GetIsolateFromWritableObject(*this);
2455 2456 2457 2458 2459
    DisallowHeapAllocation no_gc;
    TransitionsAccessor transitions(isolate, *this, &no_gc);
    int nof_transitions = transitions.NumberOfTransitions();
    if (nof_transitions > 0) {
      os << "\n - transitions #" << nof_transitions << ": ";
2460
      HeapObject heap_object;
2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472
      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());
2473 2474 2475
  if (!IsContextMap()) {
    os << "\n - constructor: " << Brief(GetConstructor());
  }
2476 2477
  os << "\n - dependent code: " << Brief(dependent_code());
  os << "\n - construction counter: " << construction_counter();
2478
  os << "\n";
2479 2480
}

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

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

2520 2521 2522 2523 2524 2525 2526 2527 2528 2529
#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];
2530
  WriteToFlat(*this, reinterpret_cast<uint8_t*>(buffer), 0, length());
2531 2532 2533 2534
  buffer[length()] = 0;
  return buffer;
}

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

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

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

2597
void TransitionsAccessor::PrintTransitionTree() {
2598
  StdoutStream os;
2599 2600 2601
  os << "map= " << Brief(map_);
  DisallowHeapAllocation no_gc;
  PrintTransitionTree(os, 0, &no_gc);
2602 2603 2604
  os << "\n" << std::flush;
}

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

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

2648
void JSObject::PrintTransitions(std::ostream& os) {  // NOLINT
2649
  DisallowHeapAllocation no_gc;
2650
  TransitionsAccessor ta(GetIsolate(), map(), &no_gc);
2651
  if (ta.NumberOfTransitions() == 0) return;
2652
  os << "\n - transitions";
2653
  ta.PrintTransitions(os);
2654
}
2655

2656
#endif  // defined(DEBUG) || defined(OBJECT_PRINT)
2657 2658
}  // namespace internal
}  // namespace v8
2659

2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677
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

2678 2679 2680
//
// The following functions are used by our gdb macros.
//
2681 2682 2683 2684
V8_EXPORT_PRIVATE extern i::Object _v8_internal_Get_Object(void* object) {
  return GetObjectFromRaw(object);
}

2685
V8_EXPORT_PRIVATE extern void _v8_internal_Print_Object(void* object) {
2686
  GetObjectFromRaw(object).Print();
2687 2688
}

2689
V8_EXPORT_PRIVATE extern void _v8_internal_Print_Code(void* object) {
2690
  i::Address address = reinterpret_cast<i::Address>(object);
2691
  i::Isolate* isolate = i::Isolate::Current();
2692

2693 2694 2695 2696 2697 2698 2699 2700 2701
  {
    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;
    }
2702
  }
2703 2704

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

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

2728 2729
V8_EXPORT_PRIVATE extern void _v8_internal_Print_LayoutDescriptor(
    void* object) {
2730
  i::Object o(GetObjectFromRaw(object));
2731
  if (!o.IsLayoutDescriptor()) {
2732
    printf("Please provide a layout descriptor\n");
2733
  } else {
2734
    i::LayoutDescriptor::cast(o).Print();
2735 2736 2737
  }
}

2738
V8_EXPORT_PRIVATE extern void _v8_internal_Print_StackTrace() {
2739 2740 2741
  i::Isolate* isolate = i::Isolate::Current();
  isolate->PrintStack(stdout);
}
2742

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

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