objects-printer.cc 40.3 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 "src/disasm.h"
8
#include "src/disassembler.h"
9
#include "src/interpreter/bytecodes.h"
10
#include "src/objects-inl.h"
11
#include "src/ostreams.h"
12
#include "src/regexp/jsregexp.h"
13 14 15 16 17 18

namespace v8 {
namespace internal {

#ifdef OBJECT_PRINT

19
void Object::Print() {
20 21
  OFStream os(stdout);
  this->Print(os);
22
  os << std::flush;
23 24 25
}


26
void Object::Print(std::ostream& os) {  // NOLINT
27
  if (IsSmi()) {
28
    Smi::cast(this)->SmiPrint(os);
29
  } else {
30
    HeapObject::cast(this)->HeapObjectPrint(os);
31 32 33 34
  }
}


35
void HeapObject::PrintHeader(std::ostream& os, const char* id) {  // NOLINT
36
  os << reinterpret_cast<void*>(this) << ": [" << id << "]\n";
37 38 39
}


40
void HeapObject::HeapObjectPrint(std::ostream& os) {  // NOLINT
41 42
  InstanceType instance_type = map()->instance_type();

43
  HandleScope scope(GetIsolate());
44
  if (instance_type < FIRST_NONSTRING_TYPE) {
45
    String::cast(this)->StringPrint(os);
46 47 48 49
    return;
  }

  switch (instance_type) {
50
    case SYMBOL_TYPE:
51
      Symbol::cast(this)->SymbolPrint(os);
52
      break;
53
    case MAP_TYPE:
54
      Map::cast(this)->MapPrint(os);
55 56
      break;
    case HEAP_NUMBER_TYPE:
57
      HeapNumber::cast(this)->HeapNumberPrint(os);
58
      break;
59
    case MUTABLE_HEAP_NUMBER_TYPE:
60 61 62
      os << "<mutable ";
      HeapNumber::cast(this)->HeapNumberPrint(os);
      os << ">";
63
      break;
64 65
    case SIMD128_VALUE_TYPE:
      Simd128Value::cast(this)->Simd128ValuePrint(os);
66
      break;
67
    case FIXED_DOUBLE_ARRAY_TYPE:
68
      FixedDoubleArray::cast(this)->FixedDoubleArrayPrint(os);
69
      break;
70
    case FIXED_ARRAY_TYPE:
71
      FixedArray::cast(this)->FixedArrayPrint(os);
72 73
      break;
    case BYTE_ARRAY_TYPE:
74
      ByteArray::cast(this)->ByteArrayPrint(os);
75
      break;
76 77 78
    case BYTECODE_ARRAY_TYPE:
      BytecodeArray::cast(this)->BytecodeArrayPrint(os);
      break;
79
    case FREE_SPACE_TYPE:
80
      FreeSpace::cast(this)->FreeSpacePrint(os);
81
      break;
82

83 84 85 86
#define PRINT_FIXED_TYPED_ARRAY(Type, type, TYPE, ctype, size) \
  case Fixed##Type##Array::kInstanceType:                      \
    Fixed##Type##Array::cast(this)->FixedTypedArrayPrint(os);  \
    break;
87

88 89
    TYPED_ARRAYS(PRINT_FIXED_TYPED_ARRAY)
#undef PRINT_FIXED_TYPED_ARRAY
90

91
    case FILLER_TYPE:
92
      os << "filler";
93 94 95 96
      break;
    case JS_OBJECT_TYPE:  // fall through
    case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
    case JS_ARRAY_TYPE:
97
    case JS_GENERATOR_OBJECT_TYPE:
98
      JSObject::cast(this)->JSObjectPrint(os);
99
      break;
100 101 102
    case JS_REGEXP_TYPE:
      JSRegExp::cast(this)->JSRegExpPrint(os);
      break;
103
    case ODDBALL_TYPE:
104
      Oddball::cast(this)->to_string()->Print(os);
105
      break;
106
    case JS_MODULE_TYPE:
107
      JSModule::cast(this)->JSModulePrint(os);
108
      break;
109
    case JS_FUNCTION_TYPE:
110
      JSFunction::cast(this)->JSFunctionPrint(os);
111 112
      break;
    case JS_GLOBAL_PROXY_TYPE:
113
      JSGlobalProxy::cast(this)->JSGlobalProxyPrint(os);
114 115
      break;
    case JS_GLOBAL_OBJECT_TYPE:
116
      JSGlobalObject::cast(this)->JSGlobalObjectPrint(os);
117 118
      break;
    case JS_VALUE_TYPE:
119
      JSValue::cast(this)->JSValuePrint(os);
120
      break;
121
    case JS_DATE_TYPE:
122
      JSDate::cast(this)->JSDatePrint(os);
123
      break;
124
    case CODE_TYPE:
125
      Code::cast(this)->CodePrint(os);
126
      break;
127
    case JS_PROXY_TYPE:
128
      JSProxy::cast(this)->JSProxyPrint(os);
129
      break;
130
    case JS_FUNCTION_PROXY_TYPE:
131
      JSFunctionProxy::cast(this)->JSFunctionProxyPrint(os);
132
      break;
133
    case JS_SET_TYPE:
134
      JSSet::cast(this)->JSSetPrint(os);
135 136
      break;
    case JS_MAP_TYPE:
137
      JSMap::cast(this)->JSMapPrint(os);
138
      break;
139
    case JS_SET_ITERATOR_TYPE:
140
      JSSetIterator::cast(this)->JSSetIteratorPrint(os);
141 142
      break;
    case JS_MAP_ITERATOR_TYPE:
143
      JSMapIterator::cast(this)->JSMapIteratorPrint(os);
144
      break;
145 146 147
    case JS_ITERATOR_RESULT_TYPE:
      JSIteratorResult::cast(this)->JSIteratorResultPrint(os);
      break;
148
    case JS_WEAK_MAP_TYPE:
149
      JSWeakMap::cast(this)->JSWeakMapPrint(os);
150
      break;
151
    case JS_WEAK_SET_TYPE:
152
      JSWeakSet::cast(this)->JSWeakSetPrint(os);
153
      break;
154
    case FOREIGN_TYPE:
155
      Foreign::cast(this)->ForeignPrint(os);
156 157
      break;
    case SHARED_FUNCTION_INFO_TYPE:
158
      SharedFunctionInfo::cast(this)->SharedFunctionInfoPrint(os);
159
      break;
160
    case JS_MESSAGE_OBJECT_TYPE:
161
      JSMessageObject::cast(this)->JSMessageObjectPrint(os);
162
      break;
163
    case CELL_TYPE:
164
      Cell::cast(this)->CellPrint(os);
165 166
      break;
    case PROPERTY_CELL_TYPE:
167
      PropertyCell::cast(this)->PropertyCellPrint(os);
168
      break;
ulan@chromium.org's avatar
ulan@chromium.org committed
169 170 171
    case WEAK_CELL_TYPE:
      WeakCell::cast(this)->WeakCellPrint(os);
      break;
172
    case JS_ARRAY_BUFFER_TYPE:
173
      JSArrayBuffer::cast(this)->JSArrayBufferPrint(os);
174
      break;
175
    case JS_TYPED_ARRAY_TYPE:
176
      JSTypedArray::cast(this)->JSTypedArrayPrint(os);
177
      break;
178
    case JS_DATA_VIEW_TYPE:
179
      JSDataView::cast(this)->JSDataViewPrint(os);
180
      break;
181 182
#define MAKE_STRUCT_CASE(NAME, Name, name) \
  case NAME##_TYPE:                        \
183
    Name::cast(this)->Name##Print(os);     \
184 185 186 187 188
    break;
  STRUCT_LIST(MAKE_STRUCT_CASE)
#undef MAKE_STRUCT_CASE

    default:
189
      os << "UNKNOWN TYPE " << map()->instance_type();
190 191 192 193 194 195
      UNREACHABLE();
      break;
  }
}


196 197 198 199 200 201 202 203 204
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();
}


205 206 207 208 209 210 211 212 213 214
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));
}


215 216 217 218 219 220 221 222
#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)); \
    }                                                               \
223
  }
224
SIMD128_INT_PRINT_FUNCTION(Int32x4, 4)
225
SIMD128_INT_PRINT_FUNCTION(Uint32x4, 4)
226
SIMD128_INT_PRINT_FUNCTION(Int16x8, 8)
227
SIMD128_INT_PRINT_FUNCTION(Uint16x8, 8)
228
SIMD128_INT_PRINT_FUNCTION(Int8x16, 16)
229
SIMD128_INT_PRINT_FUNCTION(Uint8x16, 16)
230 231 232 233 234 235 236 237 238 239 240
#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"); \
    }                                                            \
241
  }
242 243 244 245
SIMD128_BOOL_PRINT_FUNCTION(Bool32x4, 4)
SIMD128_BOOL_PRINT_FUNCTION(Bool16x8, 8)
SIMD128_BOOL_PRINT_FUNCTION(Bool8x16, 16)
#undef SIMD128_BOOL_PRINT_FUNCTION
246 247


248
void ByteArray::ByteArrayPrint(std::ostream& os) {  // NOLINT
249
  os << "byte array, data starts at " << GetDataStartAddress();
250 251 252
}


253 254 255 256 257
void BytecodeArray::BytecodeArrayPrint(std::ostream& os) {  // NOLINT
  Disassemble(os);
}


258
void FreeSpace::FreeSpacePrint(std::ostream& os) {  // NOLINT
259
  os << "free space, size " << Size();
260 261 262
}


263
template <class Traits>
264 265
void FixedTypedArray<Traits>::FixedTypedArrayPrint(
    std::ostream& os) {  // NOLINT
266
  os << "fixed " << Traits::Designator();
267 268
}

269

270
void JSObject::PrintProperties(std::ostream& os) {  // NOLINT
271 272
  if (HasFastProperties()) {
    DescriptorArray* descs = map()->instance_descriptors();
273
    for (int i = 0; i < map()->NumberOfOwnDescriptors(); i++) {
274
      os << "\n   ";
275 276
      descs->GetKey(i)->NamePrint(os);
      os << ": ";
277
      switch (descs->GetType(i)) {
278
        case DATA: {
279
          FieldIndex index = FieldIndex::ForDescriptor(map(), i);
280 281 282 283 284
          if (IsUnboxedDoubleField(index)) {
            os << "<unboxed double> " << RawFastDoublePropertyAt(index);
          } else {
            os << Brief(RawFastPropertyAt(index));
          }
285
          os << " (data field at offset " << index.property_index() << ")";
286 287
          break;
        }
288
        case ACCESSOR: {
289
          FieldIndex index = FieldIndex::ForDescriptor(map(), i);
290
          os << " (accessor field at offset " << index.property_index() << ")";
291 292
          break;
        }
293
        case DATA_CONSTANT:
294
          os << Brief(descs->GetConstant(i)) << " (data constant)";
295
          break;
296
        case ACCESSOR_CONSTANT:
297
          os << Brief(descs->GetCallbacksObject(i)) << " (accessor constant)";
298 299 300
          break;
      }
    }
301
  } else if (IsJSGlobalObject()) {
302
    global_dictionary()->Print(os);
303
  } else {
304
    property_dictionary()->Print(os);
305 306 307 308
  }
}


309
template <class T>
310
static void DoPrintElements(std::ostream& os, Object* object) {  // NOLINT
311 312
  T* p = T::cast(object);
  for (int i = 0; i < p->length(); i++) {
313
    os << "\n   " << i << ": " << p->get_scalar(i);
314 315 316 317
  }
}


318
void JSObject::PrintElements(std::ostream& os) {  // NOLINT
319 320 321
  // Don't call GetElementsKind, its validation code can cause the printer to
  // fail when debugging.
  switch (map()->elements_kind()) {
322 323 324
    case FAST_HOLEY_SMI_ELEMENTS:
    case FAST_SMI_ELEMENTS:
    case FAST_HOLEY_ELEMENTS:
325 326 327 328
    case FAST_ELEMENTS: {
      // Print in array notation for non-sparse arrays.
      FixedArray* p = FixedArray::cast(elements());
      for (int i = 0; i < p->length(); i++) {
329
        os << "\n   " << i << ": " << Brief(p->get(i));
330 331 332
      }
      break;
    }
333
    case FAST_HOLEY_DOUBLE_ELEMENTS:
334 335
    case FAST_DOUBLE_ELEMENTS: {
      // Print in array notation for non-sparse arrays.
336 337 338
      if (elements()->length() > 0) {
        FixedDoubleArray* p = FixedDoubleArray::cast(elements());
        for (int i = 0; i < p->length(); i++) {
339
          os << "\n   " << i << ": ";
340
          if (p->is_the_hole(i)) {
341
            os << "<the hole>";
342
          } else {
343
            os << p->get_scalar(i);
344
          }
345 346 347 348
        }
      }
      break;
    }
349 350


351 352 353 354 355
#define PRINT_ELEMENTS(Kind, Type)         \
  case Kind: {                             \
    DoPrintElements<Type>(os, elements()); \
    break;                                 \
  }
356 357 358 359 360 361 362 363

    PRINT_ELEMENTS(UINT8_ELEMENTS, FixedUint8Array)
    PRINT_ELEMENTS(UINT8_CLAMPED_ELEMENTS, FixedUint8ClampedArray)
    PRINT_ELEMENTS(INT8_ELEMENTS, FixedInt8Array)
    PRINT_ELEMENTS(UINT16_ELEMENTS, FixedUint16Array)
    PRINT_ELEMENTS(INT16_ELEMENTS, FixedInt16Array)
    PRINT_ELEMENTS(UINT32_ELEMENTS, FixedUint32Array)
    PRINT_ELEMENTS(INT32_ELEMENTS, FixedInt32Array)
364 365
    PRINT_ELEMENTS(FLOAT32_ELEMENTS, FixedFloat32Array)
    PRINT_ELEMENTS(FLOAT64_ELEMENTS, FixedFloat64Array)
366 367 368

#undef PRINT_ELEMENTS

369
    case DICTIONARY_ELEMENTS:
370
      elements()->Print(os);
371
      break;
372 373
    case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
    case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: {
374
      FixedArray* p = FixedArray::cast(elements());
375
      os << "\n   parameter map:";
376
      for (int i = 2; i < p->length(); i++) {
377
        os << " " << (i - 2) << ":" << Brief(p->get(i));
378
      }
379
      os << "\n   context: " << Brief(p->get(0))
380
         << "\n   arguments: " << Brief(p->get(1));
381 382
      break;
    }
383 384 385 386
  }
}


387 388 389
static void JSObjectPrintHeader(std::ostream& os, JSObject* obj,
                                const char* id) {  // NOLINT
  obj->PrintHeader(os, id);
390 391
  // Don't call GetElementsKind, its validation code can cause the printer to
  // fail when debugging.
392 393 394 395 396 397 398
  PrototypeIterator iter(obj->GetIsolate(), obj);
  os << " - map = " << reinterpret_cast<void*>(obj->map()) << " ["
     << ElementsKindToString(obj->map()->elements_kind())
     << "]\n - prototype = " << reinterpret_cast<void*>(iter.GetCurrent());
}


399 400 401
static void JSObjectPrintBody(std::ostream& os, JSObject* obj,  // NOLINT
                              bool print_elements = true) {
  os << "\n {";
402 403
  obj->PrintProperties(os);
  obj->PrintTransitions(os);
404 405
  if (print_elements) obj->PrintElements(os);
  os << "\n }\n";
406 407 408
}


409 410 411 412 413 414
void JSObject::JSObjectPrint(std::ostream& os) {  // NOLINT
  JSObjectPrintHeader(os, this, "JSObject");
  JSObjectPrintBody(os, this);
}


415 416 417 418 419 420 421
void JSRegExp::JSRegExpPrint(std::ostream& os) {  // NOLINT
  JSObjectPrintHeader(os, this, "JSRegExp");
  os << "\n - data = " << Brief(data());
  JSObjectPrintBody(os, this);
}


422
void JSModule::JSModulePrint(std::ostream& os) {  // NOLINT
423 424 425 426
  JSObjectPrintHeader(os, this, "JSModule");
  os << "\n - context = " << Brief(context());
  os << " - scope_info = " << Brief(scope_info());
  JSObjectPrintBody(os, this);
427 428 429
}


430 431
static const char* TypeToString(InstanceType type) {
  switch (type) {
432 433 434
#define TYPE_TO_STRING(TYPE) case TYPE: return #TYPE;
  INSTANCE_TYPE_LIST(TYPE_TO_STRING)
#undef TYPE_TO_STRING
435
  }
436 437
  UNREACHABLE();
  return "UNKNOWN";  // Keep the compiler happy.
438 439 440
}


441
void Symbol::SymbolPrint(std::ostream& os) {  // NOLINT
442 443 444
  HeapObject::PrintHeader(os, "Symbol");
  os << " - hash: " << Hash();
  os << "\n - name: " << Brief(name());
445 446 447
  if (name()->IsUndefined()) {
    os << " (" << PrivateSymbolToName() << ")";
  }
448
  os << "\n - private: " << is_private();
449
  os << "\n";
450 451 452
}


453
void Map::MapPrint(std::ostream& os) {  // NOLINT
454 455 456
  HeapObject::PrintHeader(os, "Map");
  os << " - type: " << TypeToString(instance_type()) << "\n";
  os << " - instance size: " << instance_size() << "\n";
457 458 459
  if (IsJSObjectMap()) {
    os << " - inobject properties: " << GetInObjectProperties() << "\n";
  }
460
  os << " - elements kind: " << ElementsKindToString(elements_kind()) << "\n";
461
  os << " - unused property fields: " << unused_property_fields() << "\n";
462
  if (is_deprecated()) os << " - deprecated_map\n";
463
  if (is_stable()) os << " - stable_map\n";
464
  if (is_dictionary_map()) os << " - dictionary_map\n";
465 466 467 468
  if (is_hidden_prototype()) os << " - hidden_prototype\n";
  if (has_named_interceptor()) os << " - named_interceptor\n";
  if (has_indexed_interceptor()) os << " - indexed_interceptor\n";
  if (is_undetectable()) os << " - undetectable\n";
469
  if (is_callable()) os << " - callable\n";
470
  if (is_constructor()) os << " - constructor\n";
471
  if (is_access_check_needed()) os << " - access_check_needed\n";
472
  if (!is_extensible()) os << " - non-extensible\n";
473
  if (is_observed()) os << " - observed\n";
474
  if (is_strong()) os << " - strong_map\n";
475 476 477 478 479 480
  if (is_prototype_map()) {
    os << " - prototype_map\n";
    os << " - prototype info: " << Brief(prototype_info());
  } else {
    os << " - back pointer: " << Brief(GetBackPointer());
  }
481 482 483
  os << "\n - instance descriptors " << (owns_descriptors() ? "(own) " : "")
     << "#" << NumberOfOwnDescriptors() << ": "
     << Brief(instance_descriptors());
484 485 486
  if (FLAG_unbox_double_fields) {
    os << "\n - layout descriptor: " << Brief(layout_descriptor());
  }
487 488 489 490 491
  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);
492
  }
493
  os << "\n - prototype: " << Brief(prototype());
494
  os << "\n - constructor: " << Brief(GetConstructor());
495 496 497
  os << "\n - code cache: " << Brief(code_cache());
  os << "\n - dependent code: " << Brief(dependent_code());
  os << "\n";
498 499 500
}


501
void CodeCache::CodeCachePrint(std::ostream& os) {  // NOLINT
502 503 504
  HeapObject::PrintHeader(os, "CodeCache");
  os << "\n - default_cache: " << Brief(default_cache());
  os << "\n - normal_type_cache: " << Brief(normal_type_cache());
505 506 507
}


508 509
void PolymorphicCodeCache::PolymorphicCodeCachePrint(
    std::ostream& os) {  // NOLINT
510 511
  HeapObject::PrintHeader(os, "PolymorphicCodeCache");
  os << "\n - cache: " << Brief(cache());
512 513 514
}


515
void TypeFeedbackInfo::TypeFeedbackInfoPrint(std::ostream& os) {  // NOLINT
516 517
  HeapObject::PrintHeader(os, "TypeFeedbackInfo");
  os << " - ic_total_count: " << ic_total_count()
518 519
     << ", ic_with_type_info_count: " << ic_with_type_info_count()
     << ", ic_generic_count: " << ic_generic_count() << "\n";
520 521 522
}


523 524
void AliasedArgumentsEntry::AliasedArgumentsEntryPrint(
    std::ostream& os) {  // NOLINT
525 526
  HeapObject::PrintHeader(os, "AliasedArgumentsEntry");
  os << "\n - aliased_context_slot: " << aliased_context_slot();
527 528 529
}


530
void FixedArray::FixedArrayPrint(std::ostream& os) {  // NOLINT
531 532
  HeapObject::PrintHeader(os, "FixedArray");
  os << " - length: " << length();
533
  for (int i = 0; i < length(); i++) {
534
    os << "\n  [" << i << "]: " << Brief(get(i));
535
  }
536
  os << "\n";
537 538 539
}


540
void FixedDoubleArray::FixedDoubleArrayPrint(std::ostream& os) {  // NOLINT
541 542
  HeapObject::PrintHeader(os, "FixedDoubleArray");
  os << " - length: " << length();
543
  for (int i = 0; i < length(); i++) {
544
    os << "\n  [" << i << "]: ";
545
    if (is_the_hole(i)) {
546
      os << "<the hole>";
547
    } else {
548
      os << get_scalar(i);
549
    }
550
  }
551
  os << "\n";
552 553 554
}


555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580
void TypeFeedbackMetadata::Print() {
  OFStream os(stdout);
  TypeFeedbackMetadataPrint(os);
  os << std::flush;
}


void TypeFeedbackMetadata::TypeFeedbackMetadataPrint(
    std::ostream& os) {  // NOLINT
  HeapObject::PrintHeader(os, "TypeFeedbackMetadata");
  os << " - length: " << length();
  if (length() == 0) {
    os << " (empty)\n";
    return;
  }

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


581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598
void TypeFeedbackVector::Print() {
  OFStream os(stdout);
  TypeFeedbackVectorPrint(os);
  os << std::flush;
}


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

  os << "\n - ics with type info: " << ic_with_type_info_count();
  os << "\n - generic ics: " << ic_generic_count();

599
  TypeFeedbackMetadataIterator iter(metadata());
600 601 602 603
  while (iter.HasNext()) {
    FeedbackVectorSlot slot = iter.Next();
    FeedbackVectorSlotKind kind = iter.kind();

604
    os << "\n Slot " << slot << " " << kind << " ";
605 606 607 608 609 610 611 612 613 614
    switch (kind) {
      case FeedbackVectorSlotKind::LOAD_IC: {
        LoadICNexus nexus(this, slot);
        os << Code::ICState2String(nexus.StateFromFeedback());
        break;
      }
      case FeedbackVectorSlotKind::KEYED_LOAD_IC: {
        KeyedLoadICNexus nexus(this, slot);
        os << Code::ICState2String(nexus.StateFromFeedback());
        break;
615
      }
616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637
      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;
      }
      case FeedbackVectorSlotKind::GENERAL:
        break;
      case FeedbackVectorSlotKind::INVALID:
      case FeedbackVectorSlotKind::KINDS_NUMBER:
        UNREACHABLE();
        break;
    }
638

639 640 641 642
    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));
643 644 645 646 647 648
    }
  }
  os << "\n";
}


649
void JSValue::JSValuePrint(std::ostream& os) {  // NOLINT
650 651 652
  JSObjectPrintHeader(os, this, "JSValue");
  os << "\n - value = " << Brief(value());
  JSObjectPrintBody(os, this);
653 654 655
}


656
void JSMessageObject::JSMessageObjectPrint(std::ostream& os) {  // NOLINT
657 658
  JSObjectPrintHeader(os, this, "JSMessageObject");
  os << "\n - type: " << type();
659
  os << "\n - arguments: " << Brief(argument());
660 661 662 663
  os << "\n - start_position: " << start_position();
  os << "\n - end_position: " << end_position();
  os << "\n - script: " << Brief(script());
  os << "\n - stack_frames: " << Brief(stack_frames());
664
  JSObjectPrintBody(os, this);
665 666 667
}


668
void String::StringPrint(std::ostream& os) {  // NOLINT
669
  if (StringShape(this).IsInternalized()) {
670
    os << "#";
671
  } else if (StringShape(this).IsCons()) {
672
    os << "c\"";
673
  } else {
674
    os << "\"";
675 676 677 678 679 680 681 682 683 684
  }

  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++) {
685
    os << AsUC16(Get(i));
686 687
  }
  if (len != length()) {
688
    os << truncated_epilogue;
689 690
  }

691
  if (!StringShape(this).IsInternalized()) os << "\"";
692 693 694
}


695
void Name::NamePrint(std::ostream& os) {  // NOLINT
696
  if (IsString()) {
697
    String::cast(this)->StringPrint(os);
698 699 700
  } else if (IsSymbol()) {
    Symbol::cast(this)->name()->Print(os);
  } else {
701
    os << Brief(this);
702
  }
703 704 705
}


706 707 708 709
static const char* const weekdays[] = {
  "???", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
};

710

711
void JSDate::JSDatePrint(std::ostream& os) {  // NOLINT
712 713
  JSObjectPrintHeader(os, this, "JSDate");
  os << "\n - value = " << Brief(value());
714
  if (!year()->IsSmi()) {
715
    os << "\n - time = NaN\n";
716
  } else {
717
    // TODO(svenpanne) Add some basic formatting to our streams.
718
    ScopedVector<char> buf(100);
719
    SNPrintF(
720
        buf, "\n - time = %s %04d/%02d/%02d %02d:%02d:%02d\n",
721 722 723 724 725 726 727 728
        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();
729
  }
730
  JSObjectPrintBody(os, this);
731 732 733
}


734
void JSProxy::JSProxyPrint(std::ostream& os) {  // NOLINT
735 736 737 738 739 740 741
  HeapObject::PrintHeader(os, "JSProxy");
  os << " - map = " << reinterpret_cast<void*>(map()) << "\n";
  os << " - handler = ";
  handler()->Print(os);
  os << "\n - hash = ";
  hash()->Print(os);
  os << "\n";
742 743 744
}


745
void JSFunctionProxy::JSFunctionProxyPrint(std::ostream& os) {  // NOLINT
746 747 748 749 750 751 752 753 754
  HeapObject::PrintHeader(os, "JSFunctionProxy");
  os << " - map = " << reinterpret_cast<void*>(map()) << "\n";
  os << " - handler = ";
  handler()->Print(os);
  os << "\n - call_trap = ";
  call_trap()->Print(os);
  os << "\n - construct_trap = ";
  construct_trap()->Print(os);
  os << "\n";
755 756 757
}


758
void JSSet::JSSetPrint(std::ostream& os) {  // NOLINT
759
  JSObjectPrintHeader(os, this, "JSSet");
760
  os << " - table = " << Brief(table());
761
  JSObjectPrintBody(os, this);
762 763 764
}


765
void JSMap::JSMapPrint(std::ostream& os) {  // NOLINT
766
  JSObjectPrintHeader(os, this, "JSMap");
767
  os << " - table = " << Brief(table());
768
  JSObjectPrintBody(os, this);
769 770 771
}


772
template <class Derived, class TableType>
773 774 775
void
OrderedHashTableIterator<Derived, TableType>::OrderedHashTableIteratorPrint(
    std::ostream& os) {  // NOLINT
776
  os << "\n - table = " << Brief(table());
777 778 779
  os << "\n - index = " << Brief(index());
  os << "\n - kind = " << Brief(kind());
  os << "\n";
780 781 782
}


783 784
template void OrderedHashTableIterator<
    JSSetIterator,
785
    OrderedHashSet>::OrderedHashTableIteratorPrint(std::ostream& os);  // NOLINT
786 787


788 789
template void OrderedHashTableIterator<
    JSMapIterator,
790
    OrderedHashMap>::OrderedHashTableIteratorPrint(std::ostream& os);  // NOLINT
791 792


793
void JSSetIterator::JSSetIteratorPrint(std::ostream& os) {  // NOLINT
794
  JSObjectPrintHeader(os, this, "JSSetIterator");
795
  OrderedHashTableIteratorPrint(os);
796 797 798
}


799
void JSMapIterator::JSMapIteratorPrint(std::ostream& os) {  // NOLINT
800
  JSObjectPrintHeader(os, this, "JSMapIterator");
801
  OrderedHashTableIteratorPrint(os);
802 803 804
}


805
void JSIteratorResult::JSIteratorResultPrint(std::ostream& os) {  // NOLINT
806 807 808
  JSObjectPrintHeader(os, this, "JSIteratorResult");
  os << "\n - done = " << Brief(done());
  os << "\n - value = " << Brief(value());
809 810 811 812
  os << "\n";
}


813
void JSWeakMap::JSWeakMapPrint(std::ostream& os) {  // NOLINT
814 815 816
  JSObjectPrintHeader(os, this, "JSWeakMap");
  os << "\n - table = " << Brief(table());
  JSObjectPrintBody(os, this);
817 818 819
}


820
void JSWeakSet::JSWeakSetPrint(std::ostream& os) {  // NOLINT
821 822 823
  JSObjectPrintHeader(os, this, "JSWeakSet");
  os << "\n - table = " << Brief(table());
  JSObjectPrintBody(os, this);
824 825 826
}


827
void JSArrayBuffer::JSArrayBufferPrint(std::ostream& os) {  // NOLINT
828 829 830
  JSObjectPrintHeader(os, this, "JSArrayBuffer");
  os << "\n - backing_store = " << backing_store();
  os << "\n - byte_length = " << Brief(byte_length());
831
  if (was_neutered()) os << " - neutered\n";
832
  JSObjectPrintBody(os, this, !was_neutered());
833 834 835
}


836
void JSTypedArray::JSTypedArrayPrint(std::ostream& os) {  // NOLINT
837 838
  JSObjectPrintHeader(os, this, "JSTypedArray");
  os << "\n - buffer = " << Brief(buffer());
839 840 841
  os << "\n - byte_offset = " << Brief(byte_offset());
  os << "\n - byte_length = " << Brief(byte_length());
  os << "\n - length = " << Brief(length());
842
  if (WasNeutered()) os << " - neutered\n";
843
  JSObjectPrintBody(os, this, !WasNeutered());
844 845 846
}


847
void JSDataView::JSDataViewPrint(std::ostream& os) {  // NOLINT
848 849
  JSObjectPrintHeader(os, this, "JSDataView");
  os << "\n - buffer =" << Brief(buffer());
850 851
  os << "\n - byte_offset = " << Brief(byte_offset());
  os << "\n - byte_length = " << Brief(byte_length());
852
  if (WasNeutered()) os << " - neutered\n";
853
  JSObjectPrintBody(os, this, !WasNeutered());
854 855 856
}


857
void JSFunction::JSFunctionPrint(std::ostream& os) {  // NOLINT
858 859
  JSObjectPrintHeader(os, this, "Function");
  os << "\n - initial_map = ";
860 861 862
  if (has_initial_map()) os << Brief(initial_map());
  os << "\n - shared_info = " << Brief(shared());
  os << "\n   - name = " << Brief(shared()->name());
863 864 865
  if (shared()->is_generator()) {
    os << "\n   - generator";
  }
866
  os << "\n - context = " << Brief(context());
867
  if (shared()->bound()) {
868
    os << "\n - bindings = " << Brief(function_bindings());
869
  } else {
870
    os << "\n - literals = " << Brief(literals());
871
  }
872
  os << "\n - code = " << Brief(code());
873
  JSObjectPrintBody(os, this);
874 875 876
}


877
void SharedFunctionInfo::SharedFunctionInfoPrint(std::ostream& os) {  // NOLINT
878 879 880 881 882 883 884
  HeapObject::PrintHeader(os, "SharedFunctionInfo");
  os << " - name: " << Brief(name());
  os << "\n - expected_nof_properties: " << expected_nof_properties();
  os << "\n - ast_node_count: " << ast_node_count();
  os << "\n - instance class name = ";
  instance_class_name()->Print(os);
  os << "\n - code = " << Brief(code());
885
  if (HasSourceCode()) {
886
    os << "\n - source code = ";
887 888 889
    String* source = String::cast(Script::cast(script())->source());
    int start = start_position();
    int length = end_position() - start;
rmcilroy's avatar
rmcilroy committed
890 891
    base::SmartArrayPointer<char> source_string = source->ToCString(
        DISALLOW_NULLS, FAST_STRING_TRAVERSAL, start, length, NULL);
892
    os << source_string.get();
893
  }
894
  // Script files are often large, hard to read.
895 896 897 898 899 900 901 902 903 904
  // os << "\n - script =";
  // script()->Print(os);
  os << "\n - function token position = " << function_token_position();
  os << "\n - start position = " << start_position();
  os << "\n - end position = " << end_position();
  os << "\n - is expression = " << is_expression();
  os << "\n - debug info = " << Brief(debug_info());
  os << "\n - length = " << length();
  os << "\n - optimized_code_map = " << Brief(optimized_code_map());
  os << "\n - feedback_vector = ";
905
  feedback_vector()->TypeFeedbackVectorPrint(os);
906 907 908
  if (HasBytecodeArray()) {
    os << "\n - bytecode_array = " << bytecode_array();
  }
909
  os << "\n";
910 911 912
}


913
void JSGlobalProxy::JSGlobalProxyPrint(std::ostream& os) {  // NOLINT
914 915 916 917
  os << "global_proxy ";
  JSObjectPrint(os);
  os << "native context : " << Brief(native_context());
  os << "\n";
918 919 920
}


921
void JSGlobalObject::JSGlobalObjectPrint(std::ostream& os) {  // NOLINT
922 923 924 925
  os << "global ";
  JSObjectPrint(os);
  os << "native context : " << Brief(native_context());
  os << "\n";
926 927 928
}


929
void Cell::CellPrint(std::ostream& os) {  // NOLINT
930
  HeapObject::PrintHeader(os, "Cell");
931 932
  os << " - value: " << Brief(value());
  os << "\n";
933 934 935
}


936
void PropertyCell::PropertyCellPrint(std::ostream& os) {  // NOLINT
937
  HeapObject::PrintHeader(os, "PropertyCell");
938 939 940
  os << " - value: " << Brief(value());
  os << "\n - details: " << property_details();
  os << "\n";
941 942 943
}


ulan@chromium.org's avatar
ulan@chromium.org committed
944 945
void WeakCell::WeakCellPrint(std::ostream& os) {  // NOLINT
  HeapObject::PrintHeader(os, "WeakCell");
946 947 948 949 950
  if (cleared()) {
    os << "\n - cleared";
  } else {
    os << "\n - value: " << Brief(value());
  }
951
  os << "\n";
ulan@chromium.org's avatar
ulan@chromium.org committed
952 953 954
}


955
void Code::CodePrint(std::ostream& os) {  // NOLINT
956
  HeapObject::PrintHeader(os, "Code");
957 958
#ifdef ENABLE_DISASSEMBLER
  if (FLAG_use_verbose_printer) {
959
    Disassemble(NULL, os);
960 961 962 963 964
  }
#endif
}


965
void Foreign::ForeignPrint(std::ostream& os) {  // NOLINT
966
  os << "foreign address : " << foreign_address();
967
  os << "\n";
968 969 970
}


971
void ExecutableAccessorInfo::ExecutableAccessorInfoPrint(
972
    std::ostream& os) {  // NOLINT
973 974
  HeapObject::PrintHeader(os, "ExecutableAccessorInfo");
  os << "\n - name: " << Brief(name());
975
  os << "\n - flag: " << flag();
976 977 978 979
  os << "\n - getter: " << Brief(getter());
  os << "\n - setter: " << Brief(setter());
  os << "\n - data: " << Brief(data());
  os << "\n";
980 981 982
}


983
void Box::BoxPrint(std::ostream& os) {  // NOLINT
984 985 986 987 988 989
  HeapObject::PrintHeader(os, "Box");
  os << "\n - value: " << Brief(value());
  os << "\n";
}


990 991 992
void PrototypeInfo::PrototypeInfoPrint(std::ostream& os) {  // NOLINT
  HeapObject::PrintHeader(os, "PrototypeInfo");
  os << "\n - prototype users: " << Brief(prototype_users());
993
  os << "\n - registry slot: " << registry_slot();
994
  os << "\n - validity cell: " << Brief(validity_cell());
995
  os << "\n - constructor name: " << Brief(constructor_name());
996 997 998 999
  os << "\n";
}


1000 1001 1002 1003 1004 1005 1006 1007 1008
void SloppyBlockWithEvalContextExtension::
    SloppyBlockWithEvalContextExtensionPrint(std::ostream& os) {  // NOLINT
  HeapObject::PrintHeader(os, "SloppyBlockWithEvalContextExtension");
  os << "\n - scope_info: " << Brief(scope_info());
  os << "\n - extension: " << Brief(extension());
  os << "\n";
}


1009
void AccessorPair::AccessorPairPrint(std::ostream& os) {  // NOLINT
1010 1011 1012 1013 1014 1015 1016
  HeapObject::PrintHeader(os, "AccessorPair");
  os << "\n - getter: " << Brief(getter());
  os << "\n - setter: " << Brief(setter());
  os << "\n";
}


1017
void AccessCheckInfo::AccessCheckInfoPrint(std::ostream& os) {  // NOLINT
1018 1019 1020
  HeapObject::PrintHeader(os, "AccessCheckInfo");
  os << "\n - named_callback: " << Brief(named_callback());
  os << "\n - indexed_callback: " << Brief(indexed_callback());
1021
  os << "\n - callback: " << Brief(callback());
1022 1023 1024 1025 1026
  os << "\n - data: " << Brief(data());
  os << "\n";
}


1027
void InterceptorInfo::InterceptorInfoPrint(std::ostream& os) {  // NOLINT
1028 1029 1030 1031 1032 1033 1034 1035
  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";
1036 1037 1038
}


1039
void CallHandlerInfo::CallHandlerInfoPrint(std::ostream& os) {  // NOLINT
1040 1041 1042 1043
  HeapObject::PrintHeader(os, "CallHandlerInfo");
  os << "\n - callback: " << Brief(callback());
  os << "\n - data: " << Brief(data());
  os << "\n";
1044 1045 1046
}


1047 1048
void FunctionTemplateInfo::FunctionTemplateInfoPrint(
    std::ostream& os) {  // NOLINT
1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065
  HeapObject::PrintHeader(os, "FunctionTemplateInfo");
  os << "\n - class name: " << Brief(class_name());
  os << "\n - tag: " << Brief(tag());
  os << "\n - property_list: " << Brief(property_list());
  os << "\n - serial_number: " << Brief(serial_number());
  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());
  os << "\n - hidden_prototype: " << (hidden_prototype() ? "true" : "false");
  os << "\n - undetectable: " << (undetectable() ? "true" : "false");
  os << "\n - need_access_check: " << (needs_access_check() ? "true" : "false");
1066
  os << "\n - instantiated: " << (instantiated() ? "true" : "false");
1067 1068 1069 1070
  os << "\n";
}


1071
void ObjectTemplateInfo::ObjectTemplateInfoPrint(std::ostream& os) {  // NOLINT
1072 1073 1074 1075 1076 1077 1078 1079 1080 1081
  HeapObject::PrintHeader(os, "ObjectTemplateInfo");
  os << " - tag: " << Brief(tag());
  os << "\n - property_list: " << Brief(property_list());
  os << "\n - property_accessors: " << Brief(property_accessors());
  os << "\n - constructor: " << Brief(constructor());
  os << "\n - internal_field_count: " << Brief(internal_field_count());
  os << "\n";
}


1082
void TypeSwitchInfo::TypeSwitchInfoPrint(std::ostream& os) {  // NOLINT
1083 1084 1085 1086 1087 1088
  HeapObject::PrintHeader(os, "TypeSwitchInfo");
  os << "\n - types: " << Brief(types());
  os << "\n";
}


1089
void AllocationSite::AllocationSitePrint(std::ostream& os) {  // NOLINT
1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100
  HeapObject::PrintHeader(os, "AllocationSite");
  os << " - weak_next: " << Brief(weak_next());
  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: ";
1101 1102
  if (transition_info()->IsSmi()) {
    ElementsKind kind = GetElementsKind();
1103
    os << "Array allocation with ElementsKind " << ElementsKindToString(kind);
1104
  } else if (transition_info()->IsJSArray()) {
1105 1106 1107
    os << "Array literal " << Brief(transition_info());
  } else {
    os << "unknown transition_info" << Brief(transition_info());
1108
  }
1109
  os << "\n";
1110 1111 1112
}


1113
void AllocationMemento::AllocationMementoPrint(std::ostream& os) {  // NOLINT
1114 1115
  HeapObject::PrintHeader(os, "AllocationMemento");
  os << " - allocation site: ";
1116
  if (IsValid()) {
1117
    GetAllocationSite()->Print(os);
1118
  } else {
1119
    os << "<invalid>\n";
1120 1121 1122 1123
  }
}


1124
void Script::ScriptPrint(std::ostream& os) {  // NOLINT
1125 1126 1127
  HeapObject::PrintHeader(os, "Script");
  os << "\n - source: " << Brief(source());
  os << "\n - name: " << Brief(name());
1128 1129 1130 1131
  os << "\n - line_offset: " << line_offset();
  os << "\n - column_offset: " << column_offset();
  os << "\n - type: " << type();
  os << "\n - id: " << id();
1132 1133 1134 1135 1136 1137
  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());
  os << "\n - eval from instructions offset: "
1138
     << eval_from_instructions_offset();
1139
  os << "\n - shared function infos: " << Brief(shared_function_infos());
1140 1141 1142 1143
  os << "\n";
}


1144
void DebugInfo::DebugInfoPrint(std::ostream& os) {  // NOLINT
1145 1146 1147 1148 1149 1150 1151 1152
  HeapObject::PrintHeader(os, "DebugInfo");
  os << "\n - shared: " << Brief(shared());
  os << "\n - code: " << Brief(code());
  os << "\n - break_points: ";
  break_points()->Print(os);
}


1153
void BreakPointInfo::BreakPointInfoPrint(std::ostream& os) {  // NOLINT
1154
  HeapObject::PrintHeader(os, "BreakPointInfo");
1155 1156 1157
  os << "\n - code_position: " << code_position();
  os << "\n - source_position: " << source_position();
  os << "\n - statement_position: " << statement_position();
1158 1159 1160 1161 1162
  os << "\n - break_point_objects: " << Brief(break_point_objects());
  os << "\n";
}


1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189
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;
}


void LayoutDescriptor::Print(std::ostream& os) {  // NOLINT
  os << "Layout descriptor: ";
  if (IsUninitialized()) {
    os << "<uninitialized>";
  } else if (IsFastPointerLayout()) {
    os << "<all tagged>";
  } else if (IsSmi()) {
    os << "fast";
    PrintBitMask(os, static_cast<uint32_t>(Smi::cast(this)->value()));
  } else {
    os << "slow";
1190
    int len = length();
1191 1192 1193 1194 1195 1196 1197 1198 1199
    for (int i = 0; i < len; i++) {
      if (i > 0) os << " |";
      PrintBitMask(os, get_scalar(i));
    }
  }
  os << "\n";
}


1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238
#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);
    if (s->name()->IsUndefined()) {
      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);
    if (s->name()->IsUndefined()) {
      return SNPrintF(str, "#<%s>", s->PrivateSymbolToName());
    } else {
      return SNPrintF(str, "<%s>", String::cast(s->name())->ToCString().get());
    }
  }
}


#endif  // TRACE_MAPS


1239
#if defined(DEBUG) || defined(OBJECT_PRINT)
1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263
// 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());
1264
  os << "Descriptor array #" << number_of_descriptors();
1265 1266 1267
  for (int i = 0; i < number_of_descriptors(); i++) {
    Descriptor desc;
    Get(i, &desc);
1268
    os << "\n " << i << ": " << desc;
1269 1270 1271 1272 1273
  }
  os << "\n";
}


1274 1275
void TransitionArray::Print() {
  OFStream os(stdout);
1276
  TransitionArray::PrintTransitions(os, this);
1277
  os << "\n" << std::flush;
1278 1279 1280
}


1281
void TransitionArray::PrintTransitions(std::ostream& os, Object* transitions,
1282
                                       bool print_header) {  // NOLINT
1283
  int num_transitions = NumberOfTransitions(transitions);
1284
  if (print_header) {
1285
    os << "Transition array #" << num_transitions << ":";
1286
  }
1287 1288 1289
  for (int i = 0; i < num_transitions; i++) {
    Name* key = GetKey(transitions, i);
    Map* target = GetTarget(transitions, i);
1290
    os << "\n   ";
1291
#ifdef OBJECT_PRINT
1292
    key->NamePrint(os);
1293 1294 1295
#else
    key->ShortPrint(os);
#endif
1296
    os << ": ";
1297 1298
    Heap* heap = key->GetHeap();
    if (key == heap->nonextensible_symbol()) {
1299
      os << "(transition to non-extensible)";
1300
    } else if (key == heap->sealed_symbol()) {
1301
      os << "(transition to sealed)";
1302
    } else if (key == heap->frozen_symbol()) {
1303
      os << "(transition to frozen)";
1304
    } else if (key == heap->elements_transition_symbol()) {
1305
      os << "(transition to " << ElementsKindToString(target->elements_kind())
1306
         << ")";
1307
    } else if (key == heap->observed_symbol()) {
1308 1309
      os << " (transition to Object.observe)";
    } else {
1310
      PropertyDetails details = GetTargetDetails(key, target);
1311
      os << "(transition to ";
1312
      if (details.location() == kDescriptor) {
1313 1314
        os << "immutable ";
      }
1315 1316
      os << (details.kind() == kData ? "data" : "accessor");
      if (details.location() == kDescriptor) {
1317 1318 1319
        Object* value =
            target->instance_descriptors()->GetValue(target->LastAdded());
        os << " " << Brief(value);
1320
      }
1321
      os << "), attrs: " << details.attributes();
1322
    }
1323
    os << " -> " << Brief(target);
1324 1325 1326 1327
  }
}


1328
void JSObject::PrintTransitions(std::ostream& os) {  // NOLINT
1329 1330 1331 1332 1333
  Object* transitions = map()->raw_transitions();
  int num_transitions = TransitionArray::NumberOfTransitions(transitions);
  if (num_transitions == 0) return;
  os << "\n - transitions";
  TransitionArray::PrintTransitions(os, transitions, false);
1334
}
1335
#endif  // defined(DEBUG) || defined(OBJECT_PRINT)
1336 1337
}  // namespace internal
}  // namespace v8