objects-printer.cc 53.5 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.h"
6

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

10
#include "src/bootstrapper.h"
11
#include "src/disasm.h"
12
#include "src/disassembler.h"
13
#include "src/interpreter/bytecodes.h"
14
#include "src/objects-inl.h"
15
#include "src/ostreams.h"
16
#include "src/regexp/jsregexp.h"
17 18 19 20 21 22

namespace v8 {
namespace internal {

#ifdef OBJECT_PRINT

23
void Object::Print() {
24 25
  OFStream os(stdout);
  this->Print(os);
26
  os << std::flush;
27 28 29
}


30
void Object::Print(std::ostream& os) {  // NOLINT
31
  if (IsSmi()) {
32 33
    os << "Smi: " << std::hex << "0x" << Smi::cast(this)->value();
    os << std::dec << " (" << Smi::cast(this)->value() << ")\n";
34
  } else {
35
    HeapObject::cast(this)->HeapObjectPrint(os);
36 37 38 39
  }
}


40
void HeapObject::PrintHeader(std::ostream& os, const char* id) {  // NOLINT
41 42 43 44 45 46 47
  os << reinterpret_cast<void*>(this) << ": [";
  if (id != nullptr) {
    os << id;
  } else {
    os << map()->instance_type();
  }
  os << "]";
48 49 50
}


51
void HeapObject::HeapObjectPrint(std::ostream& os) {  // NOLINT
52 53
  InstanceType instance_type = map()->instance_type();

54
  HandleScope scope(GetIsolate());
55
  if (instance_type < FIRST_NONSTRING_TYPE) {
56
    String::cast(this)->StringPrint(os);
57
    os << "\n";
58 59 60 61
    return;
  }

  switch (instance_type) {
62
    case SYMBOL_TYPE:
63
      Symbol::cast(this)->SymbolPrint(os);
64
      break;
65
    case MAP_TYPE:
66
      Map::cast(this)->MapPrint(os);
67 68
      break;
    case HEAP_NUMBER_TYPE:
69
      HeapNumber::cast(this)->HeapNumberPrint(os);
70
      os << "\n";
71
      break;
72
    case MUTABLE_HEAP_NUMBER_TYPE:
73 74
      os << "<mutable ";
      HeapNumber::cast(this)->HeapNumberPrint(os);
75
      os << ">\n";
76
      break;
77 78
    case SIMD128_VALUE_TYPE:
      Simd128Value::cast(this)->Simd128ValuePrint(os);
79
      break;
80
    case FIXED_DOUBLE_ARRAY_TYPE:
81
      FixedDoubleArray::cast(this)->FixedDoubleArrayPrint(os);
82
      break;
83
    case FIXED_ARRAY_TYPE:
84
      FixedArray::cast(this)->FixedArrayPrint(os);
85 86
      break;
    case BYTE_ARRAY_TYPE:
87
      ByteArray::cast(this)->ByteArrayPrint(os);
88
      break;
89 90 91
    case BYTECODE_ARRAY_TYPE:
      BytecodeArray::cast(this)->BytecodeArrayPrint(os);
      break;
92 93 94
    case TRANSITION_ARRAY_TYPE:
      TransitionArray::cast(this)->TransitionArrayPrint(os);
      break;
95
    case FREE_SPACE_TYPE:
96
      FreeSpace::cast(this)->FreeSpacePrint(os);
97
      break;
98

99 100 101 102
#define PRINT_FIXED_TYPED_ARRAY(Type, type, TYPE, ctype, size) \
  case Fixed##Type##Array::kInstanceType:                      \
    Fixed##Type##Array::cast(this)->FixedTypedArrayPrint(os);  \
    break;
103

104 105
    TYPED_ARRAYS(PRINT_FIXED_TYPED_ARRAY)
#undef PRINT_FIXED_TYPED_ARRAY
106

107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
    case JS_TYPED_ARRAY_KEY_ITERATOR_TYPE:
    case JS_FAST_ARRAY_KEY_ITERATOR_TYPE:
    case JS_GENERIC_ARRAY_KEY_ITERATOR_TYPE:
    case JS_INT8_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    case JS_UINT8_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    case JS_INT16_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    case JS_UINT16_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    case JS_INT32_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    case JS_UINT32_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    case JS_FLOAT32_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    case JS_FLOAT64_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    case JS_UINT8_CLAMPED_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    case JS_FAST_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    case JS_FAST_HOLEY_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    case JS_FAST_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    case JS_FAST_HOLEY_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    case JS_FAST_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    case JS_FAST_HOLEY_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    case JS_GENERIC_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    case JS_INT8_ARRAY_VALUE_ITERATOR_TYPE:
    case JS_UINT8_ARRAY_VALUE_ITERATOR_TYPE:
    case JS_INT16_ARRAY_VALUE_ITERATOR_TYPE:
    case JS_UINT16_ARRAY_VALUE_ITERATOR_TYPE:
    case JS_INT32_ARRAY_VALUE_ITERATOR_TYPE:
    case JS_UINT32_ARRAY_VALUE_ITERATOR_TYPE:
    case JS_FLOAT32_ARRAY_VALUE_ITERATOR_TYPE:
    case JS_FLOAT64_ARRAY_VALUE_ITERATOR_TYPE:
    case JS_UINT8_CLAMPED_ARRAY_VALUE_ITERATOR_TYPE:
    case JS_FAST_SMI_ARRAY_VALUE_ITERATOR_TYPE:
    case JS_FAST_HOLEY_SMI_ARRAY_VALUE_ITERATOR_TYPE:
    case JS_FAST_ARRAY_VALUE_ITERATOR_TYPE:
    case JS_FAST_HOLEY_ARRAY_VALUE_ITERATOR_TYPE:
    case JS_FAST_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE:
    case JS_FAST_HOLEY_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE:
    case JS_GENERIC_ARRAY_VALUE_ITERATOR_TYPE:
      JSArrayIterator::cast(this)->JSArrayIteratorPrint(os);
      break;

145
    case FILLER_TYPE:
146
      os << "filler";
147 148
      break;
    case JS_OBJECT_TYPE:  // fall through
149
    case JS_API_OBJECT_TYPE:
150
    case JS_SPECIAL_API_OBJECT_TYPE:
151
    case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
152
    case JS_GENERATOR_OBJECT_TYPE:
153 154
    case JS_ARGUMENTS_TYPE:
    case JS_ERROR_TYPE:
155
    case JS_PROMISE_CAPABILITY_TYPE:
156
      JSObject::cast(this)->JSObjectPrint(os);
157
      break;
158 159 160
    case JS_PROMISE_TYPE:
      JSPromise::cast(this)->JSPromisePrint(os);
      break;
161 162 163
    case JS_ARRAY_TYPE:
      JSArray::cast(this)->JSArrayPrint(os);
      break;
164 165 166
    case JS_REGEXP_TYPE:
      JSRegExp::cast(this)->JSRegExpPrint(os);
      break;
167
    case ODDBALL_TYPE:
168
      Oddball::cast(this)->to_string()->Print(os);
169
      break;
170 171 172
    case JS_BOUND_FUNCTION_TYPE:
      JSBoundFunction::cast(this)->JSBoundFunctionPrint(os);
      break;
173
    case JS_FUNCTION_TYPE:
174
      JSFunction::cast(this)->JSFunctionPrint(os);
175 176
      break;
    case JS_GLOBAL_PROXY_TYPE:
177
      JSGlobalProxy::cast(this)->JSGlobalProxyPrint(os);
178 179
      break;
    case JS_GLOBAL_OBJECT_TYPE:
180
      JSGlobalObject::cast(this)->JSGlobalObjectPrint(os);
181 182
      break;
    case JS_VALUE_TYPE:
183
      JSValue::cast(this)->JSValuePrint(os);
184
      break;
185
    case JS_DATE_TYPE:
186
      JSDate::cast(this)->JSDatePrint(os);
187
      break;
188
    case CODE_TYPE:
189
      Code::cast(this)->CodePrint(os);
190
      break;
191
    case JS_PROXY_TYPE:
192
      JSProxy::cast(this)->JSProxyPrint(os);
193
      break;
194
    case JS_SET_TYPE:
195
      JSSet::cast(this)->JSSetPrint(os);
196 197
      break;
    case JS_MAP_TYPE:
198
      JSMap::cast(this)->JSMapPrint(os);
199
      break;
200
    case JS_SET_ITERATOR_TYPE:
201
      JSSetIterator::cast(this)->JSSetIteratorPrint(os);
202 203
      break;
    case JS_MAP_ITERATOR_TYPE:
204
      JSMapIterator::cast(this)->JSMapIteratorPrint(os);
205
      break;
206
    case JS_WEAK_MAP_TYPE:
207
      JSWeakMap::cast(this)->JSWeakMapPrint(os);
208
      break;
209
    case JS_WEAK_SET_TYPE:
210
      JSWeakSet::cast(this)->JSWeakSetPrint(os);
211
      break;
212 213 214
    case JS_MODULE_NAMESPACE_TYPE:
      JSModuleNamespace::cast(this)->JSModuleNamespacePrint(os);
      break;
215
    case FOREIGN_TYPE:
216
      Foreign::cast(this)->ForeignPrint(os);
217 218
      break;
    case SHARED_FUNCTION_INFO_TYPE:
219
      SharedFunctionInfo::cast(this)->SharedFunctionInfoPrint(os);
220
      break;
221
    case JS_MESSAGE_OBJECT_TYPE:
222
      JSMessageObject::cast(this)->JSMessageObjectPrint(os);
223
      break;
224
    case CELL_TYPE:
225
      Cell::cast(this)->CellPrint(os);
226 227
      break;
    case PROPERTY_CELL_TYPE:
228
      PropertyCell::cast(this)->PropertyCellPrint(os);
229
      break;
ulan@chromium.org's avatar
ulan@chromium.org committed
230 231 232
    case WEAK_CELL_TYPE:
      WeakCell::cast(this)->WeakCellPrint(os);
      break;
233
    case JS_ARRAY_BUFFER_TYPE:
234
      JSArrayBuffer::cast(this)->JSArrayBufferPrint(os);
235
      break;
236
    case JS_TYPED_ARRAY_TYPE:
237
      JSTypedArray::cast(this)->JSTypedArrayPrint(os);
238
      break;
239
    case JS_DATA_VIEW_TYPE:
240
      JSDataView::cast(this)->JSDataViewPrint(os);
241
      break;
242 243
#define MAKE_STRUCT_CASE(NAME, Name, name) \
  case NAME##_TYPE:                        \
244
    Name::cast(this)->Name##Print(os);     \
245 246 247 248 249
    break;
  STRUCT_LIST(MAKE_STRUCT_CASE)
#undef MAKE_STRUCT_CASE

    default:
250
      os << "UNKNOWN TYPE " << map()->instance_type();
251 252 253 254 255 256
      UNREACHABLE();
      break;
  }
}


257 258 259 260 261 262 263 264 265
void Simd128Value::Simd128ValuePrint(std::ostream& os) {  // NOLINT
#define PRINT_SIMD128_VALUE(TYPE, Type, type, lane_count, lane_type) \
  if (Is##Type()) return Type::cast(this)->Type##Print(os);
  SIMD128_TYPES(PRINT_SIMD128_VALUE)
#undef PRINT_SIMD128_VALUE
  UNREACHABLE();
}


266 267 268 269 270 271 272 273 274 275
void Float32x4::Float32x4Print(std::ostream& os) {  // NOLINT
  char arr[100];
  Vector<char> buffer(arr, arraysize(arr));
  os << std::string(DoubleToCString(get_lane(0), buffer)) << ", "
     << std::string(DoubleToCString(get_lane(1), buffer)) << ", "
     << std::string(DoubleToCString(get_lane(2), buffer)) << ", "
     << std::string(DoubleToCString(get_lane(3), buffer));
}


276 277 278 279 280 281 282 283
#define SIMD128_INT_PRINT_FUNCTION(type, lane_count)                \
  void type::type##Print(std::ostream& os) {                        \
    char arr[100];                                                  \
    Vector<char> buffer(arr, arraysize(arr));                       \
    os << std::string(IntToCString(get_lane(0), buffer));           \
    for (int i = 1; i < lane_count; i++) {                          \
      os << ", " << std::string(IntToCString(get_lane(i), buffer)); \
    }                                                               \
284
  }
285
SIMD128_INT_PRINT_FUNCTION(Int32x4, 4)
286
SIMD128_INT_PRINT_FUNCTION(Uint32x4, 4)
287
SIMD128_INT_PRINT_FUNCTION(Int16x8, 8)
288
SIMD128_INT_PRINT_FUNCTION(Uint16x8, 8)
289
SIMD128_INT_PRINT_FUNCTION(Int8x16, 16)
290
SIMD128_INT_PRINT_FUNCTION(Uint8x16, 16)
291 292 293 294 295 296 297 298 299 300 301
#undef SIMD128_INT_PRINT_FUNCTION


#define SIMD128_BOOL_PRINT_FUNCTION(type, lane_count)            \
  void type::type##Print(std::ostream& os) {                     \
    char arr[100];                                               \
    Vector<char> buffer(arr, arraysize(arr));                    \
    os << std::string(get_lane(0) ? "true" : "false");           \
    for (int i = 1; i < lane_count; i++) {                       \
      os << ", " << std::string(get_lane(i) ? "true" : "false"); \
    }                                                            \
302
  }
303 304 305 306
SIMD128_BOOL_PRINT_FUNCTION(Bool32x4, 4)
SIMD128_BOOL_PRINT_FUNCTION(Bool16x8, 8)
SIMD128_BOOL_PRINT_FUNCTION(Bool8x16, 16)
#undef SIMD128_BOOL_PRINT_FUNCTION
307 308


309
void ByteArray::ByteArrayPrint(std::ostream& os) {  // NOLINT
310
  os << "byte array, data starts at " << GetDataStartAddress();
311 312 313
}


314 315 316 317 318
void BytecodeArray::BytecodeArrayPrint(std::ostream& os) {  // NOLINT
  Disassemble(os);
}


319
void FreeSpace::FreeSpacePrint(std::ostream& os) {  // NOLINT
320
  os << "free space, size " << Size();
321 322 323
}


324
template <class Traits>
325 326
void FixedTypedArray<Traits>::FixedTypedArrayPrint(
    std::ostream& os) {  // NOLINT
327
  os << "fixed " << Traits::Designator();
328 329
}

330
bool JSObject::PrintProperties(std::ostream& os) {  // NOLINT
331 332
  if (HasFastProperties()) {
    DescriptorArray* descs = map()->instance_descriptors();
333 334 335
    int i = 0;
    for (; i < map()->NumberOfOwnDescriptors(); i++) {
      os << "\n    ";
336 337
      descs->GetKey(i)->NamePrint(os);
      os << ": ";
338 339 340
      PropertyDetails details = descs->GetDetails(i);
      switch (details.location()) {
        case kField: {
341
          FieldIndex field_index = FieldIndex::ForDescriptor(map(), i);
342 343
          if (IsUnboxedDoubleField(field_index)) {
            os << "<unboxed double> " << RawFastDoublePropertyAt(field_index);
344
          } else {
345
            os << Brief(RawFastPropertyAt(field_index));
346
          }
347 348
          break;
        }
349 350
        case kDescriptor:
          os << Brief(descs->GetValue(i));
351
          break;
352
      }
353 354
      os << " ";
      details.PrintAsFastTo(os, PropertyDetails::kForProperties);
355
    }
356
    return i > 0;
357
  } else if (IsJSGlobalObject()) {
358
    global_dictionary()->Print(os);
359
  } else {
360
    property_dictionary()->Print(os);
361
  }
362
  return true;
363 364
}

365 366 367
namespace {

template <class T>
368 369
bool IsTheHoleAt(T* array, int index) {
  return false;
370 371
}

372 373 374
template <>
bool IsTheHoleAt(FixedDoubleArray* array, int index) {
  return array->is_the_hole(index);
375 376
}

377 378 379 380 381 382
template <class T>
double GetScalarElement(T* array, int index) {
  if (IsTheHoleAt(array, index)) {
    return std::numeric_limits<double>::quiet_NaN();
  }
  return array->get_scalar(index);
383 384
}

385
template <class T>
386
void DoPrintElements(std::ostream& os, Object* object) {  // NOLINT
387
  const bool print_the_hole = std::is_same<T, FixedDoubleArray>::value;
388 389 390
  T* array = T::cast(object);
  if (array->length() == 0) return;
  int previous_index = 0;
391
  double previous_value = GetScalarElement(array, 0);
392 393 394
  double value = 0.0;
  int i;
  for (i = 1; i <= array->length(); i++) {
395
    if (i < array->length()) value = GetScalarElement(array, i);
396
    bool values_are_nan = std::isnan(previous_value) && std::isnan(value);
397
    if (i != array->length() && (previous_value == value || values_are_nan) &&
398
        IsTheHoleAt(array, i - 1) == IsTheHoleAt(array, i)) {
399 400 401 402 403 404 405 406 407
      continue;
    }
    os << "\n";
    std::stringstream ss;
    ss << previous_index;
    if (previous_index != i - 1) {
      ss << '-' << (i - 1);
    }
    os << std::setw(12) << ss.str() << ": ";
408
    if (print_the_hole && IsTheHoleAt(array, i - 1)) {
409 410 411 412 413 414
      os << "<the_hole>";
    } else {
      os << previous_value;
    }
    previous_index = i;
    previous_value = value;
415 416 417
  }
}

418 419
void PrintFixedArrayElements(std::ostream& os, FixedArray* array) {
  // Print in array notation for non-sparse arrays.
420
  Object* previous_value = array->length() > 0 ? array->get(0) : nullptr;
421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441
  Object* value = nullptr;
  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);
    }
    os << std::setw(12) << ss.str() << ": " << Brief(previous_value);
    previous_index = i;
    previous_value = value;
  }
}

}  // namespace
442

443
bool JSObject::PrintElements(std::ostream& os) {  // NOLINT
444 445
  // Don't call GetElementsKind, its validation code can cause the printer to
  // fail when debugging.
446
  if (elements()->length() == 0) return false;
447
  switch (map()->elements_kind()) {
448 449 450
    case FAST_HOLEY_SMI_ELEMENTS:
    case FAST_SMI_ELEMENTS:
    case FAST_HOLEY_ELEMENTS:
451 452
    case FAST_ELEMENTS:
    case FAST_STRING_WRAPPER_ELEMENTS: {
453
      PrintFixedArrayElements(os, FixedArray::cast(elements()));
454 455
      break;
    }
456
    case FAST_HOLEY_DOUBLE_ELEMENTS:
457
    case FAST_DOUBLE_ELEMENTS: {
458
      DoPrintElements<FixedDoubleArray>(os, elements());
459 460
      break;
    }
461

462 463 464 465
#define PRINT_ELEMENTS(Type, type, TYPE, elementType, size) \
  case TYPE##_ELEMENTS: {                                   \
    DoPrintElements<Fixed##Type##Array>(os, elements());    \
    break;                                                  \
466
  }
467
      TYPED_ARRAYS(PRINT_ELEMENTS)
468 469
#undef PRINT_ELEMENTS

470
    case DICTIONARY_ELEMENTS:
471
    case SLOW_STRING_WRAPPER_ELEMENTS:
472
      SeededNumberDictionary::cast(elements())->Print(os);
473
      break;
474 475
    case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
    case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: {
476
      FixedArray* p = FixedArray::cast(elements());
477
      os << "\n   parameter map:";
478
      for (int i = 2; i < p->length(); i++) {
479
        os << " " << (i - 2) << ":" << Brief(p->get(i));
480
      }
481
      os << "\n   context: " << Brief(p->get(0))
482
         << "\n   arguments: " << Brief(p->get(1));
483 484
      break;
    }
485 486
    case NO_ELEMENTS:
      break;
487
  }
488
  return true;
489 490 491
}


492 493 494
static void JSObjectPrintHeader(std::ostream& os, JSObject* obj,
                                const char* id) {  // NOLINT
  obj->PrintHeader(os, id);
495 496
  // Don't call GetElementsKind, its validation code can cause the printer to
  // fail when debugging.
497 498 499 500 501
  os << "\n - map = " << reinterpret_cast<void*>(obj->map()) << " [";
  if (obj->HasFastProperties()) {
    os << "FastProperties";
  } else {
    os << "DictionaryProperties";
502 503 504
  }
  PrototypeIterator iter(obj->GetIsolate(), obj);
  os << "]\n - prototype = " << reinterpret_cast<void*>(iter.GetCurrent());
505 506 507 508
  os << "\n - elements = " << Brief(obj->elements()) << " ["
     << ElementsKindToString(obj->map()->elements_kind());
  if (obj->elements()->map() == obj->GetHeap()->fixed_cow_array_map()) {
    os << " (COW)";
509
  }
510
  os << "]";
511 512 513
  if (obj->GetInternalFieldCount() > 0) {
    os << "\n - internal fields: " << obj->GetInternalFieldCount();
  }
514 515 516
}


517 518
static void JSObjectPrintBody(std::ostream& os, JSObject* obj,  // NOLINT
                              bool print_elements = true) {
519
  os << "\n - properties = " << Brief(obj->properties()) << " {";
520 521
  if (obj->PrintProperties(os)) os << "\n ";
  os << "}\n";
522
  if (print_elements && obj->elements()->length() > 0) {
523 524 525
    os << " - elements = " << Brief(obj->elements()) << " {";
    if (obj->PrintElements(os)) os << "\n ";
    os << "}\n";
526
  }
527 528 529 530 531 532 533 534
  int internal_fields = obj->GetInternalFieldCount();
  if (internal_fields > 0) {
    os << " - internal fields = {";
    for (int i = 0; i < internal_fields; i++) {
      os << "\n    " << Brief(obj->GetInternalField(i));
    }
    os << "\n }\n";
  }
535 536 537
}


538
void JSObject::JSObjectPrint(std::ostream& os) {  // NOLINT
539 540 541 542 543 544 545
  JSObjectPrintHeader(os, this, nullptr);
  JSObjectPrintBody(os, this);
}

void JSArray::JSArrayPrint(std::ostream& os) {  // NOLINT
  JSObjectPrintHeader(os, this, "JSArray");
  os << "\n - length = " << Brief(this->length());
546 547 548
  JSObjectPrintBody(os, this);
}

549 550 551 552
void JSPromise::JSPromisePrint(std::ostream& os) {  // NOLINT
  JSObjectPrintHeader(os, this, "JSPromise");
  os << "\n - status = " << JSPromise::Status(status());
  os << "\n - result = " << Brief(result());
553 554 555
  os << "\n - deferred_promise: " << Brief(deferred_promise());
  os << "\n - deferred_on_resolve: " << Brief(deferred_on_resolve());
  os << "\n - deferred_on_reject: " << Brief(deferred_on_reject());
556 557
  os << "\n - fulfill_reactions = " << Brief(fulfill_reactions());
  os << "\n - reject_reactions = " << Brief(reject_reactions());
558
  os << "\n - has_handler = " << has_handler();
559
}
560

561 562 563 564 565 566 567
void JSRegExp::JSRegExpPrint(std::ostream& os) {  // NOLINT
  JSObjectPrintHeader(os, this, "JSRegExp");
  os << "\n - data = " << Brief(data());
  JSObjectPrintBody(os, this);
}


568
void Symbol::SymbolPrint(std::ostream& os) {  // NOLINT
569
  HeapObject::PrintHeader(os, "Symbol");
570
  os << "\n - hash: " << Hash();
571
  os << "\n - name: " << Brief(name());
572
  if (name()->IsUndefined(GetIsolate())) {
573 574
    os << " (" << PrivateSymbolToName() << ")";
  }
575
  os << "\n - private: " << is_private();
576
  os << "\n";
577 578 579
}


580
void Map::MapPrint(std::ostream& os) {  // NOLINT
581
  HeapObject::PrintHeader(os, "Map");
582 583
  os << "\n - type: " << instance_type();
  os << "\n - instance size: " << instance_size();
584
  if (IsJSObjectMap()) {
585
    os << "\n - inobject properties: " << GetInObjectProperties();
586
  }
587 588
  os << "\n - elements kind: " << ElementsKindToString(elements_kind());
  os << "\n - unused property fields: " << unused_property_fields();
589 590 591 592 593 594
  os << "\n - enum length: ";
  if (EnumLength() == kInvalidEnumCacheSentinel) {
    os << "invalid";
  } else {
    os << EnumLength();
  }
595 596 597
  if (is_deprecated()) os << "\n - deprecated_map";
  if (is_stable()) os << "\n - stable_map";
  if (is_dictionary_map()) os << "\n - dictionary_map";
598
  if (has_hidden_prototype()) os << "\n - has_hidden_prototype";
599
  if (has_named_interceptor()) os << "\n - named_interceptor";
600 601 602 603 604 605
  if (has_indexed_interceptor()) os << "\n - indexed_interceptor";
  if (is_undetectable()) os << "\n - undetectable";
  if (is_callable()) os << "\n - callable";
  if (is_constructor()) os << "\n - constructor";
  if (is_access_check_needed()) os << "\n - access_check_needed";
  if (!is_extensible()) os << "\n - non-extensible";
606
  if (is_prototype_map()) {
607 608
    os << "\n - prototype_map";
    os << "\n - prototype info: " << Brief(prototype_info());
609
  } else {
610
    os << "\n - back pointer: " << Brief(GetBackPointer());
611
  }
612 613 614
  os << "\n - instance descriptors " << (owns_descriptors() ? "(own) " : "")
     << "#" << NumberOfOwnDescriptors() << ": "
     << Brief(instance_descriptors());
615
  if (FLAG_unbox_double_fields) {
616 617
    os << "\n - layout descriptor: ";
    layout_descriptor()->ShortPrint(os);
618
  }
619 620 621 622 623
  int nof_transitions = TransitionArray::NumberOfTransitions(raw_transitions());
  if (nof_transitions > 0) {
    os << "\n - transitions #" << nof_transitions << ": "
       << Brief(raw_transitions());
    TransitionArray::PrintTransitions(os, raw_transitions(), false);
624
  }
625
  os << "\n - prototype: " << Brief(prototype());
626
  os << "\n - constructor: " << Brief(GetConstructor());
627 628
  os << "\n - code cache: " << Brief(code_cache());
  os << "\n - dependent code: " << Brief(dependent_code());
629
  os << "\n - construction counter: " << construction_counter();
630
  os << "\n";
631 632 633
}


634
void TypeFeedbackInfo::TypeFeedbackInfoPrint(std::ostream& os) {  // NOLINT
635
  HeapObject::PrintHeader(os, "TypeFeedbackInfo");
636
  os << "\n - ic_total_count: " << ic_total_count()
637 638
     << ", ic_with_type_info_count: " << ic_with_type_info_count()
     << ", ic_generic_count: " << ic_generic_count() << "\n";
639 640 641
}


642 643
void AliasedArgumentsEntry::AliasedArgumentsEntryPrint(
    std::ostream& os) {  // NOLINT
644 645
  HeapObject::PrintHeader(os, "AliasedArgumentsEntry");
  os << "\n - aliased_context_slot: " << aliased_context_slot();
646 647 648
}


649
void FixedArray::FixedArrayPrint(std::ostream& os) {  // NOLINT
650
  HeapObject::PrintHeader(os, "FixedArray");
651
  os << "\n - map = " << Brief(map());
652
  os << "\n - length: " << length();
653
  PrintFixedArrayElements(os, this);
654
  os << "\n";
655 656 657
}


658
void FixedDoubleArray::FixedDoubleArrayPrint(std::ostream& os) {  // NOLINT
659
  HeapObject::PrintHeader(os, "FixedDoubleArray");
660
  os << "\n - map = " << Brief(map());
661
  os << "\n - length: " << length();
662
  DoPrintElements<FixedDoubleArray>(os, this);
663
  os << "\n";
664 665 666
}


667 668
void TransitionArray::TransitionArrayPrint(std::ostream& os) {  // NOLINT
  HeapObject::PrintHeader(os, "TransitionArray");
669
  os << "\n - capacity: " << length();
670 671 672 673 674 675 676 677 678
  for (int i = 0; i < length(); i++) {
    os << "\n  [" << i << "]: " << Brief(get(i));
    if (i == kNextLinkIndex) os << " (next link)";
    if (i == kPrototypeTransitionsIndex) os << " (prototype transitions)";
    if (i == kTransitionLengthIndex) os << " (number of transitions)";
  }
  os << "\n";
}

679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698
template void FeedbackVectorSpecBase<StaticFeedbackVectorSpec>::Print();
template void FeedbackVectorSpecBase<FeedbackVectorSpec>::Print();

template <typename Derived>
void FeedbackVectorSpecBase<Derived>::Print() {
  OFStream os(stdout);
  FeedbackVectorSpecPrint(os);
  os << std::flush;
}

template <typename Derived>
void FeedbackVectorSpecBase<Derived>::FeedbackVectorSpecPrint(
    std::ostream& os) {  // NOLINT
  int slot_count = This()->slots();
  os << " - slot_count: " << slot_count;
  if (slot_count == 0) {
    os << " (empty)\n";
    return;
  }

699
  for (int slot = 0; slot < slot_count;) {
700 701 702 703 704 705 706 707
    FeedbackVectorSlotKind kind = This()->GetKind(slot);
    int entry_size = TypeFeedbackMetadata::GetSlotSize(kind);
    DCHECK_LT(0, entry_size);
    os << "\n Slot #" << slot << " " << kind;
    slot += entry_size;
  }
  os << "\n";
}
708

709 710 711 712 713 714 715 716 717 718
void TypeFeedbackMetadata::Print() {
  OFStream os(stdout);
  TypeFeedbackMetadataPrint(os);
  os << std::flush;
}


void TypeFeedbackMetadata::TypeFeedbackMetadataPrint(
    std::ostream& os) {  // NOLINT
  HeapObject::PrintHeader(os, "TypeFeedbackMetadata");
719
  os << "\n - length: " << length();
720 721 722 723
  if (length() == 0) {
    os << " (empty)\n";
    return;
  }
724
  os << "\n - slot_count: " << slot_count();
725 726 727 728 729 730 731 732 733 734 735

  TypeFeedbackMetadataIterator iter(this);
  while (iter.HasNext()) {
    FeedbackVectorSlot slot = iter.Next();
    FeedbackVectorSlotKind kind = iter.kind();
    os << "\n Slot " << slot << " " << kind;
  }
  os << "\n";
}


736 737 738 739 740 741 742 743 744
void TypeFeedbackVector::Print() {
  OFStream os(stdout);
  TypeFeedbackVectorPrint(os);
  os << std::flush;
}


void TypeFeedbackVector::TypeFeedbackVectorPrint(std::ostream& os) {  // NOLINT
  HeapObject::PrintHeader(os, "TypeFeedbackVector");
745
  os << "\n - length: " << length();
746 747 748 749 750
  if (length() == 0) {
    os << " (empty)\n";
    return;
  }

751
  TypeFeedbackMetadataIterator iter(metadata());
752 753 754 755
  while (iter.HasNext()) {
    FeedbackVectorSlot slot = iter.Next();
    FeedbackVectorSlotKind kind = iter.kind();

756 757
    os << "\n Slot " << slot << " " << kind;
    os << " ";
758 759 760 761 762 763
    switch (kind) {
      case FeedbackVectorSlotKind::LOAD_IC: {
        LoadICNexus nexus(this, slot);
        os << Code::ICState2String(nexus.StateFromFeedback());
        break;
      }
764 765 766 767 768
      case FeedbackVectorSlotKind::LOAD_GLOBAL_IC: {
        LoadGlobalICNexus nexus(this, slot);
        os << Code::ICState2String(nexus.StateFromFeedback());
        break;
      }
769 770 771 772
      case FeedbackVectorSlotKind::KEYED_LOAD_IC: {
        KeyedLoadICNexus nexus(this, slot);
        os << Code::ICState2String(nexus.StateFromFeedback());
        break;
773
      }
774 775 776 777 778 779 780 781 782 783 784 785 786 787 788
      case FeedbackVectorSlotKind::CALL_IC: {
        CallICNexus nexus(this, slot);
        os << Code::ICState2String(nexus.StateFromFeedback());
        break;
      }
      case FeedbackVectorSlotKind::STORE_IC: {
        StoreICNexus nexus(this, slot);
        os << Code::ICState2String(nexus.StateFromFeedback());
        break;
      }
      case FeedbackVectorSlotKind::KEYED_STORE_IC: {
        KeyedStoreICNexus nexus(this, slot);
        os << Code::ICState2String(nexus.StateFromFeedback());
        break;
      }
789 790 791 792 793 794 795 796 797 798
      case FeedbackVectorSlotKind::INTERPRETER_BINARYOP_IC: {
        BinaryOpICNexus nexus(this, slot);
        os << Code::ICState2String(nexus.StateFromFeedback());
        break;
      }
      case FeedbackVectorSlotKind::INTERPRETER_COMPARE_IC: {
        CompareICNexus nexus(this, slot);
        os << Code::ICState2String(nexus.StateFromFeedback());
        break;
      }
799 800 801 802 803
      case FeedbackVectorSlotKind::STORE_DATA_PROPERTY_IN_LITERAL_IC: {
        StoreDataPropertyInLiteralICNexus nexus(this, slot);
        os << Code::ICState2String(nexus.StateFromFeedback());
        break;
      }
804
      case FeedbackVectorSlotKind::CREATE_CLOSURE:
805
      case FeedbackVectorSlotKind::LITERAL:
806 807 808 809 810 811 812
      case FeedbackVectorSlotKind::GENERAL:
        break;
      case FeedbackVectorSlotKind::INVALID:
      case FeedbackVectorSlotKind::KINDS_NUMBER:
        UNREACHABLE();
        break;
    }
813

814 815 816 817
    int entry_size = iter.entry_size();
    for (int i = 0; i < entry_size; i++) {
      int index = GetIndex(slot) + i;
      os << "\n  [" << index << "]: " << Brief(get(index));
818 819 820 821 822 823
    }
  }
  os << "\n";
}


824
void JSValue::JSValuePrint(std::ostream& os) {  // NOLINT
825 826 827
  JSObjectPrintHeader(os, this, "JSValue");
  os << "\n - value = " << Brief(value());
  JSObjectPrintBody(os, this);
828 829 830
}


831
void JSMessageObject::JSMessageObjectPrint(std::ostream& os) {  // NOLINT
832 833
  JSObjectPrintHeader(os, this, "JSMessageObject");
  os << "\n - type: " << type();
834
  os << "\n - arguments: " << Brief(argument());
835 836 837 838
  os << "\n - start_position: " << start_position();
  os << "\n - end_position: " << end_position();
  os << "\n - script: " << Brief(script());
  os << "\n - stack_frames: " << Brief(stack_frames());
839
  JSObjectPrintBody(os, this);
840 841 842
}


843
void String::StringPrint(std::ostream& os) {  // NOLINT
844
  if (StringShape(this).IsInternalized()) {
845
    os << "#";
846
  } else if (StringShape(this).IsCons()) {
847
    os << "c\"";
848 849
  } else if (StringShape(this).IsThin()) {
    os << ">\"";
850
  } else {
851
    os << "\"";
852 853 854 855 856 857 858 859 860 861
  }

  const char truncated_epilogue[] = "...<truncated>";
  int len = length();
  if (!FLAG_use_verbose_printer) {
    if (len > 100) {
      len = 100 - sizeof(truncated_epilogue);
    }
  }
  for (int i = 0; i < len; i++) {
862
    os << AsUC16(Get(i));
863 864
  }
  if (len != length()) {
865
    os << truncated_epilogue;
866 867
  }

868
  if (!StringShape(this).IsInternalized()) os << "\"";
869 870 871
}


872
void Name::NamePrint(std::ostream& os) {  // NOLINT
873
  if (IsString()) {
874
    String::cast(this)->StringPrint(os);
875
  } else {
876
    os << Brief(this);
877
  }
878 879 880
}


881 882 883 884
static const char* const weekdays[] = {
  "???", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
};

885

886
void JSDate::JSDatePrint(std::ostream& os) {  // NOLINT
887 888
  JSObjectPrintHeader(os, this, "JSDate");
  os << "\n - value = " << Brief(value());
889
  if (!year()->IsSmi()) {
890
    os << "\n - time = NaN\n";
891
  } else {
892
    // TODO(svenpanne) Add some basic formatting to our streams.
893
    ScopedVector<char> buf(100);
894
    SNPrintF(
895
        buf, "\n - time = %s %04d/%02d/%02d %02d:%02d:%02d\n",
896 897 898 899 900 901 902 903
        weekdays[weekday()->IsSmi() ? Smi::cast(weekday())->value() + 1 : 0],
        year()->IsSmi() ? Smi::cast(year())->value() : -1,
        month()->IsSmi() ? Smi::cast(month())->value() : -1,
        day()->IsSmi() ? Smi::cast(day())->value() : -1,
        hour()->IsSmi() ? Smi::cast(hour())->value() : -1,
        min()->IsSmi() ? Smi::cast(min())->value() : -1,
        sec()->IsSmi() ? Smi::cast(sec())->value() : -1);
    os << buf.start();
904
  }
905
  JSObjectPrintBody(os, this);
906 907 908
}


909
void JSProxy::JSProxyPrint(std::ostream& os) {  // NOLINT
910
  HeapObject::PrintHeader(os, "JSProxy");
911
  os << "\n - map = " << reinterpret_cast<void*>(map());
912 913 914 915
  os << "\n - target = ";
  target()->ShortPrint(os);
  os << "\n - handler = ";
  handler()->ShortPrint(os);
916
  os << "\n - hash = ";
917
  hash()->ShortPrint(os);
918
  os << "\n";
919 920 921
}


922
void JSSet::JSSetPrint(std::ostream& os) {  // NOLINT
923
  JSObjectPrintHeader(os, this, "JSSet");
924
  os << " - table = " << Brief(table());
925
  JSObjectPrintBody(os, this);
926 927 928
}


929
void JSMap::JSMapPrint(std::ostream& os) {  // NOLINT
930
  JSObjectPrintHeader(os, this, "JSMap");
931
  os << " - table = " << Brief(table());
932
  JSObjectPrintBody(os, this);
933 934 935
}


936
template <class Derived, class TableType>
937 938 939
void
OrderedHashTableIterator<Derived, TableType>::OrderedHashTableIteratorPrint(
    std::ostream& os) {  // NOLINT
940
  os << "\n - table = " << Brief(table());
941 942 943
  os << "\n - index = " << Brief(index());
  os << "\n - kind = " << Brief(kind());
  os << "\n";
944 945 946
}


947 948
template void OrderedHashTableIterator<
    JSSetIterator,
949
    OrderedHashSet>::OrderedHashTableIteratorPrint(std::ostream& os);  // NOLINT
950 951


952 953
template void OrderedHashTableIterator<
    JSMapIterator,
954
    OrderedHashMap>::OrderedHashTableIteratorPrint(std::ostream& os);  // NOLINT
955 956


957
void JSSetIterator::JSSetIteratorPrint(std::ostream& os) {  // NOLINT
958
  JSObjectPrintHeader(os, this, "JSSetIterator");
959
  OrderedHashTableIteratorPrint(os);
960 961 962
}


963
void JSMapIterator::JSMapIteratorPrint(std::ostream& os) {  // NOLINT
964
  JSObjectPrintHeader(os, this, "JSMapIterator");
965
  OrderedHashTableIteratorPrint(os);
966 967 968
}


969
void JSWeakMap::JSWeakMapPrint(std::ostream& os) {  // NOLINT
970 971 972
  JSObjectPrintHeader(os, this, "JSWeakMap");
  os << "\n - table = " << Brief(table());
  JSObjectPrintBody(os, this);
973 974 975
}


976
void JSWeakSet::JSWeakSetPrint(std::ostream& os) {  // NOLINT
977 978 979
  JSObjectPrintHeader(os, this, "JSWeakSet");
  os << "\n - table = " << Brief(table());
  JSObjectPrintBody(os, this);
980 981 982
}


983
void JSArrayBuffer::JSArrayBufferPrint(std::ostream& os) {  // NOLINT
984 985 986
  JSObjectPrintHeader(os, this, "JSArrayBuffer");
  os << "\n - backing_store = " << backing_store();
  os << "\n - byte_length = " << Brief(byte_length());
987
  if (was_neutered()) os << "\n - neutered";
988
  JSObjectPrintBody(os, this, !was_neutered());
989 990 991
}


992
void JSTypedArray::JSTypedArrayPrint(std::ostream& os) {  // NOLINT
993 994
  JSObjectPrintHeader(os, this, "JSTypedArray");
  os << "\n - buffer = " << Brief(buffer());
995 996 997
  os << "\n - byte_offset = " << Brief(byte_offset());
  os << "\n - byte_length = " << Brief(byte_length());
  os << "\n - length = " << Brief(length());
998
  if (WasNeutered()) os << "\n - neutered";
999
  JSObjectPrintBody(os, this, !WasNeutered());
1000 1001
}

1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021
void JSArrayIterator::JSArrayIteratorPrint(std::ostream& os) {  // NOLING
  JSObjectPrintHeader(os, this, "JSArrayIterator");

  InstanceType instance_type = map()->instance_type();
  std::string type;
  if (instance_type <= LAST_ARRAY_KEY_ITERATOR_TYPE) {
    type = "keys";
  } else if (instance_type <= LAST_ARRAY_KEY_VALUE_ITERATOR_TYPE) {
    type = "entries";
  } else {
    type = "values";
  }

  os << "\n - type = " << type;
  os << "\n - object = " << Brief(object());
  os << "\n - index = " << Brief(index());

  JSObjectPrintBody(os, this);
}

1022
void JSDataView::JSDataViewPrint(std::ostream& os) {  // NOLINT
1023 1024
  JSObjectPrintHeader(os, this, "JSDataView");
  os << "\n - buffer =" << Brief(buffer());
1025 1026
  os << "\n - byte_offset = " << Brief(byte_offset());
  os << "\n - byte_length = " << Brief(byte_length());
1027
  if (WasNeutered()) os << "\n - neutered";
1028
  JSObjectPrintBody(os, this, !WasNeutered());
1029 1030 1031
}


1032 1033 1034 1035 1036 1037 1038 1039 1040
void JSBoundFunction::JSBoundFunctionPrint(std::ostream& os) {  // NOLINT
  JSObjectPrintHeader(os, this, "JSBoundFunction");
  os << "\n - bound_target_function = " << Brief(bound_target_function());
  os << "\n - bound_this = " << Brief(bound_this());
  os << "\n - bound_arguments = " << Brief(bound_arguments());
  JSObjectPrintBody(os, this);
}


1041
void JSFunction::JSFunctionPrint(std::ostream& os) {  // NOLINT
1042 1043
  JSObjectPrintHeader(os, this, "Function");
  os << "\n - initial_map = ";
1044 1045
  if (has_initial_map()) os << Brief(initial_map());
  os << "\n - shared_info = " << Brief(shared());
1046
  os << "\n - name = " << Brief(shared()->name());
1047 1048
  os << "\n - formal_parameter_count = "
     << shared()->internal_formal_parameter_count();
1049
  if (IsGeneratorFunction(shared()->kind())) {
1050
    os << "\n   - generator";
1051
  } else if (IsAsyncFunction(shared()->kind())) {
1052
    os << "\n   - async";
1053
  }
1054
  os << "\n - context = " << Brief(context());
1055
  os << "\n - feedback vector = " << Brief(feedback_vector());
1056
  os << "\n - code = " << Brief(code());
1057
  JSObjectPrintBody(os, this);
1058 1059 1060
}


1061
void SharedFunctionInfo::SharedFunctionInfoPrint(std::ostream& os) {  // NOLINT
1062
  HeapObject::PrintHeader(os, "SharedFunctionInfo");
1063 1064 1065 1066
  os << "\n - name = " << Brief(name());
  os << "\n - formal_parameter_count = " << internal_formal_parameter_count();
  os << "\n - expected_nof_properties = " << expected_nof_properties();
  os << "\n - ast_node_count = " << ast_node_count();
1067 1068 1069
  os << "\n - instance class name = ";
  instance_class_name()->Print(os);
  os << "\n - code = " << Brief(code());
1070
  if (HasSourceCode()) {
1071
    os << "\n - source code = ";
1072 1073 1074
    String* source = String::cast(Script::cast(script())->source());
    int start = start_position();
    int length = end_position() - start;
1075
    std::unique_ptr<char[]> source_string = source->ToCString(
rmcilroy's avatar
rmcilroy committed
1076
        DISALLOW_NULLS, FAST_STRING_TRAVERSAL, start, length, NULL);
1077
    os << source_string.get();
1078
  }
1079
  // Script files are often large, hard to read.
1080 1081
  // os << "\n - script =";
  // script()->Print(os);
1082 1083 1084 1085 1086 1087 1088
  if (is_named_expression()) {
    os << "\n - named expression";
  } else if (is_anonymous_expression()) {
    os << "\n - anonymous expression";
  } else if (is_declaration()) {
    os << "\n - declaration";
  }
1089 1090 1091
  os << "\n - function token position = " << function_token_position();
  os << "\n - start position = " << start_position();
  os << "\n - end position = " << end_position();
1092 1093 1094 1095 1096
  if (HasDebugInfo()) {
    os << "\n - debug info = " << Brief(debug_info());
  } else {
    os << "\n - no debug info";
  }
1097
  os << "\n - length = " << length();
1098
  os << "\n - num_literals = " << num_literals();
1099
  os << "\n - optimized_code_map = " << Brief(optimized_code_map());
1100 1101
  os << "\n - feedback_metadata = ";
  feedback_metadata()->TypeFeedbackMetadataPrint(os);
1102 1103 1104
  if (HasBytecodeArray()) {
    os << "\n - bytecode_array = " << bytecode_array();
  }
1105
  os << "\n";
1106 1107 1108
}


1109
void JSGlobalProxy::JSGlobalProxyPrint(std::ostream& os) {  // NOLINT
1110
  JSObjectPrintHeader(os, this, "JSGlobalProxy");
1111 1112 1113
  if (!GetIsolate()->bootstrapper()->IsActive()) {
    os << "\n - native context = " << Brief(native_context());
  }
1114 1115
  os << "\n - hash = " << Brief(hash());
  JSObjectPrintBody(os, this);
1116 1117 1118
}


1119
void JSGlobalObject::JSGlobalObjectPrint(std::ostream& os) {  // NOLINT
1120
  JSObjectPrintHeader(os, this, "JSGlobalObject");
1121 1122 1123
  if (!GetIsolate()->bootstrapper()->IsActive()) {
    os << "\n - native context = " << Brief(native_context());
  }
1124 1125
  os << "\n - global proxy = " << Brief(global_proxy());
  JSObjectPrintBody(os, this);
1126 1127 1128
}


1129
void Cell::CellPrint(std::ostream& os) {  // NOLINT
1130
  HeapObject::PrintHeader(os, "Cell");
1131
  os << "\n - value: " << Brief(value());
1132
  os << "\n";
1133 1134 1135
}


1136
void PropertyCell::PropertyCellPrint(std::ostream& os) {  // NOLINT
1137
  HeapObject::PrintHeader(os, "PropertyCell");
1138
  os << "\n - value: " << Brief(value());
1139 1140
  os << "\n - details: ";
  property_details().PrintAsSlowTo(os);
1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180
  PropertyCellType cell_type = property_details().cell_type();
  os << "\n - cell_type: ";
  if (value()->IsTheHole(GetIsolate())) {
    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;
    }
  }
1181
  os << "\n";
1182 1183 1184
}


ulan@chromium.org's avatar
ulan@chromium.org committed
1185 1186
void WeakCell::WeakCellPrint(std::ostream& os) {  // NOLINT
  HeapObject::PrintHeader(os, "WeakCell");
1187 1188 1189 1190 1191
  if (cleared()) {
    os << "\n - cleared";
  } else {
    os << "\n - value: " << Brief(value());
  }
1192
  os << "\n";
ulan@chromium.org's avatar
ulan@chromium.org committed
1193 1194 1195
}


1196
void Code::CodePrint(std::ostream& os) {  // NOLINT
1197
  HeapObject::PrintHeader(os, "Code");
1198
  os << "\n";
1199 1200
#ifdef ENABLE_DISASSEMBLER
  if (FLAG_use_verbose_printer) {
1201
    Disassemble(NULL, os);
1202 1203 1204 1205 1206
  }
#endif
}


1207
void Foreign::ForeignPrint(std::ostream& os) {  // NOLINT
1208
  os << "foreign address : " << foreign_address();
1209
  os << "\n";
1210 1211 1212
}


1213 1214
void AccessorInfo::AccessorInfoPrint(std::ostream& os) {  // NOLINT
  HeapObject::PrintHeader(os, "AccessorInfo");
1215
  os << "\n - name: " << Brief(name());
1216
  os << "\n - flag: " << flag();
1217 1218
  os << "\n - getter: " << Brief(getter());
  os << "\n - setter: " << Brief(setter());
1219
  os << "\n - js_getter: " << Brief(js_getter());
1220 1221
  os << "\n - data: " << Brief(data());
  os << "\n";
1222 1223 1224
}


1225
void Box::BoxPrint(std::ostream& os) {  // NOLINT
1226 1227 1228 1229 1230
  HeapObject::PrintHeader(os, "Box");
  os << "\n - value: " << Brief(value());
  os << "\n";
}

1231 1232 1233
void PromiseResolveThenableJobInfo::PromiseResolveThenableJobInfoPrint(
    std::ostream& os) {  // NOLINT
  HeapObject::PrintHeader(os, "PromiseResolveThenableJobInfo");
1234 1235 1236 1237
  os << "\n - thenable: " << Brief(thenable());
  os << "\n - then: " << Brief(then());
  os << "\n - resolve: " << Brief(resolve());
  os << "\n - reject: " << Brief(reject());
1238
  os << "\n - context: " << Brief(context());
1239 1240 1241
  os << "\n";
}

1242 1243 1244 1245 1246
void PromiseReactionJobInfo::PromiseReactionJobInfoPrint(
    std::ostream& os) {  // NOLINT
  HeapObject::PrintHeader(os, "PromiseReactionJobInfo");
  os << "\n - value: " << Brief(value());
  os << "\n - tasks: " << Brief(tasks());
1247 1248 1249
  os << "\n - deferred_promise: " << Brief(deferred_promise());
  os << "\n - deferred_on_resolve: " << Brief(deferred_on_resolve());
  os << "\n - deferred_on_reject: " << Brief(deferred_on_reject());
1250 1251 1252 1253
  os << "\n - reaction context: " << Brief(context());
  os << "\n";
}

1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265
void ModuleInfoEntry::ModuleInfoEntryPrint(std::ostream& os) {  // NOLINT
  HeapObject::PrintHeader(os, "ModuleInfoEntry");
  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";
}

1266 1267
void Module::ModulePrint(std::ostream& os) {  // NOLINT
  HeapObject::PrintHeader(os, "Module");
1268
  os << "\n - code: " << Brief(code());
1269
  os << "\n - exports: " << Brief(exports());
1270
  os << "\n - requested_modules: " << Brief(requested_modules());
1271
  os << "\n - evaluated: " << evaluated();
1272 1273
  os << "\n";
}
1274

1275
void JSModuleNamespace::JSModuleNamespacePrint(std::ostream& os) {  // NOLINT
1276
  JSObjectPrintHeader(os, this, "JSModuleNamespace");
1277
  os << "\n - module: " << Brief(module());
1278
  JSObjectPrintBody(os, this);
1279 1280
}

1281 1282
void PrototypeInfo::PrototypeInfoPrint(std::ostream& os) {  // NOLINT
  HeapObject::PrintHeader(os, "PrototypeInfo");
1283
  os << "\n - weak cell: " << Brief(weak_cell());
1284
  os << "\n - prototype users: " << Brief(prototype_users());
1285
  os << "\n - registry slot: " << registry_slot();
1286
  os << "\n - validity cell: " << Brief(validity_cell());
1287
  os << "\n - object create map: " << Brief(object_create_map());
1288 1289 1290
  os << "\n";
}

1291 1292 1293 1294 1295 1296 1297
void Tuple2::Tuple2Print(std::ostream& os) {  // NOLINT
  HeapObject::PrintHeader(os, "Tuple2");
  os << "\n - value1: " << Brief(value1());
  os << "\n - value2: " << Brief(value2());
  os << "\n";
}

1298 1299 1300 1301 1302 1303 1304 1305
void Tuple3::Tuple3Print(std::ostream& os) {  // NOLINT
  HeapObject::PrintHeader(os, "Tuple3");
  os << "\n - value1: " << Brief(value1());
  os << "\n - value2: " << Brief(value2());
  os << "\n - value3: " << Brief(value3());
  os << "\n";
}

1306 1307
void ContextExtension::ContextExtensionPrint(std::ostream& os) {  // NOLINT
  HeapObject::PrintHeader(os, "ContextExtension");
1308 1309 1310 1311 1312
  os << "\n - scope_info: " << Brief(scope_info());
  os << "\n - extension: " << Brief(extension());
  os << "\n";
}

1313 1314 1315 1316 1317 1318 1319
void ConstantElementsPair::ConstantElementsPairPrint(
    std::ostream& os) {  // NOLINT
  HeapObject::PrintHeader(os, "ConstantElementsPair");
  os << "\n - elements_kind: " << static_cast<ElementsKind>(elements_kind());
  os << "\n - constant_values: " << Brief(constant_values());
  os << "\n";
}
1320

1321
void AccessorPair::AccessorPairPrint(std::ostream& os) {  // NOLINT
1322 1323 1324 1325 1326 1327 1328
  HeapObject::PrintHeader(os, "AccessorPair");
  os << "\n - getter: " << Brief(getter());
  os << "\n - setter: " << Brief(setter());
  os << "\n";
}


1329
void AccessCheckInfo::AccessCheckInfoPrint(std::ostream& os) {  // NOLINT
1330
  HeapObject::PrintHeader(os, "AccessCheckInfo");
1331
  os << "\n - callback: " << Brief(callback());
1332 1333
  os << "\n - named_interceptor: " << Brief(named_interceptor());
  os << "\n - indexed_interceptor: " << Brief(indexed_interceptor());
1334 1335 1336 1337 1338
  os << "\n - data: " << Brief(data());
  os << "\n";
}


1339
void InterceptorInfo::InterceptorInfoPrint(std::ostream& os) {  // NOLINT
1340 1341 1342 1343 1344 1345 1346 1347
  HeapObject::PrintHeader(os, "InterceptorInfo");
  os << "\n - getter: " << Brief(getter());
  os << "\n - setter: " << Brief(setter());
  os << "\n - query: " << Brief(query());
  os << "\n - deleter: " << Brief(deleter());
  os << "\n - enumerator: " << Brief(enumerator());
  os << "\n - data: " << Brief(data());
  os << "\n";
1348 1349 1350
}


1351
void CallHandlerInfo::CallHandlerInfoPrint(std::ostream& os) {  // NOLINT
1352 1353 1354 1355
  HeapObject::PrintHeader(os, "CallHandlerInfo");
  os << "\n - callback: " << Brief(callback());
  os << "\n - data: " << Brief(data());
  os << "\n";
1356 1357 1358
}


1359 1360
void FunctionTemplateInfo::FunctionTemplateInfoPrint(
    std::ostream& os) {  // NOLINT
1361 1362 1363
  HeapObject::PrintHeader(os, "FunctionTemplateInfo");
  os << "\n - class name: " << Brief(class_name());
  os << "\n - tag: " << Brief(tag());
1364
  os << "\n - serial_number: " << Brief(serial_number());
1365
  os << "\n - property_list: " << Brief(property_list());
1366 1367 1368 1369 1370 1371 1372 1373 1374
  os << "\n - call_code: " << Brief(call_code());
  os << "\n - property_accessors: " << Brief(property_accessors());
  os << "\n - prototype_template: " << Brief(prototype_template());
  os << "\n - parent_template: " << Brief(parent_template());
  os << "\n - named_property_handler: " << Brief(named_property_handler());
  os << "\n - indexed_property_handler: " << Brief(indexed_property_handler());
  os << "\n - instance_template: " << Brief(instance_template());
  os << "\n - signature: " << Brief(signature());
  os << "\n - access_check_info: " << Brief(access_check_info());
1375
  os << "\n - cached_property_name: " << Brief(cached_property_name());
1376 1377 1378
  os << "\n - hidden_prototype: " << (hidden_prototype() ? "true" : "false");
  os << "\n - undetectable: " << (undetectable() ? "true" : "false");
  os << "\n - need_access_check: " << (needs_access_check() ? "true" : "false");
1379
  os << "\n - instantiated: " << (instantiated() ? "true" : "false");
1380 1381 1382 1383
  os << "\n";
}


1384
void ObjectTemplateInfo::ObjectTemplateInfoPrint(std::ostream& os) {  // NOLINT
1385
  HeapObject::PrintHeader(os, "ObjectTemplateInfo");
1386 1387
  os << "\n - tag: " << Brief(tag());
  os << "\n - serial_number: " << Brief(serial_number());
1388 1389 1390
  os << "\n - property_list: " << Brief(property_list());
  os << "\n - property_accessors: " << Brief(property_accessors());
  os << "\n - constructor: " << Brief(constructor());
1391 1392
  os << "\n - internal_field_count: " << internal_field_count();
  os << "\n - immutable_proto: " << (immutable_proto() ? "true" : "false");
1393 1394 1395 1396
  os << "\n";
}


1397
void AllocationSite::AllocationSitePrint(std::ostream& os) {  // NOLINT
1398
  HeapObject::PrintHeader(os, "AllocationSite");
1399
  os << "\n - weak_next: " << Brief(weak_next());
1400 1401 1402 1403 1404 1405 1406 1407 1408
  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: ";
1409 1410
  if (transition_info()->IsSmi()) {
    ElementsKind kind = GetElementsKind();
1411
    os << "Array allocation with ElementsKind " << ElementsKindToString(kind);
1412
  } else if (transition_info()->IsJSArray()) {
1413 1414
    os << "Array literal " << Brief(transition_info());
  } else {
1415
    os << "unknown transition_info " << Brief(transition_info());
1416
  }
1417
  os << "\n";
1418 1419 1420
}


1421
void AllocationMemento::AllocationMementoPrint(std::ostream& os) {  // NOLINT
1422
  HeapObject::PrintHeader(os, "AllocationMemento");
1423
  os << "\n - allocation site: ";
1424
  if (IsValid()) {
1425
    GetAllocationSite()->Print(os);
1426
  } else {
1427
    os << "<invalid>\n";
1428 1429 1430 1431
  }
}


1432
void Script::ScriptPrint(std::ostream& os) {  // NOLINT
1433 1434 1435
  HeapObject::PrintHeader(os, "Script");
  os << "\n - source: " << Brief(source());
  os << "\n - name: " << Brief(name());
1436 1437 1438 1439
  os << "\n - line_offset: " << line_offset();
  os << "\n - column_offset: " << column_offset();
  os << "\n - type: " << type();
  os << "\n - id: " << id();
1440 1441 1442 1443 1444
  os << "\n - context data: " << Brief(context_data());
  os << "\n - wrapper: " << Brief(wrapper());
  os << "\n - compilation type: " << compilation_type();
  os << "\n - line ends: " << Brief(line_ends());
  os << "\n - eval from shared: " << Brief(eval_from_shared());
1445
  os << "\n - eval from position: " << eval_from_position();
1446
  os << "\n - shared function infos: " << Brief(shared_function_infos());
1447 1448 1449 1450
  os << "\n";
}


1451
void DebugInfo::DebugInfoPrint(std::ostream& os) {  // NOLINT
1452 1453
  HeapObject::PrintHeader(os, "DebugInfo");
  os << "\n - shared: " << Brief(shared());
1454
  os << "\n - debug bytecode array: " << Brief(debug_bytecode_array());
1455 1456 1457 1458 1459
  os << "\n - break_points: ";
  break_points()->Print(os);
}


1460
void BreakPointInfo::BreakPointInfoPrint(std::ostream& os) {  // NOLINT
1461
  HeapObject::PrintHeader(os, "BreakPointInfo");
1462
  os << "\n - source_position: " << source_position();
1463 1464 1465 1466 1467
  os << "\n - break_point_objects: " << Brief(break_point_objects());
  os << "\n";
}


1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482
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;
  }
}


void LayoutDescriptor::Print() {
  OFStream os(stdout);
  this->Print(os);
  os << std::flush;
}

1483 1484 1485 1486 1487 1488 1489
void LayoutDescriptor::ShortPrint(std::ostream& os) {
  if (IsSmi()) {
    os << this;  // Print tagged value for easy use with "jld" gdb macro.
  } else {
    os << Brief(this);
  }
}
1490 1491 1492

void LayoutDescriptor::Print(std::ostream& os) {  // NOLINT
  os << "Layout descriptor: ";
1493
  if (IsFastPointerLayout()) {
1494 1495 1496 1497
    os << "<all tagged>";
  } else if (IsSmi()) {
    os << "fast";
    PrintBitMask(os, static_cast<uint32_t>(Smi::cast(this)->value()));
1498 1499 1500
  } else if (IsOddball() &&
             IsUninitialized(HeapObject::cast(this)->GetIsolate())) {
    os << "<uninitialized>";
1501 1502
  } else {
    os << "slow";
1503
    int len = length();
1504 1505 1506 1507 1508 1509 1510 1511 1512
    for (int i = 0; i < len; i++) {
      if (i > 0) os << " |";
      PrintBitMask(os, get_scalar(i));
    }
  }
  os << "\n";
}


1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524
#endif  // OBJECT_PRINT


#if TRACE_MAPS


void Name::NameShortPrint() {
  if (this->IsString()) {
    PrintF("%s", String::cast(this)->ToCString().get());
  } else {
    DCHECK(this->IsSymbol());
    Symbol* s = Symbol::cast(this);
1525
    if (s->name()->IsUndefined(GetIsolate())) {
1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539
      PrintF("#<%s>", s->PrivateSymbolToName());
    } else {
      PrintF("<%s>", String::cast(s->name())->ToCString().get());
    }
  }
}


int Name::NameShortPrint(Vector<char> str) {
  if (this->IsString()) {
    return SNPrintF(str, "%s", String::cast(this)->ToCString().get());
  } else {
    DCHECK(this->IsSymbol());
    Symbol* s = Symbol::cast(this);
1540
    if (s->name()->IsUndefined(GetIsolate())) {
1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551
      return SNPrintF(str, "#<%s>", s->PrivateSymbolToName());
    } else {
      return SNPrintF(str, "<%s>", String::cast(s->name())->ToCString().get());
    }
  }
}


#endif  // TRACE_MAPS


1552
#if defined(DEBUG) || defined(OBJECT_PRINT)
1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576
// 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 = NULL;
  if (buffer != NULL) delete[] buffer;
  buffer = new char[length() + 1];
  WriteToFlat(this, reinterpret_cast<uint8_t*>(buffer), 0, length());
  buffer[length()] = 0;
  return buffer;
}


void DescriptorArray::Print() {
  OFStream os(stdout);
  this->PrintDescriptors(os);
  os << std::flush;
}


void DescriptorArray::PrintDescriptors(std::ostream& os) {  // NOLINT
  HandleScope scope(GetIsolate());
1577
  os << "Descriptor array #" << number_of_descriptors() << ":";
1578
  for (int i = 0; i < number_of_descriptors(); i++) {
1579 1580 1581 1582 1583 1584 1585 1586 1587
    Name* key = GetKey(i);
    os << "\n  [" << i << "]: ";
#ifdef OBJECT_PRINT
    key->NamePrint(os);
#else
    key->ShortPrint(os);
#endif
    os << " ";
    PrintDescriptorDetails(os, i, PropertyDetails::kPrintFull);
1588 1589 1590 1591
  }
  os << "\n";
}

1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613
void DescriptorArray::PrintDescriptorDetails(std::ostream& os, int descriptor,
                                             PropertyDetails::PrintMode mode) {
  PropertyDetails details = GetDetails(descriptor);
  details.PrintAsFastTo(os, mode);
  os << " @ ";
  Object* value = GetValue(descriptor);
  switch (details.location()) {
    case kField: {
      FieldType* field_type = Map::UnwrapFieldType(value);
      field_type->PrintTo(os);
      break;
    }
    case kDescriptor:
      os << Brief(value);
      if (value->IsAccessorPair()) {
        AccessorPair* pair = AccessorPair::cast(value);
        os << "(get: " << Brief(pair->getter())
           << ", set: " << Brief(pair->setter()) << ")";
      }
      break;
  }
}
1614

1615 1616
void TransitionArray::Print() {
  OFStream os(stdout);
1617
  TransitionArray::PrintTransitions(os, this);
1618
  os << "\n" << std::flush;
1619 1620 1621
}


1622
void TransitionArray::PrintTransitions(std::ostream& os, Object* transitions,
1623
                                       bool print_header) {  // NOLINT
1624
  int num_transitions = NumberOfTransitions(transitions);
1625
  if (print_header) {
1626
    os << "Transition array #" << num_transitions << ":";
1627
  }
1628 1629 1630
  for (int i = 0; i < num_transitions; i++) {
    Name* key = GetKey(transitions, i);
    Map* target = GetTarget(transitions, i);
1631
    os << "\n     ";
1632
#ifdef OBJECT_PRINT
1633
    key->NamePrint(os);
1634 1635 1636
#else
    key->ShortPrint(os);
#endif
1637
    os << ": ";
1638 1639
    Heap* heap = key->GetHeap();
    if (key == heap->nonextensible_symbol()) {
1640
      os << "(transition to non-extensible)";
1641
    } else if (key == heap->sealed_symbol()) {
1642
      os << "(transition to sealed)";
1643
    } else if (key == heap->frozen_symbol()) {
1644
      os << "(transition to frozen)";
1645
    } else if (key == heap->elements_transition_symbol()) {
1646
      os << "(transition to " << ElementsKindToString(target->elements_kind())
1647
         << ")";
ishell's avatar
ishell committed
1648 1649
    } else if (key == heap->strict_function_transition_symbol()) {
      os << " (transition to strict function)";
1650
    } else {
1651
      DCHECK(!IsSpecialTransition(key));
1652
      os << "(transition to ";
1653 1654 1655 1656 1657
      int descriptor = target->LastAdded();
      DescriptorArray* descriptors = target->instance_descriptors();
      descriptors->PrintDescriptorDetails(os, descriptor,
                                          PropertyDetails::kForTransitions);
      os << ")";
1658
    }
1659
    os << " -> " << Brief(target);
1660 1661 1662 1663
  }
}


1664
void JSObject::PrintTransitions(std::ostream& os) {  // NOLINT
1665 1666 1667 1668 1669
  Object* transitions = map()->raw_transitions();
  int num_transitions = TransitionArray::NumberOfTransitions(transitions);
  if (num_transitions == 0) return;
  os << "\n - transitions";
  TransitionArray::PrintTransitions(os, transitions, false);
1670
}
1671
#endif  // defined(DEBUG) || defined(OBJECT_PRINT)
1672 1673
}  // namespace internal
}  // namespace v8
1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702

//
// The following functions are used by our gdb macros.
//
extern void _v8_internal_Print_Object(void* object) {
  reinterpret_cast<i::Object*>(object)->Print();
}

extern void _v8_internal_Print_Code(void* object) {
  i::Isolate* isolate = i::Isolate::Current();
  isolate->FindCodeObject(reinterpret_cast<i::Address>(object))->Print();
}

extern void _v8_internal_Print_TypeFeedbackVector(void* object) {
  if (reinterpret_cast<i::Object*>(object)->IsSmi()) {
    printf("Not a type feedback vector\n");
  } else {
    reinterpret_cast<i::TypeFeedbackVector*>(object)->Print();
  }
}

extern void _v8_internal_Print_DescriptorArray(void* object) {
  if (reinterpret_cast<i::Object*>(object)->IsSmi()) {
    printf("Not a descriptor array\n");
  } else {
    reinterpret_cast<i::DescriptorArray*>(object)->Print();
  }
}

1703 1704 1705 1706 1707 1708 1709 1710 1711
extern void _v8_internal_Print_LayoutDescriptor(void* object) {
  i::Object* o = reinterpret_cast<i::Object*>(object);
  if (!o->IsLayoutDescriptor()) {
    printf("Not a layout descriptor\n");
  } else {
    reinterpret_cast<i::LayoutDescriptor*>(object)->Print();
  }
}

1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723
extern void _v8_internal_Print_TransitionArray(void* object) {
  if (reinterpret_cast<i::Object*>(object)->IsSmi()) {
    printf("Not a transition array\n");
  } else {
    reinterpret_cast<i::TransitionArray*>(object)->Print();
  }
}

extern void _v8_internal_Print_StackTrace() {
  i::Isolate* isolate = i::Isolate::Current();
  isolate->PrintStack(stdout);
}